/* Destroy */ PJ_DEF(pj_status_t) pj_stun_sock_destroy(pj_stun_sock *stun_sock) { TRACE_((stun_sock->obj_name, "STUN sock %p request, ref_cnt=%d", stun_sock, pj_grp_lock_get_ref(stun_sock->grp_lock))); pj_grp_lock_acquire(stun_sock->grp_lock); if (stun_sock->is_destroying) { /* Destroy already called */ pj_grp_lock_release(stun_sock->grp_lock); return PJ_EINVALIDOP; } stun_sock->is_destroying = PJ_TRUE; pj_timer_heap_cancel_if_active(stun_sock->stun_cfg.timer_heap, &stun_sock->ka_timer, 0); if (stun_sock->active_sock != NULL) { stun_sock->sock_fd = PJ_INVALID_SOCKET; pj_activesock_close(stun_sock->active_sock); } else if (stun_sock->sock_fd != PJ_INVALID_SOCKET) { pj_sock_close(stun_sock->sock_fd); stun_sock->sock_fd = PJ_INVALID_SOCKET; } if (stun_sock->stun_sess) { pj_stun_session_destroy(stun_sock->stun_sess); } pj_grp_lock_dec_ref(stun_sock->grp_lock); pj_grp_lock_release(stun_sock->grp_lock); return PJ_SUCCESS; }
PJ_DEF(void) pj_grp_lock_t::pj_grp_lock_dump() { #if PJ_GRP_LOCK_DEBUG grp_lock_ref *ref = grp_lock->ref_list.next; char info_buf[1000]; pj_str_t info; info.ptr = info_buf; info.slen = 0; pj_grp_lock_acquire(grp_lock); pj_enter_critical_section(); while (ref != &grp_lock->ref_list && info.slen < sizeof(info_buf)) { char *start = info.ptr + info.slen; int max_len = sizeof(info_buf) - info.slen; int len; len = pj_ansi_snprintf(start, max_len, "%s:%d ", ref->file, ref->line); if (len < 1 || len >= max_len) { len = strlen(ref->file); if (len > max_len - 1) len = max_len - 1; memcpy(start, ref->file, len); start[len++] = ' '; } info.slen += len; ref = ref->next; } if (ref != &grp_lock->ref_list) { int i; for (i=0; i<4; ++i) info_buf[sizeof(info_buf)-i-1] = '.'; } info.ptr[info.slen-1] = '\0'; pj_leave_critical_section(); pj_grp_lock_release(grp_lock); PJ_LOG(4,(THIS_FILE, "Group lock %p, ref_cnt=%d. Reference holders: %s", grp_lock, pj_grp_lock_get_ref(grp_lock), info.ptr)); #endif }
/* * Destroy transaction immediately. */ PJ_DEF(pj_status_t) pj_stun_client_tsx_stop(pj_stun_client_tsx *tsx) { PJ_ASSERT_RETURN(tsx, PJ_EINVAL); /* Don't call grp_lock_acquire() because we might be called on * group lock's destructor. */ pj_timer_heap_cancel_if_active(tsx->timer_heap, &tsx->retransmit_timer, TIMER_INACTIVE); pj_timer_heap_cancel_if_active(tsx->timer_heap, &tsx->destroy_timer, TIMER_INACTIVE); PJ_LOG(5,(tsx->obj_name, "STUN client transaction %p stopped, ref_cnt=%d", tsx, pj_grp_lock_get_ref(tsx->grp_lock))); return PJ_SUCCESS; }
static void destroy(pj_turn_sock *turn_sock) { PJ_LOG(4,(turn_sock->obj_name, "TURN socket destroy request, ref_cnt=%d", pj_grp_lock_get_ref(turn_sock->grp_lock))); pj_grp_lock_acquire(turn_sock->grp_lock); if (turn_sock->is_destroying) { pj_grp_lock_release(turn_sock->grp_lock); return; } turn_sock->is_destroying = PJ_TRUE; if (turn_sock->sess) pj_turn_session_shutdown(turn_sock->sess); if (turn_sock->active_sock) pj_activesock_close(turn_sock->active_sock); pj_grp_lock_dec_ref(turn_sock->grp_lock); pj_grp_lock_release(turn_sock->grp_lock); }
PJ_DEF(pj_status_t) pj_stun_session_destroy(pj_stun_session *sess) { pj_stun_tx_data *tdata; PJ_ASSERT_RETURN(sess, PJ_EINVAL); TRACE_((SNAME(sess), "STUN session %p destroy request, ref_cnt=%d", sess, pj_grp_lock_get_ref(sess->grp_lock))); pj_grp_lock_acquire(sess->grp_lock); if (sess->is_destroying) { /* Prevent from decrementing the ref counter more than once */ pj_grp_lock_release(sess->grp_lock); return PJ_EINVALIDOP; } sess->is_destroying = PJ_TRUE; /* We need to stop transactions and cached response because they are * holding the group lock's reference counter while retransmitting. */ tdata = sess->pending_request_list.next; while (tdata != &sess->pending_request_list) { if (tdata->client_tsx) pj_stun_client_tsx_stop(tdata->client_tsx); tdata = tdata->next; } tdata = sess->cached_response_list.next; while (tdata != &sess->cached_response_list) { pj_timer_heap_cancel_if_active(tdata->sess->cfg->timer_heap, &tdata->res_timer, PJ_FALSE); tdata = tdata->next; } pj_grp_lock_dec_ref(sess->grp_lock); pj_grp_lock_release(sess->grp_lock); return PJ_SUCCESS; }