Changeset 1879 for pjproject/trunk/pjnath/src/pjnath/turn_udp.c
- Timestamp:
- Mar 20, 2008 4:32:06 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjnath/src/pjnath/turn_udp.c
r1869 r1879 20 20 #include <pj/assert.h> 21 21 #include <pj/errno.h> 22 #include <pj/lock.h> 22 23 #include <pj/log.h> 23 24 #include <pj/pool.h> 24 25 #include <pj/ioqueue.h> 26 27 enum 28 { 29 TIMER_NONE, 30 TIMER_DESTROY 31 }; 25 32 26 33 struct pj_turn_udp … … 30 37 pj_turn_udp_cb cb; 31 38 void *user_data; 39 40 pj_lock_t *lock; 41 42 pj_bool_t destroy_request; 43 pj_timer_heap_t *timer_heap; 44 pj_timer_entry timer; 32 45 33 46 pj_sock_t sock; … … 65 78 66 79 80 static void destroy(pj_turn_udp *udp_rel); 81 static void timer_cb(pj_timer_heap_t *th, pj_timer_entry *e); 82 83 67 84 /* 68 85 * Create. … … 92 109 if (cb) { 93 110 pj_memcpy(&udp_rel->cb, cb, sizeof(*cb)); 111 } 112 113 /* Create lock */ 114 status = pj_lock_create_recursive_mutex(pool, pool->obj_name, 115 &udp_rel->lock); 116 if (status != PJ_SUCCESS) { 117 destroy(udp_rel); 118 return status; 119 } 120 121 /* Init timer */ 122 udp_rel->timer_heap = cfg->timer_heap; 123 pj_timer_entry_init(&udp_rel->timer, TIMER_NONE, udp_rel, &timer_cb); 124 125 /* Init socket */ 126 status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &udp_rel->sock); 127 if (status != PJ_SUCCESS) { 128 destroy(udp_rel); 129 return status; 130 } 131 132 /* Bind to any */ 133 pj_sockaddr_init(af, &udp_rel->src_addr, NULL, 0); 134 status = pj_sock_bind(udp_rel->sock, &udp_rel->src_addr, 135 pj_sockaddr_get_len(&udp_rel->src_addr)); 136 if (status != PJ_SUCCESS) { 137 destroy(udp_rel); 138 return status; 139 } 140 141 /* Register to ioqeuue */ 142 pj_bzero(&ioq_cb, sizeof(ioq_cb)); 143 ioq_cb.on_read_complete = &on_read_complete; 144 status = pj_ioqueue_register_sock(udp_rel->pool, cfg->ioqueue, 145 udp_rel->sock, udp_rel, 146 &ioq_cb, &udp_rel->key); 147 if (status != PJ_SUCCESS) { 148 destroy(udp_rel); 149 return status; 94 150 } 95 151 … … 103 159 &sess_cb, udp_rel, 0, &udp_rel->sess); 104 160 if (status != PJ_SUCCESS) { 105 pj_turn_udp_destroy(udp_rel); 106 return status; 107 } 108 109 /* Init socket */ 110 status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &udp_rel->sock); 111 if (status != PJ_SUCCESS) { 112 pj_turn_udp_destroy(udp_rel); 113 return status; 114 } 115 116 /* Bind to any */ 117 pj_sockaddr_init(af, &udp_rel->src_addr, NULL, 0); 118 status = pj_sock_bind(udp_rel->sock, &udp_rel->src_addr, 119 pj_sockaddr_get_len(&udp_rel->src_addr)); 120 if (status != PJ_SUCCESS) { 121 pj_turn_udp_destroy(udp_rel); 122 return status; 123 } 124 125 /* Register to ioqeuue */ 126 pj_bzero(&ioq_cb, sizeof(ioq_cb)); 127 ioq_cb.on_read_complete = &on_read_complete; 128 status = pj_ioqueue_register_sock(udp_rel->pool, cfg->ioqueue, 129 udp_rel->sock, udp_rel, 130 &ioq_cb, &udp_rel->key); 131 if (status != PJ_SUCCESS) { 132 pj_turn_udp_destroy(udp_rel); 161 destroy(udp_rel); 133 162 return status; 134 163 } … … 145 174 * Destroy. 146 175 */ 147 PJ_DEF(void) pj_turn_udp_destroy(pj_turn_udp *udp_rel) 148 { 176 static void destroy(pj_turn_udp *udp_rel) 177 { 178 if (udp_rel->lock) { 179 pj_lock_acquire(udp_rel->lock); 180 } 181 149 182 if (udp_rel->sess) { 183 pj_turn_session_set_user_data(udp_rel->sess, NULL); 150 184 pj_turn_session_destroy(udp_rel->sess); 151 185 udp_rel->sess = NULL; 186 } 187 188 if (udp_rel->key) { 189 pj_ioqueue_unregister(udp_rel->key); 190 udp_rel->key = NULL; 191 udp_rel->sock = 0; 192 } else if (udp_rel->sock) { 193 pj_sock_close(udp_rel->sock); 194 udp_rel->sock = 0; 195 } 196 197 if (udp_rel->lock) { 198 pj_lock_release(udp_rel->lock); 199 pj_lock_destroy(udp_rel->lock); 200 udp_rel->lock = NULL; 152 201 } 153 202 … … 158 207 } 159 208 } 209 210 PJ_DEF(void) pj_turn_udp_destroy(pj_turn_udp *udp_rel) 211 { 212 pj_lock_acquire(udp_rel->lock); 213 udp_rel->destroy_request = PJ_TRUE; 214 215 if (udp_rel->sess) { 216 pj_turn_session_destroy(udp_rel->sess); 217 /* This will ultimately call our state callback, and when 218 * session state is DESTROYING we will schedule a timer to 219 * destroy ourselves. 220 */ 221 pj_lock_release(udp_rel->lock); 222 } else { 223 pj_lock_release(udp_rel->lock); 224 destroy(udp_rel); 225 } 226 227 } 228 229 /* Timer callback */ 230 static void timer_cb(pj_timer_heap_t *th, pj_timer_entry *e) 231 { 232 pj_turn_udp *udp_rel = (pj_turn_udp*)e->user_data; 233 int eid = e->id; 234 235 PJ_UNUSED_ARG(th); 236 237 e->id = TIMER_NONE; 238 239 switch (eid) { 240 case TIMER_DESTROY: 241 destroy(udp_rel); 242 break; 243 default: 244 pj_assert(!"Invalid timer id"); 245 break; 246 } 247 } 248 160 249 161 250 /* … … 272 361 273 362 udp_rel = (pj_turn_udp*) pj_ioqueue_get_user_data(key); 363 pj_lock_acquire(udp_rel->lock); 274 364 275 365 do { … … 301 391 ++retry < MAX_RETRY); 302 392 393 pj_lock_release(udp_rel->lock); 303 394 } 304 395 … … 317 408 pj_ssize_t len = pkt_len; 318 409 410 if (udp_rel == NULL) { 411 /* We've been destroyed */ 412 pj_assert(!"We should shutdown gracefully"); 413 return PJ_EINVALIDOP; 414 } 415 319 416 return pj_sock_sendto(udp_rel->sock, pkt, &len, 0, 320 417 dst_addr, dst_addr_len); … … 348 445 pj_turn_udp *udp_rel = (pj_turn_udp*) 349 446 pj_turn_session_get_user_data(sess); 447 if (udp_rel == NULL) { 448 /* We've been destroyed */ 449 return; 450 } 451 350 452 if (udp_rel->cb.on_rx_data) { 351 453 (*udp_rel->cb.on_rx_data)(udp_rel, pkt, pkt_len, … … 364 466 pj_turn_udp *udp_rel = (pj_turn_udp*) 365 467 pj_turn_session_get_user_data(sess); 468 if (udp_rel == NULL) { 469 /* We've been destroyed */ 470 return; 471 } 472 366 473 if (udp_rel->cb.on_state) { 367 474 (*udp_rel->cb.on_state)(udp_rel, old_state, new_state); 368 475 } 369 476 370 if (new_state > PJ_TURN_STATE_READY) { 371 udp_rel->sess = NULL; 372 } 373 } 374 375 477 if (new_state >= PJ_TURN_STATE_DESTROYING && udp_rel->sess) { 478 if (udp_rel->destroy_request) { 479 pj_time_val delay = {0, 0}; 480 481 pj_turn_session_set_user_data(udp_rel->sess, NULL); 482 483 udp_rel->timer.id = TIMER_DESTROY; 484 pj_timer_heap_schedule(udp_rel->timer_heap, &udp_rel->timer, 485 &delay); 486 } else { 487 udp_rel->sess = NULL; 488 } 489 } 490 } 491 492
Note: See TracChangeset
for help on using the changeset viewer.