2 * Copyright (C) 2013 Martin Willi
3 * Copyright (C) 2013 revosec AG
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 #include "stream_manager.h"
18 #include <threading/rwlock.h>
20 typedef struct private_stream_manager_t private_stream_manager_t
;
23 * Private data of an stream_manager_t object.
25 struct private_stream_manager_t
{
28 * Public stream_manager_t interface.
30 stream_manager_t
public;
33 * List of registered stream constructors, as stream_entry_t
35 linked_list_t
*streams
;
38 * List of registered service constructors, as service_entry_t
40 linked_list_t
*services
;
49 * Registered stream backend
54 /** constructor function */
55 stream_constructor_t create
;
59 * Registered service backend
64 /** constructor function */
65 stream_service_constructor_t create
;
68 METHOD(stream_manager_t
, connect_
, stream_t
*,
69 private_stream_manager_t
*this, char *uri
)
71 enumerator_t
*enumerator
;
72 stream_entry_t
*entry
;
73 stream_t
*stream
= NULL
;
75 this->lock
->read_lock(this->lock
);
76 enumerator
= this->streams
->create_enumerator(this->streams
);
77 while (enumerator
->enumerate(enumerator
, &entry
))
79 if (strpfx(uri
, entry
->prefix
))
81 stream
= entry
->create(uri
);
88 enumerator
->destroy(enumerator
);
89 this->lock
->unlock(this->lock
);
94 METHOD(stream_manager_t
, create_service
, stream_service_t
*,
95 private_stream_manager_t
*this, char *uri
, int backlog
)
97 enumerator_t
*enumerator
;
98 service_entry_t
*entry
;
99 stream_service_t
*service
= NULL
;
101 this->lock
->read_lock(this->lock
);
102 enumerator
= this->services
->create_enumerator(this->services
);
103 while (enumerator
->enumerate(enumerator
, &entry
))
105 if (strpfx(uri
, entry
->prefix
))
107 service
= entry
->create(uri
, backlog
);
114 enumerator
->destroy(enumerator
);
115 this->lock
->unlock(this->lock
);
120 METHOD(stream_manager_t
, add_stream
, void,
121 private_stream_manager_t
*this, char *prefix
, stream_constructor_t create
)
123 stream_entry_t
*entry
;
126 .prefix
= strdup(prefix
),
130 this->lock
->write_lock(this->lock
);
131 this->streams
->insert_last(this->streams
, entry
);
132 this->lock
->unlock(this->lock
);
135 METHOD(stream_manager_t
, remove_stream
, void,
136 private_stream_manager_t
*this, stream_constructor_t create
)
138 enumerator_t
*enumerator
;
139 stream_entry_t
*entry
;
141 this->lock
->write_lock(this->lock
);
142 enumerator
= this->streams
->create_enumerator(this->streams
);
143 while (enumerator
->enumerate(enumerator
, &entry
))
145 if (entry
->create
== create
)
147 this->streams
->remove_at(this->streams
, enumerator
);
152 enumerator
->destroy(enumerator
);
153 this->lock
->unlock(this->lock
);
156 METHOD(stream_manager_t
, add_service
, void,
157 private_stream_manager_t
*this, char *prefix
,
158 stream_service_constructor_t create
)
160 service_entry_t
*entry
;
163 .prefix
= strdup(prefix
),
167 this->lock
->write_lock(this->lock
);
168 this->services
->insert_last(this->services
, entry
);
169 this->lock
->unlock(this->lock
);
172 METHOD(stream_manager_t
, remove_service
, void,
173 private_stream_manager_t
*this, stream_service_constructor_t create
)
175 enumerator_t
*enumerator
;
176 service_entry_t
*entry
;
178 this->lock
->write_lock(this->lock
);
179 enumerator
= this->services
->create_enumerator(this->services
);
180 while (enumerator
->enumerate(enumerator
, &entry
))
182 if (entry
->create
== create
)
184 this->services
->remove_at(this->services
, enumerator
);
189 enumerator
->destroy(enumerator
);
190 this->lock
->unlock(this->lock
);
193 METHOD(stream_manager_t
, destroy
, void,
194 private_stream_manager_t
*this)
196 remove_stream(this, stream_create_unix
);
197 remove_stream(this, stream_create_tcp
);
198 remove_service(this, stream_service_create_unix
);
199 remove_service(this, stream_service_create_tcp
);
201 this->streams
->destroy(this->streams
);
202 this->services
->destroy(this->services
);
203 this->lock
->destroy(this->lock
);
210 stream_manager_t
*stream_manager_create()
212 private_stream_manager_t
*this;
216 .connect
= _connect_
,
217 .create_service
= _create_service
,
218 .add_stream
= _add_stream
,
219 .remove_stream
= _remove_stream
,
220 .add_service
= _add_service
,
221 .remove_service
= _remove_service
,
224 .streams
= linked_list_create(),
225 .services
= linked_list_create(),
226 .lock
= rwlock_create(RWLOCK_TYPE_DEFAULT
),
229 add_stream(this, "unix://", stream_create_unix
);
230 add_stream(this, "tcp://", stream_create_tcp
);
231 add_service(this, "unix://", stream_service_create_unix
);
232 add_service(this, "tcp://", stream_service_create_tcp
);
234 return &this->public;