Ignore:
Timestamp:
Oct 12, 2009 7:44:14 AM (15 years ago)
Author:
bennylp
Message:

Ticket #411: Cannot update account presence's status while previous PUBLISH is in progress (thanks Olivier Beytrison for the report)

  • enable request queueing. If PUBLISH is to be sent while another one is still in progress, queue the request and send it later when the ongoing request completes
  • this behavior is controlled by new pjsip_publishc_opt structure to control session's options
  • default behavior is to queue the request
File:
1 edited

Legend:

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

    r2939 r2940  
    5858 
    5959/** 
     60 * Pending request list. 
     61 */ 
     62typedef struct pending_publish 
     63{ 
     64    PJ_DECL_LIST_MEMBER(pjsip_tx_data); 
     65} pending_publish; 
     66 
     67 
     68/** 
    6069 * SIP client publication structure. 
    6170 */ 
     
    6675    pj_bool_t                    _delete_flag; 
    6776    int                          pending_tsx; 
    68  
     77    pj_mutex_t                  *mutex; 
     78 
     79    pjsip_publishc_opt           opt; 
    6980    void                        *token; 
    7081    pjsip_publishc_cb           *cb; 
     
    92103    pj_time_val                  next_refresh; 
    93104    pj_timer_entry               timer; 
     105 
     106    /* Pending PUBLISH request */ 
     107    pending_publish              pending_reqs; 
    94108}; 
    95109 
     110 
     111PJ_DEF(void) pjsip_publishc_opt_default(pjsip_publishc_opt *opt) 
     112{ 
     113    pj_bzero(opt, sizeof(*opt)); 
     114    opt->queue_request = PJSIP_PUBLISHC_QUEUE_REQUEST; 
     115} 
    96116 
    97117 
     
    128148 
    129149PJ_DEF(pj_status_t) pjsip_publishc_create( pjsip_endpoint *endpt,  
    130                                            unsigned options, 
     150                                           const pjsip_publishc_opt *opt, 
    131151                                           void *token, 
    132152                                           pjsip_publishc_cb *cb,        
     
    135155    pj_pool_t *pool; 
    136156    pjsip_publishc *pubc; 
     157    pjsip_publishc_opt default_opt; 
    137158    pj_status_t status; 
    138159 
    139160    /* Verify arguments. */ 
    140161    PJ_ASSERT_RETURN(endpt && cb && p_pubc, PJ_EINVAL); 
    141     PJ_ASSERT_RETURN(options == 0, PJ_EINVAL); 
    142  
    143     PJ_UNUSED_ARG(options); 
    144162 
    145163    pool = pjsip_endpt_create_pool(endpt, "pubc%p", 1024, 1024); 
     
    154172    pubc->expires = PJSIP_PUBC_EXPIRATION_NOT_SPECIFIED; 
    155173 
     174    if (!opt) { 
     175        pjsip_publishc_opt_default(&default_opt); 
     176        opt = &default_opt; 
     177    } 
     178    pj_memcpy(&pubc->opt, opt, sizeof(*opt)); 
     179    pj_list_init(&pubc->pending_reqs); 
     180 
     181    status = pj_mutex_create_recursive(pubc->pool, "pubc%p", &pubc->mutex); 
     182    if (status != PJ_SUCCESS) { 
     183        pj_pool_release(pool); 
     184        return status; 
     185    } 
     186 
    156187    status = pjsip_auth_clt_init(&pubc->auth_sess, endpt, pubc->pool, 0); 
    157     if (status != PJ_SUCCESS) 
     188    if (status != PJ_SUCCESS) { 
     189        pj_mutex_destroy(pubc->mutex); 
     190        pj_pool_release(pool); 
    158191        return status; 
     192    } 
    159193 
    160194    pj_list_init(&pubc->route_set); 
     
    181215        } 
    182216 
     217        if (pubc->mutex) 
     218            pj_mutex_destroy(pubc->mutex); 
    183219        pjsip_endpt_release_pool(pubc->endpt, pubc->pool); 
    184220    } 
     
    576612            if (pubc->auto_refresh && expiration!=0 && expiration!=0xFFFF) { 
    577613                pj_time_val delay = { 0, 0}; 
     614 
     615                /* Cancel existing timer, if any */ 
     616                if (pubc->timer.id != 0) { 
     617                    pjsip_endpt_cancel_timer(pubc->endpt, &pubc->timer); 
     618                    pubc->timer.id = 0; 
     619                } 
    578620 
    579621                delay.sec = expiration - DELAY_BEFORE_REFRESH; 
     
    614656 
    615657        --pubc->pending_tsx; 
     658 
     659        /* If we have pending request(s), send them now */ 
     660        pj_mutex_lock(pubc->mutex); 
     661        while (!pj_list_empty(&pubc->pending_reqs)) { 
     662            pjsip_tx_data *tdata = pubc->pending_reqs.next; 
     663            pj_list_erase(tdata); 
     664            status = pjsip_publishc_send(pubc, tdata); 
     665            if (status == PJ_EPENDING) { 
     666                pj_assert(!"Not expected"); 
     667                pj_list_erase(tdata); 
     668                pjsip_tx_data_dec_ref(tdata); 
     669            } else if (status == PJ_SUCCESS) { 
     670                break; 
     671            } 
     672        } 
     673        pj_mutex_unlock(pubc->mutex); 
    616674    } 
    617675 
     
    630688    pj_uint32_t cseq; 
    631689 
     690    PJ_ASSERT_RETURN(pubc && tdata, PJ_EINVAL); 
     691 
    632692    /* Make sure we don't have pending transaction. */ 
     693    pj_mutex_lock(pubc->mutex); 
    633694    if (pubc->pending_tsx) { 
    634         PJ_LOG(4,(THIS_FILE, "Unable to send request, pubc has another " 
    635                              "transaction pending")); 
    636         pjsip_tx_data_dec_ref( tdata ); 
    637         return PJSIP_EBUSY; 
    638     } 
     695        if (pubc->opt.queue_request) { 
     696            pj_list_push_back(&pubc->pending_reqs, tdata); 
     697            pj_mutex_unlock(pubc->mutex); 
     698            PJ_LOG(4,(THIS_FILE, "Request is queued, pubc has another " 
     699                                 "transaction pending")); 
     700            return PJ_EPENDING; 
     701        } else { 
     702            pjsip_tx_data_dec_ref(tdata); 
     703            pj_mutex_unlock(pubc->mutex); 
     704            PJ_LOG(4,(THIS_FILE, "Unable to send request, pubc has another " 
     705                                 "transaction pending")); 
     706            return PJ_EBUSY; 
     707        } 
     708    } 
     709    pj_mutex_unlock(pubc->mutex); 
    639710 
    640711    /* Invalidate message buffer. */ 
Note: See TracChangeset for help on using the changeset viewer.