1
/*
2
* \brief Parent interface
3
* \author Norman Feske
4
* \date 2006-05-10
5
*/
6
7
/*
8
* Copyright (C) 2006-2013 Genode Labs GmbH
9
*
10
* This file is part of the Genode OS framework, which is distributed
11
* under the terms of the GNU General Public License version 2.
12
*/
13
14
#
ifndef _INCLUDE__PARENT__PARENT_H_
15
#
define _INCLUDE__PARENT__PARENT_H_
16
17
#
include <base/exception.h>
18
#
include <base/rpc.h>
19
#
include <base/rpc_args.h>
20
#
include <base/thread.h>
21
#
include <session/capability.h>
22
#
include <root/capability.h>
23
24
namespace
Genode {
class
Parent;
}
25
26
27
class
Genode::
Parent
28
{
29
private
:
30
31
/**
32
* Recursively announce inherited service interfaces
33
*
34
* At compile time, the `ROOT` type is inspected for the presence
35
* of the `Rpc_inherited_interface` type in the corresponding
36
* session interface. If present, the session type gets announced.
37
* This works recursively.
38
*/
39
template
<
typename
ROOT
>
40
void
_announce_base(
Capability<
ROOT
>
const
&
,
Meta::
Bool_to_type<
false
>
*
)
{
}
41
42
/*
43
* This overload gets selected if the ROOT interface corresponds to
44
* an inherited session type.
45
*/
46
template
<
typename
ROOT
>
47
inline
void
_announce_base(
Capability<
ROOT
>
const
&
,
Meta::
Bool_to_type<
true
>
*
)
;
48
49
public
:
50
51
/*********************
52
** Exception types **
53
*********************/
54
55
class
Exception :
public
::
Genode::
Exception
{
}
;
56
class
Service_denied :
public
Exception
{
}
;
57
class
Quota_exceeded :
public
Exception
{
}
;
58
class
Unavailable :
public
Exception
{
}
;
59
60
typedef
Rpc_in_buffer<
64
>
Service_name
;
61
typedef
Rpc_in_buffer<
160
>
Session_args
;
62
typedef
Rpc_in_buffer<
160
>
Upgrade_args
;
63
64
/**
65
* Use `String` instead of `Rpc_in_buffer` because `Resource_args`
66
* is used as both in and out parameter.
67
*/
68
typedef
String<
160
>
Resource_args
;
69
70
71
virtual
~
Parent(
)
{
}
72
73
/**
74
* Tell parent to exit the program
75
*/
76
virtual
void
exit(
int
exit_value
)
=
0
;
77
78
/**
79
* Announce service to the parent
80
*/
81
virtual
void
announce(
Service_name const
&
service_name
,
82
Root_capability
service_root
)
=
0
;
83
84
85
/**
86
* Announce service to the parent
87
*
88
* \param service_root root capability
89
*
90
* The type of the specified `service_root` capability match with
91
* an interface that provides a `Session_type` type (i.e., a
92
* `Typed_root` interface). This `Session_type` is expected to
93
* host a class function called `service_name` returning the
94
* name of the provided interface as null-terminated string.
95
*/
96
template
<
typename
ROOT_INTERFACE
>
97
void
announce(
Capability<
ROOT_INTERFACE
>
const
&
service_root
)
98
{
99
typedef
typename
ROOT_INTERFACE::
Session_type Session;
100
announce(
Session::
service_name(
)
,
service_root)
;
101
102
/*
103
* Announce inherited session types
104
*
105
* Select the overload based on the presence of the type
106
* `Rpc_inherited_interface` within the session type.
107
*/
108
_announce_base(
service_root,
109
(
Meta::
Bool_to_type<
Rpc_interface_is_inherited<
Session
>
::
VALUE
>
*
)
0)
;
110
}
111
112
/**
113
* Create session to a service
114
*
115
* \param service_name name of the requested interface
116
* \param args session constructor arguments
117
* \param affinity preferred CPU affinity for the session
118
*
119
* \throw Service_denied parent denies session request
120
* \throw Quota_exceeded our own quota does not suffice for
121
* the creation of the new session
122
* \throw Unavailable
123
*
124
* \return untyped capability to new session
125
*
126
* The use of this method is discouraged. Please use the type safe
127
* `session()` template instead.
128
*/
129
virtual
Session_capability
session(
Service_name const
&
service_name
,
130
Session_args const
&
args
,
131
Affinity const
&
affinity
=
Affinity(
)
)
=
0
;
132
133
/**
134
* Create session to a service
135
*
136
* \param SESSION_TYPE session interface type
137
* \param args session constructor arguments
138
* \param affinity preferred CPU affinity for the session
139
*
140
* \throw Service_denied parent denies session request
141
* \throw Quota_exceeded our own quota does not suffice for
142
* the creation of the new session
143
* \throw Unavailable
144
*
145
* \return capability to new session
146
*/
147
template
<
typename
SESSION_TYPE
>
148
Capability<
SESSION_TYPE
>
session(
Session_args const
&
args
,
149
Affinity const
&
affinity
=
Affinity(
)
)
150
{
151
Session_capability cap =
session(
SESSION_TYPE::
service_name(
)
,
152
args,
affinity)
;
153
return
reinterpret_cap_cast<
SESSION_TYPE
>
(
cap)
;
154
}
155
156
/**
157
* Transfer our quota to the server that provides the specified session
158
*
159
* \param to_session recipient session
160
* \param args description of the amount of quota to transfer
161
*
162
* \throw Quota_exceeded quota could not be transferred
163
*
164
* The `args` argument has the same principle format as the `args`
165
* argument of the `session` operation.
166
* The error case indicates that there is not enough unused quota on
167
* the source side.
168
*/
169
virtual
void
upgrade(
Session_capability
to_session
,
170
Upgrade_args const
&
args
)
=
0
;
171
172
/**
173
* Close session
174
*/
175
virtual
void
close(
Session_capability
session
)
=
0
;
176
177
/**
178
* Provide thread_cap of main thread
179
*/
180
virtual
Thread_capability
main_thread_cap(
)
const
=
0
;
181
182
/**
183
* Register signal handler for resource notifications
184
*/
185
virtual
void
resource_avail_sigh(
Signal_context_capability
sigh
)
=
0
;
186
187
/**
188
* Request additional resources
189
*
190
* By invoking this method, a process is able to inform its
191
* parent about the need for additional resources. The argument
192
* string contains a resource description in the same format as
193
* used for session-construction arguments. In particular, for
194
* requesting additional RAM quota, the argument looks like
195
* "ram_quota=<amount>" where `amount` is the amount of additional
196
* resources expected from the parent. If the parent complies with
197
* the request, it submits a resource-available signal to the
198
* handler registered via `resource_avail_sigh()`. On the reception
199
* of such a signal, the process can re-evaluate its resource quota
200
* and resume execution.
201
*/
202
virtual
void
resource_request(
Resource_args const
&
args
)
=
0
;
203
204
/**
205
* Register signal handler for resource yield notifications
206
*
207
* Using the yield signal, the parent is able to inform the process
208
* about its wish to regain resources.
209
*/
210
virtual
void
yield_sigh(
Signal_context_capability
sigh
)
=
0
;
211
212
/**
213
* Obtain information about the amount of resources to free
214
*
215
* The amount of resources returned by this method is the
216
* goal set by the parent. It is not commanded but merely meant
217
* as a friendly beg to cooperate. The process is not obligated
218
* to comply. If the process decides to take action to free
219
* resources, it can inform its parent about the availability
220
* of freed up resources by calling `yield_response()`.
221
*/
222
virtual
Resource_args
yield_request(
)
=
0
;
223
224
/**
225
* Notify the parent about a response to a yield request
226
*/
227
virtual
void
yield_response(
)
=
0
;
228
229
230
/*********************
231
** RPC declaration **
232
*********************/
233
234
GENODE_RPC
(
Rpc_exit,
void,
exit,
int)
;
235
GENODE_RPC
(
Rpc_announce,
void,
announce,
236
Service_name const
&
,
Root_capability)
;
237
GENODE_RPC_THROW
(
Rpc_session,
Session_capability,
session,
238
GENODE_TYPE_LIST
(
Service_denied,
Quota_exceeded,
Unavailable)
,
239
Service_name const
&
,
Session_args const
&
,
Affinity const
&
)
;
240
GENODE_RPC_THROW
(
Rpc_upgrade,
void,
upgrade,
241
GENODE_TYPE_LIST
(
Quota_exceeded)
,
242
Session_capability,
Upgrade_args const
&
)
;
243
GENODE_RPC
(
Rpc_close,
void,
close,
Session_capability)
;
244
GENODE_RPC
(
Rpc_main_thread,
Thread_capability,
main_thread_cap)
;
245
GENODE_RPC
(
Rpc_resource_avail_sigh,
void,
resource_avail_sigh,
246
Signal_context_capability)
;
247
GENODE_RPC
(
Rpc_resource_request,
void,
resource_request,
248
Resource_args const
&
)
;
249
GENODE_RPC
(
Rpc_yield_sigh,
void,
yield_sigh,
Signal_context_capability)
;
250
GENODE_RPC
(
Rpc_yield_request,
Resource_args,
yield_request)
;
251
GENODE_RPC
(
Rpc_yield_response,
void,
yield_response)
;
252
253
typedef
Meta::
Type_tuple<
Rpc_exit
,
254
Meta::
Type_tuple<
Rpc_announce
,
255
Meta::
Type_tuple<
Rpc_session
,
256
Meta::
Type_tuple<
Rpc_upgrade
,
257
Meta::
Type_tuple<
Rpc_close
,
258
Meta::
Type_tuple<
Rpc_main_thread
,
259
Meta::
Type_tuple<
Rpc_resource_avail_sigh
,
260
Meta::
Type_tuple<
Rpc_resource_request
,
261
Meta::
Type_tuple<
Rpc_yield_sigh
,
262
Meta::
Type_tuple<
Rpc_yield_request
,
263
Meta::
Type_tuple<
Rpc_yield_response
,
264
Meta::
Empty
>
265
>
>
>
>
>
>
>
>
>
>
Rpc_functions
;
266
}
;
267
268
269
template
<
typename
ROOT_INTERFACE
>
270
void
271
Genode::
Parent::
_announce_base(
Genode::
Capability<
ROOT_INTERFACE
>
const
&
service_root
,
272
Genode::
Meta::
Bool_to_type<
true
>
*
)
273
{
274
/* shortcut for inherited session type */
275
typedef
typename
ROOT_INTERFACE::
Session_type::
Rpc_inherited_interface
276
Session_type_inherited;
277
278
/* shortcut for root interface type matching the inherited session type */
279
typedef
Typed_root<
Session_type_inherited
>
Root_inherited
;
280
281
/* convert root capability to match the inherited session type */
282
Capability<
Root
>
root =
service_root;
283
Capability<
Root_inherited
>
root_inherited =
static_cap_cast<
Root_inherited
>
(
root)
;
284
285
/* announce inherited service type */
286
announce(
Session_type_inherited::
service_name(
)
,
root_inherited)
;
287
288
/* recursively announce further inherited session types */
289
_announce_base(
root_inherited,
290
(
Meta::
Bool_to_type<
Rpc_interface_is_inherited<
Session_type_inherited
>
::
VALUE
>
*
)
0)
;
291
}
292
293
294
#
endif /* _INCLUDE__PARENT__PARENT_H_ */