Ignore:
Timestamp:
Feb 21, 2013 11:18:36 AM (11 years ago)
Author:
bennylp
Message:

Fixed #1616: Implementation of Group lock and other foundation in PJLIB for fixing synchronization issues

File:
1 edited

Legend:

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

    r4281 r4359  
    3636#include <pj/lock.h> 
    3737#include <pj/log.h> 
     38#include <pj/rand.h> 
    3839 
    3940#define THIS_FILE       "timer.c" 
     
    452453    entry->user_data = user_data; 
    453454    entry->cb = cb; 
     455    entry->_grp_lock = NULL; 
    454456 
    455457    return entry; 
    456458} 
     459 
     460#if PJ_TIMER_DEBUG 
     461static pj_status_t schedule_w_grp_lock_dbg(pj_timer_heap_t *ht, 
     462                                           pj_timer_entry *entry, 
     463                                           const pj_time_val *delay, 
     464                                           pj_bool_t set_id, 
     465                                           int id_val, 
     466                                           pj_grp_lock_t *grp_lock, 
     467                                           const char *src_file, 
     468                                           int src_line) 
     469#else 
     470static pj_status_t schedule_w_grp_lock(pj_timer_heap_t *ht, 
     471                                       pj_timer_entry *entry, 
     472                                       const pj_time_val *delay, 
     473                                       pj_bool_t set_id, 
     474                                       int id_val, 
     475                                       pj_grp_lock_t *grp_lock) 
     476#endif 
     477{ 
     478    pj_status_t status; 
     479    pj_time_val expires; 
     480 
     481    PJ_ASSERT_RETURN(ht && entry && delay, PJ_EINVAL); 
     482    PJ_ASSERT_RETURN(entry->cb != NULL, PJ_EINVAL); 
     483 
     484    /* Prevent same entry from being scheduled more than once */ 
     485    PJ_ASSERT_RETURN(entry->_timer_id < 1, PJ_EINVALIDOP); 
     486 
     487#if PJ_TIMER_DEBUG 
     488    entry->src_file = src_file; 
     489    entry->src_line = src_line; 
     490#endif 
     491    pj_gettickcount(&expires); 
     492    PJ_TIME_VAL_ADD(expires, *delay); 
     493     
     494    lock_timer_heap(ht); 
     495    status = schedule_entry(ht, entry, &expires); 
     496    if (status == PJ_SUCCESS) { 
     497        if (set_id) 
     498            entry->id = id_val; 
     499        entry->_grp_lock = grp_lock; 
     500        if (entry->_grp_lock) { 
     501            pj_grp_lock_add_ref(entry->_grp_lock); 
     502        } 
     503    } 
     504    unlock_timer_heap(ht); 
     505 
     506    return status; 
     507} 
     508 
    457509 
    458510#if PJ_TIMER_DEBUG 
     
    462514                                                const char *src_file, 
    463515                                                int src_line) 
     516{ 
     517    return schedule_w_grp_lock_dbg(ht, entry, delay, PJ_FALSE, 1, NULL, 
     518                                   src_file, src_line); 
     519} 
     520 
     521PJ_DEF(pj_status_t) pj_timer_heap_schedule_w_grp_lock_dbg( 
     522                                                pj_timer_heap_t *ht, 
     523                                                pj_timer_entry *entry, 
     524                                                const pj_time_val *delay, 
     525                                                int id_val, 
     526                                                pj_grp_lock_t *grp_lock, 
     527                                                const char *src_file, 
     528                                                int src_line) 
     529{ 
     530    return schedule_w_grp_lock_dbg(ht, entry, delay, PJ_TRUE, id_val, 
     531                                   grp_lock, src_file, src_line); 
     532} 
     533 
    464534#else 
    465535PJ_DEF(pj_status_t) pj_timer_heap_schedule( pj_timer_heap_t *ht, 
    466                                             pj_timer_entry *entry,  
    467                                             const pj_time_val *delay) 
     536                                            pj_timer_entry *entry, 
     537                                            const pj_time_val *delay) 
     538{ 
     539    return schedule_w_grp_lock(ht, entry, delay, PJ_FALSE, 1, NULL); 
     540} 
     541 
     542PJ_DEF(pj_status_t) pj_timer_heap_schedule_w_grp_lock(pj_timer_heap_t *ht, 
     543                                                      pj_timer_entry *entry, 
     544                                                      const pj_time_val *delay, 
     545                                                      int id_val, 
     546                                                      pj_grp_lock_t *grp_lock) 
     547{ 
     548    return schedule_w_grp_lock(ht, entry, delay, PJ_TRUE, id_val, grp_lock); 
     549} 
    468550#endif 
    469 { 
    470     pj_status_t status; 
    471     pj_time_val expires; 
    472  
    473     PJ_ASSERT_RETURN(ht && entry && delay, PJ_EINVAL); 
    474     PJ_ASSERT_RETURN(entry->cb != NULL, PJ_EINVAL); 
    475  
    476     /* Prevent same entry from being scheduled more than once */ 
    477     PJ_ASSERT_RETURN(entry->_timer_id < 1, PJ_EINVALIDOP); 
    478  
    479 #if PJ_TIMER_DEBUG 
    480     entry->src_file = src_file; 
    481     entry->src_line = src_line; 
    482 #endif 
    483     pj_gettickcount(&expires); 
    484     PJ_TIME_VAL_ADD(expires, *delay); 
    485      
     551 
     552static int cancel_timer(pj_timer_heap_t *ht, 
     553                        pj_timer_entry *entry, 
     554                        pj_bool_t set_id, 
     555                        int id_val) 
     556{ 
     557    int count; 
     558 
     559    PJ_ASSERT_RETURN(ht && entry, PJ_EINVAL); 
     560 
    486561    lock_timer_heap(ht); 
    487     status = schedule_entry(ht, entry, &expires); 
     562    count = cancel(ht, entry, 1); 
     563    if (set_id) { 
     564        entry->id = id_val; 
     565    } 
     566    if (entry->_grp_lock) { 
     567        pj_grp_lock_t *grp_lock = entry->_grp_lock; 
     568        entry->_grp_lock = NULL; 
     569        pj_grp_lock_dec_ref(grp_lock); 
     570    } 
    488571    unlock_timer_heap(ht); 
    489572 
    490     return status; 
     573    return count; 
    491574} 
    492575 
     
    494577                                  pj_timer_entry *entry) 
    495578{ 
    496     int count; 
    497  
    498     PJ_ASSERT_RETURN(ht && entry, PJ_EINVAL); 
    499  
    500     lock_timer_heap(ht); 
    501     count = cancel(ht, entry, 1); 
    502     unlock_timer_heap(ht); 
    503  
    504     return count; 
     579    return cancel_timer(ht, entry, PJ_FALSE, 0); 
     580} 
     581 
     582PJ_DEF(int) pj_timer_heap_cancel_if_active(pj_timer_heap_t *ht, 
     583                                           pj_timer_entry *entry, 
     584                                           int id_val) 
     585{ 
     586    return cancel_timer(ht, entry, PJ_TRUE, id_val); 
    505587} 
    506588 
     
    528610    { 
    529611        pj_timer_entry *node = remove_node(ht, 0); 
     612        pj_grp_lock_t *grp_lock; 
     613 
    530614        ++count; 
    531615 
     616        grp_lock = node->_grp_lock; 
     617        node->_grp_lock = NULL; 
     618 
    532619        unlock_timer_heap(ht); 
     620 
     621        PJ_RACE_ME(5); 
     622 
    533623        if (node->cb) 
    534624            (*node->cb)(ht, node); 
     625 
     626        if (grp_lock) 
     627            pj_grp_lock_dec_ref(grp_lock); 
     628 
    535629        lock_timer_heap(ht); 
    536630    } 
Note: See TracChangeset for help on using the changeset viewer.