- Info
1
9
10
16
17 #ifndef _INCLUDE__ROOT__COMPONENT_H_
18 #define _INCLUDE__ROOT__COMPONENT_H_
19
20 #include <root/server.h>
21 #include <base/heap.h>
22 #include <ram_session/ram_session.h>
23 #include <util/arg_string.h>
24 #include <base/printf.h>
25
26 namespace Genode {
27
28
31 class Single_client
32 {
33 private:
34
35 bool _used;
36
37 public:
38
39 Single_client() : _used(0) { }
40
41 void aquire(const char *args)
42 {
43 if (_used)
44 throw Root::Unavailable();
45
46 _used = true;
47 }
48
49 void release() { _used = false; }
50 };
51
52
53
56 struct Multiple_clients
57 {
58 void aquire(const char *args) { }
59 void release() { }
60 };
61
62
63
89 template <typename SESSION_TYPE, typename POLICY = Multiple_clients>
90 class Root_component : public Root_server, private POLICY
91 {
92 private:
93
94
98 Server_entrypoint *_ep;
99
100
106 Allocator *_md_alloc;
107
108 protected:
109
110
127 virtual SESSION_TYPE *_create_session(const char *args) = 0;
128
129 virtual void _destroy_session(SESSION_TYPE *session) {
130 destroy(_md_alloc, session); }
131
132
135 Allocator *md_alloc() { return _md_alloc; }
136 Server_entrypoint *ep() { return _ep; }
137
138 public:
139
140
148 Root_component(Server_entrypoint *ep, Allocator *metadata_alloc)
149 : Root_server(), _ep(ep), _md_alloc(metadata_alloc) { }
150
151
152
155
156 Session_capability session(const char *args)
157 {
158 POLICY::aquire(args);
159
160
164 size_t ram_quota = Arg_string::find_arg(args, "ram_quota").long_value(0);
165 long remaining_ram_quota = ram_quota - sizeof(SESSION_TYPE);
166 if (remaining_ram_quota < 0) {
167 PERR("Insufficient ram quota, provided=%zd, required=%zd",
168 ram_quota, sizeof(SESSION_TYPE));
169 throw Quota_exceeded();
170 }
171
172 SESSION_TYPE *s = 0;
173 try {
174 s = _create_session(args);
175 } catch (Allocator::Out_of_memory) {
176 throw Quota_exceeded();
177 }
178
179 return Session_capability(_ep->manage(s));
180 }
181
182 void close(Session_capability session)
183 {
184 SESSION_TYPE *s;
185
186 s = dynamic_cast<SESSION_TYPE *>(_ep->obj_by_cap(session));
187 if (!s) return;
188
189
190 _ep->dissolve(s);
191
192 _destroy_session(s);
193
194 POLICY::release();
195 return;
196 }
197 };
198 }
199
200 #endif