Changeset 1395


Ignore:
Timestamp:
Jun 27, 2007 12:52:35 PM (12 years ago)
Author:
bennylp
Message:

Ticket #346: deadlock in event subscription when SUBSCRIBE is followed immediately with UN-SUBSCRIBE

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/src/pjsip-simple/evsub.c

    r1241 r1395  
    12101210} 
    12111211 
     1212 
     1213/* Callback to be called to terminate transaction. */ 
     1214static void terminate_timer_cb(pj_timer_heap_t *timer_heap, 
     1215                               struct pj_timer_entry *entry) 
     1216{ 
     1217    pj_str_t *key; 
     1218    pjsip_transaction *tsx; 
     1219 
     1220    PJ_UNUSED_ARG(timer_heap); 
     1221 
     1222    key = (pj_str_t*)entry->user_data; 
     1223    tsx = pjsip_tsx_layer_find_tsx(key, PJ_FALSE); 
     1224    /* Chance of race condition here */ 
     1225    if (tsx) { 
     1226        pjsip_tsx_terminate(tsx, PJSIP_SC_REQUEST_UPDATED); 
     1227    } 
     1228} 
    12121229 
    12131230 
     
    13761393            sub->pending_sub->state < PJSIP_TSX_STATE_COMPLETED)  
    13771394        { 
     1395            pj_timer_entry *timer; 
     1396            pj_str_t *key; 
     1397            pj_time_val timeout = {0, 0}; 
     1398 
    13781399            PJ_LOG(4,(sub->obj_name,  
    13791400                      "Cancelling pending subscription request")); 
     
    13831404             * will ignore the transaction. 
    13841405             */ 
    1385             pjsip_tsx_terminate(sub->pending_sub, PJSIP_SC_REQUEST_UPDATED); 
     1406            /* This unfortunately may cause deadlock, because at the moment 
     1407             * we are holding dialog's mutex. If a response to this 
     1408             * transaction is in progress in another thread, that thread 
     1409             * will deadlock when trying to acquire dialog mutex, because 
     1410             * it is holding the transaction mutex. 
     1411             * 
     1412             * So the solution is to register timer to kill this transaction. 
     1413             */ 
     1414            //pjsip_tsx_terminate(sub->pending_sub, PJSIP_SC_REQUEST_UPDATED); 
     1415            timer = PJ_POOL_ZALLOC_T(dlg->pool, pj_timer_entry); 
     1416            key = PJ_POOL_ALLOC_T(dlg->pool, pj_str_t); 
     1417            pj_strdup(dlg->pool, key, &sub->pending_sub->transaction_key); 
     1418            timer->cb = &terminate_timer_cb; 
     1419            timer->user_data = key; 
     1420 
     1421            pjsip_endpt_schedule_timer(dlg->endpt, timer, &timeout); 
    13861422        } 
    13871423 
     
    15001536 
    15011537        /* Clear pending subscription */ 
    1502         if (tsx == sub->pending_sub) 
     1538        if (tsx == sub->pending_sub) { 
    15031539            sub->pending_sub = NULL; 
     1540        } else if (sub->pending_sub != NULL) { 
     1541            /* This SUBSCRIBE transaction has been "renewed" with another 
     1542             * SUBSCRIBE, so we can just ignore this. For example, user 
     1543             * sent SUBSCRIBE followed immediately with UN-SUBSCRIBE. 
     1544             */ 
     1545            return; 
     1546        } 
    15041547 
    15051548        /* Handle authentication. */ 
Note: See TracChangeset for help on using the changeset viewer.