Changeset 2826 for pjproject/trunk


Ignore:
Timestamp:
Jul 2, 2009 8:24:22 AM (15 years ago)
Author:
bennylp
Message:

Ticket #913: Concurrency problem in select ioqueue may corrupt descriptor set

  • fixed the concurrency problem
  • also fixed ioqueue unregister test in pjlib-test
Location:
pjproject/trunk/pjlib/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjlib/src/pj/ioqueue_common_abs.c

    r2394 r2826  
    688688 
    689689    pj_mutex_lock(key->mutex); 
     690    /* Check again. Handle may have been closed after the previous check 
     691     * in multithreaded app. If we add bad handle to the set it will 
     692     * corrupt the ioqueue set. See #913 
     693     */ 
     694    if (IS_CLOSING(key)) { 
     695        pj_mutex_unlock(key->mutex); 
     696        return PJ_ECANCELLED; 
     697    } 
    690698    pj_list_insert_before(&key->read_list, read_op); 
    691699    ioqueue_add_to_set(key->ioqueue, key, READABLE_EVENT); 
     
    756764 
    757765    pj_mutex_lock(key->mutex); 
     766    /* Check again. Handle may have been closed after the previous check 
     767     * in multithreaded app. If we add bad handle to the set it will 
     768     * corrupt the ioqueue set. See #913 
     769     */ 
     770    if (IS_CLOSING(key)) { 
     771        pj_mutex_unlock(key->mutex); 
     772        return PJ_ECANCELLED; 
     773    } 
    758774    pj_list_insert_before(&key->read_list, read_op); 
    759775    ioqueue_add_to_set(key->ioqueue, key, READABLE_EVENT); 
     
    862878     
    863879    pj_mutex_lock(key->mutex); 
     880    /* Check again. Handle may have been closed after the previous check 
     881     * in multithreaded app. If we add bad handle to the set it will 
     882     * corrupt the ioqueue set. See #913 
     883     */ 
     884    if (IS_CLOSING(key)) { 
     885        pj_mutex_unlock(key->mutex); 
     886        return PJ_ECANCELLED; 
     887    } 
    864888    pj_list_insert_before(&key->write_list, write_op); 
    865889    ioqueue_add_to_set(key->ioqueue, key, WRITEABLE_EVENT); 
     
    9791003     
    9801004    pj_mutex_lock(key->mutex); 
     1005    /* Check again. Handle may have been closed after the previous check 
     1006     * in multithreaded app. If we add bad handle to the set it will 
     1007     * corrupt the ioqueue set. See #913 
     1008     */ 
     1009    if (IS_CLOSING(key)) { 
     1010        pj_mutex_unlock(key->mutex); 
     1011        return PJ_ECANCELLED; 
     1012    } 
    9811013    pj_list_insert_before(&key->write_list, write_op); 
    9821014    ioqueue_add_to_set(key->ioqueue, key, WRITEABLE_EVENT); 
     
    10481080 
    10491081    pj_mutex_lock(key->mutex); 
     1082    /* Check again. Handle may have been closed after the previous check 
     1083     * in multithreaded app. If we add bad handle to the set it will 
     1084     * corrupt the ioqueue set. See #913 
     1085     */ 
     1086    if (IS_CLOSING(key)) { 
     1087        pj_mutex_unlock(key->mutex); 
     1088        return PJ_ECANCELLED; 
     1089    } 
    10501090    pj_list_insert_before(&key->accept_list, accept_op); 
    10511091    ioqueue_add_to_set(key->ioqueue, key, READABLE_EVENT); 
     
    10841124            /* Pending! */ 
    10851125            pj_mutex_lock(key->mutex); 
     1126            /* Check again. Handle may have been closed after the previous  
     1127             * check in multithreaded app. See #913 
     1128             */ 
     1129            if (IS_CLOSING(key)) { 
     1130                pj_mutex_unlock(key->mutex); 
     1131                return PJ_ECANCELLED; 
     1132            } 
    10861133            key->connecting = PJ_TRUE; 
    10871134            ioqueue_add_to_set(key->ioqueue, key, WRITEABLE_EVENT); 
  • pjproject/trunk/pjlib/src/pjlib-test/ioq_unreg.c

    r2782 r2826  
    9494            sock_data.unregistered = 1; 
    9595            pj_ioqueue_unregister(key); 
    96             pj_mutex_destroy(sock_data.mutex); 
    97             pj_pool_release(sock_data.pool); 
    98             sock_data.pool = NULL; 
    9996            return; 
    10097        } 
     
    244241    for (;;) { 
    245242        pj_time_val now, timeout; 
     243        int n; 
    246244 
    247245        pj_gettimeofday(&now); 
     
    249247        if (test_method == UNREGISTER_IN_APP &&  
    250248            PJ_TIME_VAL_GTE(now, time_to_unregister) && 
    251             sock_data.pool)  
     249            !sock_data.unregistered)  
    252250        { 
    253             //Can't do this otherwise it'll deadlock 
    254             //pj_mutex_lock(sock_data.mutex); 
    255  
    256251            sock_data.unregistered = 1; 
     252            /* Wait (as much as possible) for callback to complete */ 
     253            pj_mutex_lock(sock_data.mutex); 
     254            pj_mutex_unlock(sock_data.mutex); 
    257255            pj_ioqueue_unregister(sock_data.key); 
    258             //pj_mutex_unlock(sock_data.mutex); 
    259             pj_mutex_destroy(sock_data.mutex); 
    260             pj_pool_release(sock_data.pool); 
    261             sock_data.pool = NULL; 
    262256        } 
    263257 
     
    266260 
    267261        timeout.sec = 0; timeout.msec = 10; 
    268         pj_ioqueue_poll(ioqueue, &timeout); 
    269         //pj_thread_sleep(1); 
    270  
     262        n = pj_ioqueue_poll(ioqueue, &timeout); 
     263        if (n < 0) { 
     264            app_perror("pj_ioqueue_poll error", -n); 
     265            pj_thread_sleep(1); 
     266        } 
    271267    } 
    272268 
     
    277273        pj_thread_destroy(thread[i]); 
    278274    } 
     275 
     276    /* Destroy data */ 
     277    pj_mutex_destroy(sock_data.mutex); 
     278    pj_pool_release(sock_data.pool); 
     279    sock_data.pool = NULL; 
    279280 
    280281    if (other_socket) { 
     
    315316    } 
    316317 
    317     PJ_LOG(3, (THIS_FILE, "...ioqueue unregister stress test 0/3 (%s)",  
     318    PJ_LOG(3, (THIS_FILE, "...ioqueue unregister stress test 0/3, unregister in app (%s)",  
    318319               pj_ioqueue_name())); 
    319320    for (i=0; i<LOOP; ++i) { 
     
    325326 
    326327 
    327     PJ_LOG(3, (THIS_FILE, "...ioqueue unregister stress test 1/3 (%s)", 
     328    PJ_LOG(3, (THIS_FILE, "...ioqueue unregister stress test 1/3, unregister in app (%s)", 
    328329               pj_ioqueue_name())); 
    329330    for (i=0; i<LOOP; ++i) { 
     
    336337    test_method = UNREGISTER_IN_CALLBACK; 
    337338 
    338     PJ_LOG(3, (THIS_FILE, "...ioqueue unregister stress test 2/3 (%s)",  
     339    PJ_LOG(3, (THIS_FILE, "...ioqueue unregister stress test 2/3, unregister in cb (%s)",  
    339340               pj_ioqueue_name())); 
    340341    for (i=0; i<LOOP; ++i) { 
     
    346347 
    347348 
    348     PJ_LOG(3, (THIS_FILE, "...ioqueue unregister stress test 3/3 (%s)",  
     349    PJ_LOG(3, (THIS_FILE, "...ioqueue unregister stress test 3/3, unregister in cb (%s)",  
    349350               pj_ioqueue_name())); 
    350351    for (i=0; i<LOOP; ++i) { 
     
    367368    rc = udp_ioqueue_unreg_test_imp(PJ_TRUE); 
    368369    if (rc != 0) 
    369         return rc; 
     370        return rc; 
    370371 
    371372    rc = udp_ioqueue_unreg_test_imp(PJ_FALSE); 
Note: See TracChangeset for help on using the changeset viewer.