]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/kobject_helper.cpp
eb84b887109c890bde8d4434f9b8dd5dd4e18ec3
[l4.git] / kernel / fiasco / src / kern / kobject_helper.cpp
1 INTERFACE:
2
3 #include "kobject.h"
4 #include "thread.h"
5 #include <type_traits>
6
7 class Kobject_helper_base
8 {
9 protected:
10   static Mword _utcb_dummy[];
11   static Utcb *utcb_dummy()
12   {
13     char *x = reinterpret_cast<char*>(&_utcb_dummy);
14     return reinterpret_cast<Utcb*>(x);
15   }
16
17   static L4_msg_tag no_reply() { return L4_msg_tag(L4_msg_tag::Schedule); }
18   static bool have_receive(Utcb *rcv) { return rcv != utcb_dummy(); }
19 };
20
21 template<typename T, typename Base = Kobject>
22 class Kobject_h : public Base, protected Kobject_helper_base
23 {
24 private:
25   static Sender *_sender(Thread *, Sender *t) { return t; }
26   static Sender *_sender(Thread *ct, ...) { return ct; }
27
28 public:
29
30   explicit Kobject_h() {}
31
32   template< typename... A >
33   explicit Kobject_h(A&&... args) : Base(cxx::forward<A>(args)...) {}
34
35   void invoke(L4_obj_ref self, Mword rights, Syscall_frame *f, Utcb *u)
36   {
37     L4_msg_tag res(no_reply());
38     if (EXPECT_TRUE(self.op() & L4_obj_ref::Ipc_send))
39       res = static_cast<T*>(this)->T::kinvoke(self, rights, f, (Utcb const *)u,
40                                               self.have_recv() ? u : utcb_dummy());
41
42     if (EXPECT_FALSE(res.has_error()))
43       {
44         f->tag(res);
45         return;
46       }
47
48     if (self.have_recv())
49       {
50         if (!res.do_switch())
51           {
52             Thread *t = current_thread();
53             Sender *s = (self.op() & L4_obj_ref::Ipc_open_wait) ? 0 : _sender(t, static_cast<T*>(this));
54             t->do_ipc(f->tag(), 0, 0, true, s, f->timeout(), f, rights);
55             return;
56           }
57         else
58           f->tag(res);
59       }
60   }
61
62 };
63
64
65 IMPLEMENTATION:
66
67 Mword Kobject_helper_base::_utcb_dummy[(sizeof(Utcb) + sizeof(Mword) - 1) / sizeof(Mword)];
68