15
15
16
16
#include <assert.h>
17
17
#include <string.h>
18
+ #include <stdio.h>
18
19
19
20
#define INITIAL_REGISTRY_SIZE 16
20
21
21
- typedef struct conn_mode_entry {
22
- int (* registry_init_func )(conn_registry_t * registry , udp_socket_config_t * config );
23
- void (* registry_cleanup_func )(conn_registry_t * registry );
24
-
25
- int (* init_func )(juice_agent_t * agent , struct conn_registry * registry ,
26
- udp_socket_config_t * config );
27
- void (* cleanup_func )(juice_agent_t * agent );
28
- void (* lock_func )(juice_agent_t * agent );
29
- void (* unlock_func )(juice_agent_t * agent );
30
- int (* interrupt_func )(juice_agent_t * agent );
31
- int (* send_func )(juice_agent_t * agent , const addr_record_t * dst , const char * data , size_t size ,
32
- int ds );
33
- int (* get_addrs_func )(juice_agent_t * agent , addr_record_t * records , size_t size );
34
-
35
- mutex_t mutex ;
36
- conn_registry_t * registry ;
37
- } conn_mode_entry_t ;
38
-
39
22
#define MODE_ENTRIES_SIZE 3
40
23
41
24
static conn_mode_entry_t mode_entries [MODE_ENTRIES_SIZE ] = {
42
25
{conn_poll_registry_init , conn_poll_registry_cleanup , conn_poll_init , conn_poll_cleanup ,
43
26
conn_poll_lock , conn_poll_unlock , conn_poll_interrupt , conn_poll_send , conn_poll_get_addrs ,
44
- MUTEX_INITIALIZER , NULL },
27
+ NULL , NULL , NULL , MUTEX_INITIALIZER , NULL },
45
28
{conn_mux_registry_init , conn_mux_registry_cleanup , conn_mux_init , conn_mux_cleanup ,
46
29
conn_mux_lock , conn_mux_unlock , conn_mux_interrupt , conn_mux_send , conn_mux_get_addrs ,
47
- MUTEX_INITIALIZER , NULL },
48
- {NULL , NULL , conn_thread_init , conn_thread_cleanup , conn_thread_lock , conn_thread_unlock ,
49
- conn_thread_interrupt , conn_thread_send , conn_thread_get_addrs , MUTEX_INITIALIZER , NULL }};
30
+ conn_mux_listen , conn_mux_get_registry , conn_mux_can_release_registry , MUTEX_INITIALIZER , NULL },
31
+ {NULL , NULL , conn_thread_init , conn_thread_cleanup ,
32
+ conn_thread_lock , conn_thread_unlock , conn_thread_interrupt , conn_thread_send , conn_thread_get_addrs ,
33
+ NULL , NULL , NULL , MUTEX_INITIALIZER , NULL }
34
+ };
50
35
51
- static conn_mode_entry_t * get_mode_entry (juice_agent_t * agent ) {
52
- juice_concurrency_mode_t mode = agent -> config .concurrency_mode ;
36
+ #define MODE_ENTRIES_SIZE 3
37
+
38
+ static conn_mode_entry_t mode_entries [MODE_ENTRIES_SIZE ];
39
+
40
+ conn_mode_entry_t * conn_get_mode_entry (juice_concurrency_mode_t mode ) {
53
41
assert (mode >= 0 && mode < MODE_ENTRIES_SIZE );
54
42
return mode_entries + (int )mode ;
55
43
}
56
44
57
- static int acquire_registry (conn_mode_entry_t * entry , udp_socket_config_t * config ) {
45
+ static conn_mode_entry_t * get_agent_mode_entry (juice_agent_t * agent ) {
46
+ juice_concurrency_mode_t mode = agent -> config .concurrency_mode ;
47
+ return conn_get_mode_entry (mode );
48
+ }
49
+
50
+ static int acquire_registry (conn_mode_entry_t * entry , udp_socket_config_t * config , conn_registry_t * * acquired ) {
58
51
// entry must be locked
59
- conn_registry_t * registry = entry -> registry ;
52
+ conn_registry_t * registry ;
53
+
54
+ if (entry -> get_registry_func ) {
55
+ registry = entry -> get_registry_func (config );
56
+ } else {
57
+ registry = entry -> registry ;
58
+ }
59
+
60
60
if (!registry ) {
61
- if (!entry -> registry_init_func )
61
+ if (!entry -> registry_init_func ) {
62
+ * acquired = NULL ;
62
63
return 0 ;
64
+ }
63
65
64
66
JLOG_DEBUG ("Creating connections registry" );
65
67
@@ -92,33 +94,34 @@ static int acquire_registry(conn_mode_entry_t *entry, udp_socket_config_t *confi
92
94
}
93
95
94
96
entry -> registry = registry ;
95
-
96
97
} else {
97
98
mutex_lock (& registry -> mutex );
98
99
}
99
100
101
+ * acquired = registry ;
102
+
100
103
// registry is locked
101
104
return 0 ;
102
105
}
103
106
104
- static void release_registry (conn_mode_entry_t * entry ) {
107
+ static void release_registry (conn_mode_entry_t * entry , conn_registry_t * registry ) {
105
108
// entry must be locked
106
- conn_registry_t * registry = entry -> registry ;
107
109
if (!registry )
108
110
return ;
109
111
110
112
// registry must be locked
113
+ bool canRelease = entry -> can_release_registry_func ? entry -> can_release_registry_func (registry ) : true;
111
114
112
- if (registry -> agents_count == 0 && registry -> cb_mux_incoming == NULL ) {
115
+ if (registry -> agents_count == 0 && canRelease ) {
113
116
JLOG_DEBUG ("No connection left, destroying connections registry" );
114
117
mutex_unlock (& registry -> mutex );
115
118
116
119
if (entry -> registry_cleanup_func )
117
120
entry -> registry_cleanup_func (registry );
118
121
122
+ entry -> registry = NULL ;
119
123
free (registry -> agents );
120
124
free (registry );
121
- entry -> registry = NULL ;
122
125
return ;
123
126
}
124
127
@@ -129,14 +132,15 @@ static void release_registry(conn_mode_entry_t *entry) {
129
132
}
130
133
131
134
int conn_create (juice_agent_t * agent , udp_socket_config_t * config ) {
132
- conn_mode_entry_t * entry = get_mode_entry (agent );
135
+ conn_mode_entry_t * entry = get_agent_mode_entry (agent );
136
+ conn_registry_t * registry ;
133
137
mutex_lock (& entry -> mutex );
134
- if (acquire_registry (entry , config )) { // locks the registry if created
138
+ if (acquire_registry (entry , config , & registry )) { // locks the registry if created
135
139
mutex_unlock (& entry -> mutex );
136
140
return -1 ;
137
141
}
138
142
139
- conn_registry_t * registry = entry -> registry ;
143
+ agent -> registry = registry ;
140
144
141
145
JLOG_DEBUG ("Creating connection" );
142
146
if (registry ) {
@@ -163,8 +167,8 @@ int conn_create(juice_agent_t *agent, udp_socket_config_t *config) {
163
167
memset (registry -> agents + i , 0 , (new_size - i ) * sizeof (juice_agent_t * ));
164
168
}
165
169
166
- if (get_mode_entry (agent )-> init_func (agent , registry , config )) {
167
- release_registry (entry ); // unlocks the registry
170
+ if (get_agent_mode_entry (agent )-> init_func (agent , registry , config )) {
171
+ release_registry (entry , registry ); // unlocks the registry
168
172
mutex_unlock (& entry -> mutex );
169
173
return -1 ;
170
174
}
@@ -176,7 +180,7 @@ int conn_create(juice_agent_t *agent, udp_socket_config_t *config) {
176
180
mutex_unlock (& registry -> mutex );
177
181
178
182
} else {
179
- if (get_mode_entry (agent )-> init_func (agent , NULL , config )) {
183
+ if (get_agent_mode_entry (agent )-> init_func (agent , NULL , config )) {
180
184
mutex_unlock (& entry -> mutex );
181
185
return -1 ;
182
186
}
@@ -190,11 +194,11 @@ int conn_create(juice_agent_t *agent, udp_socket_config_t *config) {
190
194
}
191
195
192
196
void conn_destroy (juice_agent_t * agent ) {
193
- conn_mode_entry_t * entry = get_mode_entry (agent );
197
+ conn_mode_entry_t * entry = get_agent_mode_entry (agent );
194
198
mutex_lock (& entry -> mutex );
195
199
196
200
JLOG_DEBUG ("Destroying connection" );
197
- conn_registry_t * registry = entry -> registry ;
201
+ conn_registry_t * registry = agent -> registry ;
198
202
if (registry ) {
199
203
mutex_lock (& registry -> mutex );
200
204
@@ -210,7 +214,8 @@ void conn_destroy(juice_agent_t *agent) {
210
214
assert (registry -> agents_count > 0 );
211
215
-- registry -> agents_count ;
212
216
213
- release_registry (entry ); // unlocks the registry
217
+ agent -> registry = NULL ;
218
+ release_registry (entry , registry ); // unlocks the registry
214
219
215
220
} else {
216
221
entry -> cleanup_func (agent );
@@ -224,99 +229,80 @@ void conn_lock(juice_agent_t *agent) {
224
229
if (!agent -> conn_impl )
225
230
return ;
226
231
227
- get_mode_entry (agent )-> lock_func (agent );
232
+ get_agent_mode_entry (agent )-> lock_func (agent );
228
233
}
229
234
230
235
void conn_unlock (juice_agent_t * agent ) {
231
236
if (!agent -> conn_impl )
232
237
return ;
233
238
234
- get_mode_entry (agent )-> unlock_func (agent );
239
+ get_agent_mode_entry (agent )-> unlock_func (agent );
235
240
}
236
241
237
242
int conn_interrupt (juice_agent_t * agent ) {
238
243
if (!agent -> conn_impl )
239
244
return -1 ;
240
245
241
- return get_mode_entry (agent )-> interrupt_func (agent );
246
+ return get_agent_mode_entry (agent )-> interrupt_func (agent );
242
247
}
243
248
244
249
int conn_send (juice_agent_t * agent , const addr_record_t * dst , const char * data , size_t size ,
245
250
int ds ) {
246
251
if (!agent -> conn_impl )
247
252
return -1 ;
248
253
249
- return get_mode_entry (agent )-> send_func (agent , dst , data , size , ds );
254
+ return get_agent_mode_entry (agent )-> send_func (agent , dst , data , size , ds );
250
255
}
251
256
252
257
int conn_get_addrs (juice_agent_t * agent , addr_record_t * records , size_t size ) {
253
258
if (!agent -> conn_impl )
254
259
return -1 ;
255
260
256
- return get_mode_entry (agent )-> get_addrs_func (agent , records , size );
261
+ return get_agent_mode_entry (agent )-> get_addrs_func (agent , records , size );
257
262
}
258
263
259
- static int juice_mux_stop_listen (const char * bind_address , int local_port ) {
260
- (void )bind_address ;
261
- (void )local_port ;
262
-
264
+ int juice_mux_listen (const char * bind_address , int local_port , juice_cb_mux_incoming_t cb , void * user_ptr ) {
263
265
conn_mode_entry_t * entry = & mode_entries [JUICE_CONCURRENCY_MODE_MUX ];
264
266
265
- mutex_lock (& entry -> mutex );
266
-
267
- conn_registry_t * registry = entry -> registry ;
268
- if (!registry ) {
269
- mutex_unlock (& entry -> mutex );
267
+ if (!entry -> mux_listen_func ) {
268
+ JLOG_DEBUG ("juice_mux_listen mux_listen_func is not implemented" );
270
269
return -1 ;
271
270
}
272
271
273
- mutex_lock (& registry -> mutex );
274
-
275
- registry -> cb_mux_incoming = NULL ;
276
- registry -> mux_incoming_user_ptr = NULL ;
277
- conn_mux_interrupt_registry (registry );
278
-
279
- release_registry (entry );
280
-
281
- mutex_unlock (& entry -> mutex );
282
-
283
- return 0 ;
284
- }
285
-
286
- int juice_mux_listen (const char * bind_address , int local_port , juice_cb_mux_incoming_t cb , void * user_ptr )
287
- {
288
- if (!cb )
289
- return juice_mux_stop_listen (bind_address , local_port );
272
+ if (!entry -> get_registry_func ) {
273
+ JLOG_DEBUG ("juice_mux_listen get_registry_func is not implemented" );
274
+ return -1 ;
275
+ }
290
276
291
- conn_mode_entry_t * entry = & mode_entries [ JUICE_CONCURRENCY_MODE_MUX ] ;
277
+ mutex_lock ( & entry -> mutex ) ;
292
278
293
279
udp_socket_config_t config ;
294
280
config .bind_address = bind_address ;
295
281
config .port_begin = config .port_end = local_port ;
296
282
297
- mutex_lock ( & entry -> mutex ) ;
283
+ conn_registry_t * registry ;
298
284
299
- if (entry -> registry ) {
285
+ // locks the registry, creating it first if required
286
+ if (acquire_registry (entry , & config , & registry )) {
287
+ JLOG_DEBUG ("juice_mux_listen acquiring registry failed" );
300
288
mutex_unlock (& entry -> mutex );
301
- JLOG_DEBUG ("juice_mux_listen needs to be called before establishing any mux connection." );
302
289
return -1 ;
303
290
}
304
291
305
- if (acquire_registry (entry , & config )) { // locks the registry if created
292
+ if (!registry ) {
293
+ JLOG_DEBUG ("juice_mux_listen registry not found after creating it" );
306
294
mutex_unlock (& entry -> mutex );
307
295
return -1 ;
308
296
}
309
297
310
- conn_registry_t * registry = entry -> registry ;
311
- if (!registry ) {
298
+ if (entry -> mux_listen_func (registry , cb , user_ptr )) {
299
+ JLOG_DEBUG ("juice_mux_listen failed to call mux_listen_func for %s:%d" , bind_address , local_port );
300
+ release_registry (entry , registry );
312
301
mutex_unlock (& entry -> mutex );
313
302
return -1 ;
314
303
}
315
304
316
- registry -> cb_mux_incoming = cb ;
317
- registry -> mux_incoming_user_ptr = user_ptr ;
318
-
319
- mutex_unlock (& registry -> mutex );
305
+ release_registry (entry , registry );
320
306
mutex_unlock (& entry -> mutex );
321
307
return 0 ;
322
308
}
0 commit comments