L4Re Operating System Framework
Interface and Usage Documentation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ipc_server_loop
1// vi:set ft=cpp: -*- Mode: C++ -*-
2/*
3 * Copyright (C) 2015, 2017, 2019, 2021-2024 Kernkonzept GmbH.
4 * Author(s): Alexander Warg <alexander.warg@kernkonzept.com>
5 *
6 * License: see LICENSE.spdx (in this directory or the directories above)
7 */
8#pragma once
9
10#include "ipc_epiface"
11
12namespace L4 {
13
31namespace Ipc_svr {
32
51
58{ static void error(l4_msgtag_t, l4_utcb_t *) {} };
59
66{ static l4_timeout_t timeout() { return L4_IPC_SEND_TIMEOUT_0; } };
67
74{
75 static Reply_mode before_reply(l4_msgtag_t, l4_utcb_t *)
76 { return Reply_compound; }
77};
78
85{ static void setup_wait(l4_utcb_t *, Reply_mode) {} };
86
94template< typename R >
96{
98 R &r;
99
102
105 { return r.dispatch(tag, obj, utcb); }
106};
107
115template< typename R >
117{
119 R *r;
120
122 Direct_dispatch(R *r) : r(r) {}
123
125 l4_msgtag_t operator () (l4_msgtag_t tag, l4_umword_t obj, l4_utcb_t *utcb)
126 { return r->dispatch(tag, obj, utcb); }
127};
128
129#ifdef __EXCEPTIONS
139template< typename R, typename Exc> // = L4::Runtime_error>
140struct Exc_dispatch : private Direct_dispatch<R>
141{
144
149 {
150 try
151 {
152 return Direct_dispatch<R>::operator () (tag, obj, utcb);
153 }
154 catch (Exc &e)
155 {
156 return l4_msgtag(e.err_no(), 0, 0, 0);
157 }
158 catch (int err)
159 {
160 return l4_msgtag(err, 0, 0, 0);
161 }
162 catch (long err)
163 {
164 return l4_msgtag(err, 0, 0, 0);
165 }
166 }
167};
168
183template< typename R, typename Exc, typename Printer >
184struct Dbg_dispatch : private Direct_dispatch<R>
185{
187 Dbg_dispatch(R r, Printer p) : Direct_dispatch<R>(r), _printer(p) {}
188
194 {
195 try
196 {
197 return Direct_dispatch<R>::operator () (tag, obj, utcb);
198 }
199 catch (Exc &e)
200 {
201 _printer.printf("Error in handling IPC: %s: %s\n", e.str(),
202 e.extra_str());
203 return l4_msgtag(e.err_no(), 0, 0, 0);
204 }
205 catch (int err)
206 {
207 _printer.printf("Error in handling IPC: %d (%s)\n", err,
208 l4sys_errtostr(err));
209 return l4_msgtag(err, 0, 0, 0);
210 }
211 catch (long err)
212 {
213 _printer.printf("Error in handling IPC: %ld (%s)\n", err,
214 l4sys_errtostr(err));
215 return l4_msgtag(err, 0, 0, 0);
216 }
217 }
218
219 Printer _printer;
220};
221#endif
222
234{
235public:
240 int alloc_buffer_demand(Demand const &demand) override
241 {
242 if (!demand.no_demand())
243 return -L4_ENOMEM;
244 return L4_EOK;
245 }
246
248 L4::Cap<void> get_rcv_cap(int) const override
249 { return L4::Cap<void>::Invalid; }
250
252 int realloc_rcv_cap(int) override
253 { return -L4_ENOMEM; }
254
257 { return -L4_ENOSYS; }
258
260 int remove_timeout(Timeout *) override
261 { return -L4_ENOSYS; }
262
263protected:
265 unsigned first_free_br() const
266 { return 1; }
267
270 {
271 l4_buf_regs_t *br = l4_utcb_br_u(utcb);
272 br->bdr = 0;
273 br->br[0] = 0;
274 }
275};
276
289
290}
291
306template< typename LOOP_HOOKS = Ipc_svr::Default_loop_hooks >
307class Server :
308 public LOOP_HOOKS
309{
310public:
317 /* Internal note: After all users have been converted, remove this
318 * constructor. Also remove the constructor below then. */
319 explicit Server(l4_utcb_t *)
320 L4_DEPRECATED("Do not specify the UTCB with the constructor. "
321 "Supply it on the loop function if needed.")
322 {}
323
327 /* Internal note: Remove this constructor when the above deprecated
328 * constructor with the UTCB pointer is also removed. */
330
337 template< typename DISPATCH >
338 inline L4_NORETURN void internal_loop(DISPATCH dispatch, l4_utcb_t *);
339
343 template< typename R >
346
347#ifdef __EXCEPTIONS
354 template< typename EXC, typename R >
355 inline L4_NORETURN void loop(R r, l4_utcb_t *u = l4_utcb())
356 {
358 // function will never return
359 }
360
367 template< typename EXC, typename R, typename Printer >
368 inline L4_NORETURN void loop_dbg(R r, Printer p, l4_utcb_t *u = l4_utcb())
369 {
371 // function will never return
372 }
373#endif
374protected:
377};
378
379template< typename L >
380inline l4_msgtag_t
382{
383 if (reply.label() != -L4_ENOREPLY)
384 {
385 Ipc_svr::Reply_mode m = this->before_reply(reply, utcb);
387 {
388 this->setup_wait(utcb, m);
389 return l4_ipc_reply_and_wait(utcb, reply, p, this->timeout());
390 }
391 else
392 {
393 l4_msgtag_t res = l4_ipc_send(L4_INVALID_CAP | L4_SYSF_REPLY, utcb, reply, this->timeout());
394 if (res.has_error())
395 return res;
396 }
397 }
398 this->setup_wait(utcb, Ipc_svr::Reply_separate);
399 return l4_ipc_wait(utcb, p, this->timeout());
400}
401
402template< typename L >
403template< typename DISPATCH >
404inline L4_NORETURN void
405Server<L>::internal_loop(DISPATCH dispatch, l4_utcb_t *utcb)
406{
407 l4_msgtag_t res;
408 l4_umword_t p;
409 l4_msgtag_t r = l4_msgtag(-L4_ENOREPLY, 0, 0, 0);
410
411 while (true)
412 {
413 res = reply_n_wait(r, &p, utcb);
414 if (res.has_error())
415 {
416 this->error(res, utcb);
417 r = l4_msgtag(-L4_ENOREPLY, 0, 0, 0);
418 continue;
419 }
420
421 r = dispatch(res, p, utcb);
422 }
423}
424
425} // namespace L4
C++ interface for capabilities.
Definition capability.h:219
Empty implementation of Server_iface.
L4::Cap< void > get_rcv_cap(int) const override
Returns L4::Cap<void>::Invalid, we have no buffer management.
int remove_timeout(Timeout *) override
Returns -L4_ENOSYS, we have no timeout queue.
int alloc_buffer_demand(Demand const &demand) override
Tells the server to allocate buffers for the given demand.
unsigned first_free_br() const
Returns 1 as first free buffer.
int realloc_rcv_cap(int) override
Returns -L4_ENOMEM, we have no buffer management.
int add_timeout(Timeout *, l4_kernel_clock_t) override
Returns -L4_ENOSYS, we have no timeout queue.
void setup_wait(l4_utcb_t *utcb, L4::Ipc_svr::Reply_mode)
Setup wait function for the server loop (Server<>).
Interface for server-loop related functions.
Definition ipc_epiface:37
Callback interface for Timeout_queue.
Basic server loop for handling client requests.
L4_NORETURN void loop_dbg(R r, Printer p, l4_utcb_t *u=l4_utcb())
Server loop with internal exception handling including message printing.
l4_msgtag_t reply_n_wait(l4_msgtag_t reply, l4_umword_t *p, l4_utcb_t *)
Internal implementation for reply and wait.
Server()
Initializes the server loop.
L4_NORETURN void internal_loop(DISPATCH dispatch, l4_utcb_t *)
The server loop.
L4_NORETURN void loop(R r, l4_utcb_t *u=l4_utcb())
Server loop with internal exception handling.
L4_NORETURN void loop_noexc(R r, l4_utcb_t *u=l4_utcb())
Server loop without exception handling.
Server(l4_utcb_t *)
Initializes the server loop.
Data type for expressing the needed receive buffers at the server-side of an interface.
Definition __typeinfo.h:507
bool no_demand() const noexcept
Definition __typeinfo.h:532
Reply_mode
Reply mode for server loop.
@ Reply_separate
Server shall call reply and wait separately.
@ Reply_compound
Server shall use a compound reply and wait (fast).
unsigned long l4_umword_t
Unsigned machine word.
Definition l4int.h:40
l4_uint64_t l4_kernel_clock_t
Kernel clock type.
Definition l4int.h:53
@ L4_INVALID_CAP
Invalid capability selector.
Definition consts.h:157
@ L4_ENOSYS
No sys.
Definition err.h:50
@ L4_ENOREPLY
No reply.
Definition err.h:55
@ L4_EOK
Ok.
Definition err.h:32
@ L4_ENOMEM
No memory.
Definition err.h:39
l4_msgtag_t l4_ipc_reply_and_wait(l4_utcb_t *utcb, l4_msgtag_t tag, l4_umword_t *label, l4_timeout_t timeout) L4_NOTHROW
Reply and wait operation (uses the reply capability).
Definition ipc.h:572
l4_msgtag_t l4_ipc_send(l4_cap_idx_t dest, l4_utcb_t *utcb, l4_msgtag_t tag, l4_timeout_t timeout) L4_NOTHROW
Send a message to an object (do not wait for a reply).
Definition ipc.h:586
l4_msgtag_t l4_ipc_wait(l4_utcb_t *utcb, l4_umword_t *label, l4_timeout_t timeout) L4_NOTHROW
Wait for an incoming message from any possible sender.
Definition ipc.h:593
@ L4_SYSF_REPLY
Reply flag.
Definition consts.h:104
l4_msgtag_t l4_msgtag(long label, unsigned words, unsigned items, unsigned flags) L4_NOTHROW
Create a message tag from the specified values.
Definition types.h:404
#define L4_IPC_SEND_TIMEOUT_0
0 send timeout
Definition __timeout.h:78
struct l4_utcb_t l4_utcb_t
Opaque type for the UTCB.
Definition utcb.h:56
l4_utcb_t * l4_utcb(void) L4_NOTHROW L4_PURE
Get the UTCB address.
Definition utcb.h:346
#define L4_NORETURN
Noreturn function attribute.
Definition compiler.h:197
#define L4_DEPRECATED(s)
Mark symbol deprecated.
Definition compiler.h:280
L4 low-level kernel interface.
Mix in for LOOP_HOOKS to always use compound reply and wait.
Dispatch helper that, in addition to what Exc_dispatch does, prints exception messages.
l4_msgtag_t operator()(l4_msgtag_t tag, l4_umword_t obj, l4_utcb_t *utcb)
Dispatch the call via Direct_dispatch<R>(), handle exceptions, and print the exception message.
Dbg_dispatch(R r, Printer p)
Make an exception handling dispatcher.
Mix in for LOOP_HOOKS for setup_wait no op.
Mix in for LOOP_HOOKS to use a 0 send and a infinite receive timeout.
R * r
stores a pointer to the registry object
Direct_dispatch(R *r)
Make a direct dispatcher.
Direct dispatch helper, for forwarding dispatch calls to a registry R.
R & r
stores a reference to the registry object
l4_msgtag_t operator()(l4_msgtag_t tag, l4_umword_t obj, l4_utcb_t *utcb)
call operator forwarding to r.dispatch()
Direct_dispatch(R &r)
Make a direct dispatcher.
Dispatch helper wrapping try {} catch {} around the dispatch call.
Exc_dispatch(R r)
Make an exception handling dispatcher.
l4_msgtag_t operator()(l4_msgtag_t tag, l4_umword_t obj, l4_utcb_t *utcb)
Dispatch the call via Direct_dispatch<R>() and handle exceptions.
Mix in for LOOP_HOOKS to ignore IPC errors.
Encapsulation of the buffer-registers block in the UTCB.
Definition utcb.h:83
l4_umword_t br[L4_UTCB_GENERIC_BUFFERS_SIZE]
Buffer registers.
Definition utcb.h:88
l4_umword_t bdr
Buffer descriptor.
Definition utcb.h:85
Message tag data structure.
Definition types.h:153
long label() const L4_NOTHROW
Get the protocol value.
Definition types.h:157
bool has_error() const L4_NOTHROW
Test if flags indicate an error.
Definition types.h:190
Timeout pair.
Definition __timeout.h:53