]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/mag/include/server/object
update
[l4.git] / l4 / pkg / mag / include / server / object
1 // vi:ft=cpp
2 /*
3  * (c) 2010 Alexander Warg <warg@os.inf.tu-dresden.de>
4  *     economic rights: Technische Universität Dresden (Germany)
5  *
6  * This file is part of TUD:OS and distributed under the terms of the
7  * GNU General Public License 2.
8  * Please see the COPYING-GPL-2 file for details.
9  */
10 #pragma once
11
12 #include <l4/cxx/ipc_server>
13 #include <l4/cxx/ref_ptr>
14 #include <l4/re/util/object_registry>
15
16 #include <cassert>
17
18 namespace Mag_server {
19
20 class Object_gc;
21
22 class Object : public L4::Server_object
23 {
24 private:
25   friend class Object_gc;
26   template< typename T >
27   friend class Gc_ref_count;
28
29   mutable int _ref_cnt;
30
31   Object *_n;
32   Object **_pn;
33
34   void dequeue()
35   {
36     if (!_pn)
37       return;
38
39     if (_n)
40       _n->_pn = _pn;
41
42     *_pn = _n;
43     _n = 0;
44     _pn = 0;
45   }
46
47   void enqueue(Object **q)
48   {
49     _n = *q;
50     _pn = q;
51
52     if (_n)
53       _n->_pn = &_n;
54
55     *q = this;
56   }
57
58 public:
59   Object() : _ref_cnt(0), _pn(0)
60   {}
61
62   void add_ref() const throw() { ++_ref_cnt; }
63   int remove_ref() const throw() { return --_ref_cnt; }
64
65   virtual void destroy() = 0;
66   virtual ~Object() = 0;
67 };
68
69 inline
70 Object::~Object()
71 {
72   assert (_pn == 0); // must not be queued
73 }
74
75
76
77 class Registry : protected L4Re::Util::Object_registry
78 {
79 public:
80   L4::Cap<void> register_obj(cxx::Ref_ptr<Object> o)
81   {
82     L4::Cap<void> r = L4Re::Util::Object_registry::register_obj(o.ptr());
83
84     if (r)
85       add_gc_obj(o.release());
86
87     return r;
88   }
89
90   L4::Cap<void> register_obj(cxx::Ref_ptr<Object> o, char const *name)
91   {
92     L4::Cap<void> r = L4Re::Util::Object_registry::register_obj(o.ptr(), name);
93
94     if (r)
95       add_gc_obj(o.release());
96
97     return r;
98   }
99
100   virtual void add_gc_obj(Object *o) = 0;
101
102   using L4Re::Util::Object_registry::dispatch;
103 };
104
105 }