Changeset 4446


Ignore:
Timestamp:
Mar 21, 2013 6:07:28 AM (6 years ago)
Author:
bennylp
Message:

Part 2, fixed #1646: crash in transaction when it is destroyed while transport operation is in progress

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/src/pjsip/sip_transaction.c

    r4444 r4446  
    10901090            prev_state = tsx->state; 
    10911091 
     1092            /* Release transport as it's no longer working. */ 
     1093            tsx_update_transport(tsx, NULL); 
     1094 
    10921095            if (tsx->status_code < 200) { 
    10931096                pj_str_t err; 
     
    19161919                               pj_ssize_t sent) 
    19171920{ 
     1921    pjsip_transaction *tsx = (pjsip_transaction*) token; 
     1922 
    19181923    if (sent < 0) { 
    1919         pjsip_transaction *tsx = (pjsip_transaction*) token; 
     1924        pj_time_val delay = {0, 0}; 
    19201925        char errmsg[PJ_ERR_MSG_SIZE]; 
    19211926        pj_str_t err; 
    19221927 
    1923         tsx->transport_err = -sent; 
    1924  
    19251928        err = pj_strerror(-sent, errmsg, sizeof(errmsg)); 
    19261929 
     
    19281931                pjsip_tx_data_get_info(tdata), -sent, errmsg)); 
    19291932 
    1930         pj_grp_lock_acquire(tsx->grp_lock); 
    1931  
    1932         /* Release transport. */ 
    1933         tsx_update_transport(tsx, NULL); 
    1934  
    1935         /* Terminate transaction. */ 
    1936         tsx_set_status_code(tsx, PJSIP_SC_TSX_TRANSPORT_ERROR, &err); 
    1937         tsx_set_state( tsx, PJSIP_TSX_STATE_TERMINATED,  
    1938                        PJSIP_EVENT_TRANSPORT_ERROR, tdata ); 
    1939  
    1940         pj_grp_lock_release(tsx->grp_lock); 
     1933        /* Post the event for later processing, to avoid deadlock. 
     1934         * See https://trac.pjsip.org/repos/ticket/1646 
     1935         */ 
     1936        lock_timer(tsx); 
     1937        tsx->transport_err = -sent; 
     1938        tsx_cancel_timer(tsx, &tsx->timeout_timer); 
     1939        tsx_schedule_timer(tsx, &tsx->timeout_timer, &delay, 
     1940                           TRANSPORT_ERR_TIMER); 
     1941        unlock_timer(tsx); 
    19411942   } 
     1943 
     1944    /* Decrease pending send counter */ 
     1945    pj_grp_lock_dec_ref(tsx->grp_lock); 
    19421946} 
    19431947 
     
    19931997     */ 
    19941998    if (tsx->transport) { 
     1999        /* Increment group lock while waiting for send operation to complete, 
     2000         * to prevent us from being destroyed prematurely. See 
     2001         * https://trac.pjsip.org/repos/ticket/1646 
     2002         */ 
     2003        pj_grp_lock_add_ref(tsx->grp_lock); 
     2004 
    19952005        status = pjsip_transport_send( tsx->transport, tdata, &tsx->addr, 
    19962006                                       tsx->addr_len, tsx,  
     
    19982008        if (status == PJ_EPENDING) 
    19992009            status = PJ_SUCCESS; 
     2010        else { 
     2011            /* Operation completes immediately */ 
     2012            pj_grp_lock_dec_ref(tsx->grp_lock); 
     2013        } 
    20002014 
    20012015        if (status != PJ_SUCCESS) { 
Note: See TracChangeset for help on using the changeset viewer.