]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/mag/include/server/object
c97c710567275cf3ed9cbc65929f1cf339288d5f
[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
78 class Registry : protected L4Re::Util::Object_registry
79 {
80 public:
81   L4::Cap<void> register_obj(cxx::Ref_ptr<Object> o)
82   {
83
84     L4::Cap<void> r = L4Re::Util::Object_registry::register_obj(o.ptr());
85
86     if (r)
87       add_gc_obj(o.release());
88
89     return r;
90   }
91
92   L4::Cap<void> register_obj(cxx::Ref_ptr<Object> o, char const *name)
93   {
94     L4::Cap<void> r = L4Re::Util::Object_registry::register_obj(o.ptr(), name);
95
96     if (r)
97       add_gc_obj(o.release());
98
99     return r;
100   }
101
102   virtual void add_gc_obj(Object *o) = 0;
103
104   using L4Re::Util::Object_registry::dispatch;
105
106 };
107
108 }