1
/*
2
* \brief Object pool - map capabilities to objects
3
* \author Norman Feske
4
* \author Alexander Boettcher
5
* \author Stafen Kalkowski
6
* \date 2006-06-26
7
*/
8
9
/*
10
* Copyright (C) 2006-2013 Genode Labs GmbH
11
*
12
* This file is part of the Genode OS framework, which is distributed
13
* under the terms of the GNU General Public License version 2.
14
*/
15
16
#
ifndef _INCLUDE__BASE__OBJECT_POOL_H_
17
#
define _INCLUDE__BASE__OBJECT_POOL_H_
18
19
#
include <util/avl_tree.h>
20
#
include <util/noncopyable.h>
21
#
include <base/capability.h>
22
#
include <base/weak_ptr.h>
23
24
namespace
Genode {
template
<
typename
>
class
Object_pool;
}
25
26
27
/**
28
* Map capabilities to local objects
29
*
30
* \param OBJ_TYPE object type (must be inherited from Object_pool::Entry)
31
*
32
* The local names of a capabilities are used to differentiate multiple server
33
* objects managed by one and the same object pool.
34
*/
35
template
<
typename
OBJ_TYPE
>
36
class
Genode::
Object_pool
37
{
38
public
:
39
40
class
Entry :
public
Avl_node<
Entry
>
41
{
42
private
:
43
44
friend
class
Object_pool;
45
friend
class
Avl_tree<
Entry
>
;
46
47
struct
Entry_lock :
Weak_object<
Entry_lock
>
,
Noncopyable
48
{
49
Entry &
obj;
50
51
Entry_lock(
Entry &
e
)
:
obj(
e)
{
}
52
~
Entry_lock(
)
{
53
Weak_object<
Entry_lock
>
::
lock_for_destruction(
)
;
}
54
}
;
55
56
Untyped_capability _cap;
57
Entry_lock _lock {
*
this }
;
58
59
inline
unsigned
long
_obj_id(
)
{
return
_cap.
local_name(
)
;
}
60
61
public
:
62
63
Entry(
)
{
}
64
Entry(
Untyped_capability
cap
)
:
_cap(
cap)
{
}
65
66
virtual
~
Entry(
)
{
}
67
68
/**
69
* Avl_node interface
70
*/
71
bool
higher(
Entry *
e
)
{
return
e->
_obj_id(
)
>
_obj_id(
)
;
}
72
void
recompute(
)
{
}
/* for gcc-3.4 compatibility */
73
74
/**
75
* Support for object pool
76
*/
77
Entry *
find_by_obj_id(
unsigned
long
obj_id
)
78
{
79
if
(
obj_id ==
_obj_id(
)
)
return
this
;
80
81
Entry *
obj =
this->
child(
obj_id >
_obj_id(
)
)
;
82
83
return
obj ?
obj->
find_by_obj_id(
obj_id)
: 0
;
84
}
85
86
/**
87
* Assign capability to object pool entry
88
*/
89
void
cap(
Untyped_capability
c
)
{
_cap =
c;
}
90
91
Untyped_capability const
cap(
)
const
{
return
_cap
;
}
92
}
;
93
94
private
:
95
96
Avl_tree<
Entry
>
_tree;
97
Lock _lock;
98
99
protected
:
100
101
bool
empty(
)
102
{
103
Lock::
Guard
lock_guard(
_lock
)
;
104
return
_tree.
first(
)
==
nullptr
;
105
}
106
107
public
:
108
109
void
insert(
OBJ_TYPE *
obj
)
110
{
111
Lock::
Guard
lock_guard(
_lock
)
;
112
_tree.
insert(
obj)
;
113
}
114
115
void
remove(
OBJ_TYPE *
obj
)
116
{
117
Lock::
Guard
lock_guard(
_lock
)
;
118
_tree.
remove(
obj)
;
119
}
120
121
template
<
typename
FUNC
>
122
auto apply(
unsigned
long capid,
FUNC func)
123
->
typename
Trait::
Functor<
decltype(
&
FUNC::
operator
(
)
)
>
::
Return_type
124
{
125
using
Functor =
Trait::
Functor<
decltype(
&
FUNC::
operator
(
)
)
>
;
126
using
Object_pointer =
typename
Functor::
template
Argument<
0
>
::
Type;
127
using
Weak_ptr =
Weak_ptr<
typename
Entry::
Entry_lock
>
;
128
using
Locked_ptr =
Locked_ptr<
typename
Entry::
Entry_lock
>
;
129
130
Weak_ptr ptr;
131
132
{
133
Lock::
Guard
lock_guard(
_lock
)
;
134
135
Entry *
entry =
_tree.
first(
)
?
136
_tree.
first(
)
->
find_by_obj_id(
capid)
: nullptr;
137
138
if
(
entry)
ptr =
entry->
_lock.
weak_ptr(
)
;
139
}
140
141
{
142
Locked_ptr
lock_ptr(
ptr
)
;
143
Object_pointer op =
lock_ptr.
is_valid(
)
144
?
dynamic_cast
<
Object_pointer
>
(
&
lock_ptr->
obj)
: nullptr;
145
return
func(
op)
;
146
}
147
}
148
149
template
<
typename
FUNC
>
150
auto apply(
Untyped_capability cap,
FUNC func)
151
->
typename
Trait::
Functor<
decltype(
&
FUNC::
operator
(
)
)
>
::
Return_type
152
{
153
return
apply(
cap.
local_name(
)
,
func)
;
154
}
155
156
template
<
typename
FUNC
>
157
void
remove_all(
FUNC
func
)
158
{
159
using
Weak_ptr =
Weak_ptr<
typename
Entry::
Entry_lock
>
;
160
using
Locked_ptr =
Locked_ptr<
typename
Entry::
Entry_lock
>
;
161
162
for
(
;;)
{
163
OBJ_TYPE *
obj;
164
165
{
166
Lock::
Guard
lock_guard(
_lock
)
;
167
168
if
(
!
(
(
obj =
(
OBJ_TYPE*
)
_tree.
first(
)
)
)
)
return
;
169
170
Weak_ptr ptr =
obj->
_lock.
weak_ptr(
)
;
171
{
172
Locked_ptr
lock_ptr(
ptr
)
;
173
if
(
!
lock_ptr.
is_valid(
)
)
return
;
174
175
_tree.
remove(
obj)
;
176
}
177
}
178
179
func(
obj)
;
180
}
181
}
182
}
;
183
184
#
endif /* _INCLUDE__BASE__OBJECT_POOL_H_ */