Changeset 2869


Ignore:
Timestamp:
Aug 12, 2009 5:53:47 PM (10 years ago)
Author:
bennylp
Message:

Ticket #877: Memory consumption of the invite session grows indefinitely if call is running for long period of time and with many re-INVITES

  • introducing flip-flop pools in the pjsip_inv_session. There are two additional pools created, and one of them will be reset everytime SDP negotiation is done to release memory back to the OS
Location:
pjproject/trunk/pjsip
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/include/pjsip-ua/sip_inv.h

    r2858 r2869  
    319319/** 
    320320 * This structure describes the invite session. 
     321 * 
     322 * Note regarding the invite session's pools. The inv_sess used to have 
     323 * only one pool, which is just a pointer to the dialog's pool. Ticket 
     324 * http://trac.pjsip.org/repos/ticket/877 has found that the memory 
     325 * usage will grow considerably everytime re-INVITE or UPDATE is 
     326 * performed. 
     327 * 
     328 * Ticket #877 then created two more memory pools for the inv_sess, so 
     329 * now we have three memory pools: 
     330 *  - pool: to be used to allocate long term data for the session 
     331 *  - pool_prov and pool_active: this is a flip-flop pools to be used 
     332 *     interchangably during re-INVITE and UPDATE. pool_prov is 
     333 *     "provisional" pool, used to allocate SDP offer or answer for 
     334 *     the re-INVITE and UPDATE. Once SDP negotiation is done, the 
     335 *     provisional pool will be made as the active pool, then the 
     336 *     existing active pool will be reset, to release the memory 
     337 *     back to the OS. So these pool's lifetime is synchronized to 
     338 *     the SDP offer-answer negotiation. 
     339 * 
     340 * Higher level application such as PJSUA-LIB has been modified to 
     341 * make use of these flip-flop pools, i.e. by creating media objects 
     342 * from the provisional pool rather than from the long term pool. 
     343 * 
     344 * Other applications that want to use these pools must understand 
     345 * that the flip-flop pool's lifetimes are synchronized to the 
     346 * SDP offer-answer negotiation. 
    321347 */ 
    322348struct pjsip_inv_session 
    323349{ 
    324350    char                 obj_name[PJ_MAX_OBJ_NAME]; /**< Log identification */ 
    325     pj_pool_t           *pool;                      /**< Dialog's pool.     */ 
     351    pj_pool_t           *pool;                      /**< Long term pool.    */ 
     352    pj_pool_t           *pool_prov;                 /**< Provisional pool   */ 
     353    pj_pool_t           *pool_active;               /**< Active/current pool*/ 
    326354    pjsip_inv_state      state;                     /**< Invite sess state. */ 
    327355    pj_bool_t            cancelling;                /**< CANCEL requested   */ 
  • pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c

    r2861 r2869  
    7878}; 
    7979 
     80#define POOL_INIT_SIZE  256 
     81#define POOL_INC_SIZE   256 
     82 
    8083/* 
    8184 * Static prototypes. 
     
    235238        pjsip_timer_end_session(inv); 
    236239        pjsip_dlg_dec_session(inv->dlg, &mod_inv.mod); 
     240 
     241        /* Release the flip-flop pools */ 
     242        pj_pool_release(inv->pool_prov); 
     243        pj_pool_release(inv->pool_active); 
    237244    } 
    238245} 
     
    670677    inv->cause = (pjsip_status_code) 0; 
    671678 
     679    /* Create flip-flop pool (see ticket #877) */ 
     680    /* (using inv->obj_name as temporary variable for pool names */ 
     681    pj_ansi_snprintf(inv->obj_name, PJ_MAX_OBJ_NAME, "inv%p", dlg->pool); 
     682    inv->pool_prov = pjsip_endpt_create_pool(dlg->endpt, inv->obj_name, 
     683                                             POOL_INIT_SIZE, POOL_INC_SIZE); 
     684    inv->pool_active = pjsip_endpt_create_pool(dlg->endpt, inv->obj_name, 
     685                                               POOL_INIT_SIZE, POOL_INC_SIZE); 
     686 
    672687    /* Object name will use the same dialog pointer. */ 
    673688    pj_ansi_snprintf(inv->obj_name, PJ_MAX_OBJ_NAME, "inv%p", dlg); 
     
    675690    /* Create negotiator if local_sdp is specified. */ 
    676691    if (local_sdp) { 
    677         status = pjmedia_sdp_neg_create_w_local_offer(dlg->pool, local_sdp, 
    678                                                       &inv->neg); 
     692        status = pjmedia_sdp_neg_create_w_local_offer(inv->pool,  
     693                                                      local_sdp, &inv->neg); 
    679694        if (status != PJ_SUCCESS) { 
    680695            pjsip_dlg_dec_lock(dlg); 
     
    11301145    inv->cause = (pjsip_status_code) 0; 
    11311146 
     1147    /* Create flip-flop pool (see ticket #877) */ 
     1148    /* (using inv->obj_name as temporary variable for pool names */ 
     1149    pj_ansi_snprintf(inv->obj_name, PJ_MAX_OBJ_NAME, "inv%p", dlg->pool); 
     1150    inv->pool_prov = pjsip_endpt_create_pool(dlg->endpt, inv->obj_name, 
     1151                                             POOL_INIT_SIZE, POOL_INC_SIZE); 
     1152    inv->pool_active = pjsip_endpt_create_pool(dlg->endpt, inv->obj_name, 
     1153                                               POOL_INIT_SIZE, POOL_INC_SIZE); 
     1154 
    11321155    /* Object name will use the same dialog pointer. */ 
    11331156    pj_ansi_snprintf(inv->obj_name, PJ_MAX_OBJ_NAME, "inv%p", dlg); 
     
    11511174    /* Create negotiator. */ 
    11521175    if (rem_sdp) { 
    1153         status = pjmedia_sdp_neg_create_w_remote_offer(inv->pool, local_sdp, 
    1154                                                        rem_sdp, &inv->neg); 
     1176        status = pjmedia_sdp_neg_create_w_remote_offer(inv->pool,  
     1177                                                       local_sdp, rem_sdp,  
     1178                                                       &inv->neg); 
    11551179                                                 
    11561180    } else if (local_sdp) { 
    1157         status = pjmedia_sdp_neg_create_w_local_offer(inv->pool, local_sdp, 
    1158                                                       &inv->neg); 
     1181        status = pjmedia_sdp_neg_create_w_local_offer(inv->pool,  
     1182                                                      local_sdp, &inv->neg); 
    11591183    } else { 
    11601184        status = PJ_SUCCESS; 
     
    14401464 
    14411465 
     1466/* Util: swap pool */ 
     1467static void swap_pool(pj_pool_t **p1, pj_pool_t **p2) 
     1468{ 
     1469    pj_pool_t *tmp = *p1; 
     1470    *p1 = *p2; 
     1471    *p2 = tmp; 
     1472} 
     1473 
    14421474/* 
    14431475 * Initiate SDP negotiation in the SDP negotiator. 
     
    14511483                     PJMEDIA_SDPNEG_EINSTATE); 
    14521484 
    1453     status = pjmedia_sdp_neg_negotiate(inv->pool, inv->neg, 0); 
     1485    status = pjmedia_sdp_neg_negotiate(inv->pool_prov, inv->neg, 0); 
    14541486 
    14551487    PJ_LOG(5,(inv->obj_name, "SDP negotiation done, status=%d", status)); 
     
    14571489    if (mod_inv.cb.on_media_update && inv->notify) 
    14581490        (*mod_inv.cb.on_media_update)(inv, status); 
     1491 
     1492    /* Swap the flip-flop pool, and reset the new provisional pool */ 
     1493    swap_pool(&inv->pool_prov, &inv->pool_active); 
     1494    pj_pool_reset(inv->pool_prov); 
    14591495 
    14601496    return status; 
     
    15351571 
    15361572            /* Feed the original offer to negotiator */ 
    1537             status = pjmedia_sdp_neg_modify_local_offer(inv->pool, inv->neg, 
     1573            status = pjmedia_sdp_neg_modify_local_offer(inv->pool_prov,  
     1574                                                        inv->neg, 
    15381575                                                        reoffer_sdp); 
    15391576            if (status != PJ_SUCCESS) { 
     
    15811618 
    15821619        if (inv->neg == NULL) { 
    1583             status=pjmedia_sdp_neg_create_w_remote_offer(inv->pool, NULL,  
     1620            status=pjmedia_sdp_neg_create_w_remote_offer(inv->pool, NULL, 
    15841621                                                         rem_sdp, &inv->neg); 
    15851622        } else { 
    1586             status=pjmedia_sdp_neg_set_remote_offer(inv->pool, inv->neg,  
     1623            status=pjmedia_sdp_neg_set_remote_offer(inv->pool_prov, inv->neg,  
    15871624                                                    rem_sdp); 
    15881625        } 
     
    16161653                  pjsip_rx_data_get_info(rdata))); 
    16171654 
    1618         status = pjmedia_sdp_neg_set_remote_answer(inv->pool, inv->neg,  
     1655        status = pjmedia_sdp_neg_set_remote_answer(inv->pool_prov, inv->neg, 
    16191656                                                   rem_sdp); 
    16201657 
     
    16691706 
    16701707        if (inv->neg == NULL) { 
    1671             status = pjmedia_sdp_neg_create_w_local_offer(inv->pool, local_sdp, 
     1708            status = pjmedia_sdp_neg_create_w_local_offer(inv->pool,  
     1709                                                          local_sdp, 
    16721710                                                          &inv->neg); 
    16731711        } else if (pjmedia_sdp_neg_get_state(inv->neg)== 
    16741712                   PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER) 
    16751713        { 
    1676             status = pjmedia_sdp_neg_set_local_answer(inv->pool, inv->neg, 
     1714            status = pjmedia_sdp_neg_set_local_answer(inv->pool_prov, inv->neg, 
    16771715                                                      local_sdp); 
    16781716        } else { 
     
    18791917 
    18801918    pjsip_dlg_inc_lock(inv->dlg); 
    1881     status = pjmedia_sdp_neg_set_local_answer( inv->pool, inv->neg, sdp); 
     1919    status = pjmedia_sdp_neg_set_local_answer( inv->pool_prov, inv->neg, sdp); 
    18821920    pjsip_dlg_dec_lock(inv->dlg); 
    18831921 
     
    22282266    if (new_offer) { 
    22292267        if (!inv->neg) { 
    2230             status = pjmedia_sdp_neg_create_w_local_offer(inv->pool, new_offer, 
     2268            status = pjmedia_sdp_neg_create_w_local_offer(inv->pool,  
     2269                                                          new_offer, 
    22312270                                                          &inv->neg); 
    22322271            if (status != PJ_SUCCESS) 
     
    22472286 
    22482287            case PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER: 
    2249                 status = pjmedia_sdp_neg_set_local_answer(inv->pool, inv->neg, 
     2288                status = pjmedia_sdp_neg_set_local_answer(inv->pool_prov,  
     2289                                                          inv->neg, 
    22502290                                                          new_offer); 
    22512291                if (status != PJ_SUCCESS) 
     
    22602300 
    22612301            case PJMEDIA_SDP_NEG_STATE_DONE: 
    2262                 status = pjmedia_sdp_neg_modify_local_offer(inv->pool,inv->neg, 
     2302                status = pjmedia_sdp_neg_modify_local_offer(inv->pool_prov, 
     2303                                                            inv->neg, 
    22632304                                                            new_offer); 
    22642305                if (status != PJ_SUCCESS) 
     
    23162357     * with correct SDP origin. 
    23172358     */ 
    2318     status = pjmedia_sdp_neg_modify_local_offer(inv->pool,inv->neg, 
     2359    status = pjmedia_sdp_neg_modify_local_offer(inv->pool_prov, inv->neg, 
    23192360                                                offer); 
    23202361    if (status != PJ_SUCCESS) 
     
    37453786                         * fix the offer with correct SDP origin. 
    37463787                         */ 
    3747                         status = pjmedia_sdp_neg_modify_local_offer(dlg->pool, 
    3748                                                                     inv->neg, 
    3749                                                                     sdp); 
     3788                        status =  
     3789                            pjmedia_sdp_neg_modify_local_offer(inv->pool_prov, 
     3790                                                               inv->neg, 
     3791                                                               sdp); 
    37503792 
    37513793                        /* Retrieve the "fixed" offer from negotiator */ 
     
    37603802                if (sdp == NULL) { 
    37613803                    const pjmedia_sdp_session *active_sdp = NULL; 
    3762                     status = pjmedia_sdp_neg_send_local_offer(dlg->pool,  
     3804                    status = pjmedia_sdp_neg_send_local_offer(inv->pool_prov, 
    37633805                                                              inv->neg,  
    37643806                                                              &active_sdp); 
  • pjproject/trunk/pjsip/src/pjsip-ua/sip_timer.c

    r2865 r2869  
    360360            status = pjsip_inv_invite(inv, &tdata); 
    361361            if (status == PJ_SUCCESS) 
    362                 status = pjmedia_sdp_neg_send_local_offer(inv->pool,  
     362                status = pjmedia_sdp_neg_send_local_offer(inv->pool_prov,  
    363363                                                          inv->neg, &offer); 
    364364            if (status == PJ_SUCCESS) 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c

    r2859 r2869  
    15971597        status = create_sdp_of_call_hold(call, &sdp); 
    15981598    } else { 
    1599         status = pjsua_media_channel_create_sdp(call->index, call->inv->pool,  
     1599        status = pjsua_media_channel_create_sdp(call->index,  
     1600                                                call->inv->pool_prov, 
    16001601                                                NULL, &sdp, NULL); 
    16011602        call->local_hold = PJ_FALSE; 
     
    16561657 
    16571658    /* Create SDP */ 
    1658     status = pjsua_media_channel_create_sdp(call->index, call->inv->pool,  
     1659    status = pjsua_media_channel_create_sdp(call->index,  
     1660                                            call->inv->pool_prov,  
    16591661                                            NULL, &sdp, NULL); 
    16601662    if (status != PJ_SUCCESS) { 
     
    32013203    pjmedia_sdp_session *sdp; 
    32023204 
    3203     /* Use call's pool */ 
    3204     pool = call->inv->pool; 
     3205    /* Use call's provisional pool */ 
     3206    pool = call->inv->pool_prov; 
    32053207 
    32063208    /* Create new offer */ 
     
    32683270              call->index)); 
    32693271 
    3270     status = pjsua_media_channel_create_sdp(call->index, call->inv->pool,  
     3272    status = pjsua_media_channel_create_sdp(call->index,  
     3273                                            call->inv->pool_prov,  
    32713274                                            offer, &answer, NULL); 
    32723275    if (status != PJ_SUCCESS) { 
     
    32973300         * (See RFC 3264 Section 8.4 and RFC 4317 Section 3.1) 
    32983301         */ 
    3299         attr = pjmedia_sdp_attr_create(call->inv->pool, "sendonly", NULL); 
     3302        attr = pjmedia_sdp_attr_create(call->inv->pool_prov, "sendonly", NULL); 
    33003303        pjmedia_sdp_media_add_attr(answer->media[0], attr); 
    33013304    } 
     
    33353338                  call->index)); 
    33363339 
    3337         status = pjsua_media_channel_create_sdp(call->index, call->inv->pool,  
     3340        status = pjsua_media_channel_create_sdp(call->index,  
     3341                                                call->inv->pool_prov,  
    33383342                                                NULL, offer, NULL); 
    33393343    } 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c

    r2864 r2869  
    14271427    /* Create media session info based on SDP parameters.  
    14281428     */     
    1429     status = pjmedia_session_info_from_sdp( call->inv->dlg->pool,  
     1429    status = pjmedia_session_info_from_sdp( call->inv->pool_prov,  
    14301430                                            pjsua_var.med_endpt,  
    14311431                                            PJMEDIA_MAX_SDP_MEDIA, &sess_info, 
     
    14701470        /* Start/restart media transport */ 
    14711471        status = pjmedia_transport_media_start(call->med_tp,  
    1472                                                call->inv->pool, 
     1472                                               call->inv->pool_prov, 
    14731473                                               local_sdp, remote_sdp, 0); 
    14741474        if (status != PJ_SUCCESS) 
     
    15731573                port_name = pj_str("call"); 
    15741574            } 
    1575             status = pjmedia_conf_add_port( pjsua_var.mconf, call->inv->pool, 
     1575            status = pjmedia_conf_add_port( pjsua_var.mconf,  
     1576                                            call->inv->pool_prov, 
    15761577                                            media_port,  
    15771578                                            &port_name, 
Note: See TracChangeset for help on using the changeset viewer.