Changeset 5519


Ignore:
Timestamp:
Jan 11, 2017 3:35:17 AM (2 years ago)
Author:
nanang
Message:

Fixed #1988: Wait for any active spinning loop in read callback to complete before reinitiating read operation in UDP restart.

File:
1 edited

Legend:

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

    r5311 r5519  
    7777    int                 is_closing; 
    7878    pj_bool_t           is_paused; 
     79    int                 read_loop_spin; 
    7980 
    8081    /* Group lock to be used by UDP transport and ioqueue key */ 
     
    130131    pj_status_t status; 
    131132 
     133    ++tp->read_loop_spin; 
     134 
    132135    /* Don't do anything if transport is closing. */ 
    133136    if (tp->is_closing) { 
    134137        tp->is_closing++; 
    135         return; 
     138        goto on_return; 
    136139    } 
    137140 
    138141    /* Don't do anything if transport is being paused. */ 
    139142    if (tp->is_paused) 
    140         return; 
     143        goto on_return; 
    141144 
    142145    /* 
     
    228231         */ 
    229232        if (tp->is_paused) 
    230             return; 
     233            break; 
    231234 
    232235        /* Read next packet. */ 
     
    244247 
    245248        } else if (status == PJ_EPENDING) { 
     249            break; 
     250 
     251        } else if (status == PJ_ECANCELLED) { 
     252            /* Socket is closing, quit loop */ 
    246253            break; 
    247254 
     
    277284        } 
    278285    } 
     286 
     287on_return: 
     288    --tp->read_loop_spin; 
    279289} 
    280290 
     
    624634        return PJ_SUCCESS; 
    625635 
    626     /* Create group lock */ 
    627     status = pj_grp_lock_create(tp->base.pool, NULL, &tp->grp_lock); 
    628     if (status != PJ_SUCCESS) 
    629         return status; 
    630  
    631     pj_grp_lock_add_ref(tp->grp_lock); 
    632     pj_grp_lock_add_handler(tp->grp_lock, tp->base.pool, tp, &udp_on_destroy); 
     636    /* Create group lock if not yet (don't need to do so on UDP restart) */ 
     637    if (!tp->grp_lock) { 
     638        status = pj_grp_lock_create(tp->base.pool, NULL, &tp->grp_lock); 
     639        if (status != PJ_SUCCESS) 
     640            return status; 
     641 
     642        pj_grp_lock_add_ref(tp->grp_lock); 
     643        pj_grp_lock_add_handler(tp->grp_lock, tp->base.pool, tp, 
     644                                &udp_on_destroy); 
     645    } 
    633646     
    634647    /* Register to ioqueue. */ 
     
    10761089    tp = (struct udp_transport*) transport; 
    10771090 
     1091    /* Pause the transport first, so that any active read loop spin will 
     1092     * quit as soon as possible. 
     1093     */ 
     1094    tp->is_paused = PJ_TRUE; 
     1095 
    10781096    if (option & PJSIP_UDP_TRANSPORT_DESTROY_SOCKET) { 
    10791097        char addr_buf[PJ_INET6_ADDRSTRLEN]; 
     
    11391157    } 
    11401158 
     1159    /* Make sure all udp_on_read_complete() loop spin are stopped */ 
     1160    do { 
     1161        pj_thread_sleep(1); 
     1162    } while (tp->read_loop_spin); 
     1163 
    11411164    /* Re-register new or existing socket to ioqueue. */ 
    11421165    status = register_to_ioqueue(tp); 
Note: See TracChangeset for help on using the changeset viewer.