PJ_DEF(pj_status_t) pjsip_tx_data_create( pjsip_tpmgr *mgr,
					  pjsip_tx_data **p_tdata )
{
    pj_pool_t *pool;
    pjsip_tx_data *tdata;
    pj_status_t status;

    PJ_ASSERT_RETURN(mgr && p_tdata, PJ_EINVAL);

    pool = pjsip_endpt_create_pool( mgr->endpt, "tdta%p",
				    PJSIP_POOL_LEN_TDATA,
				    PJSIP_POOL_INC_TDATA );
    if (!pool)
	return PJ_ENOMEM;

    tdata = PJ_POOL_ZALLOC_T(pool, pjsip_tx_data);
    tdata->pool = pool;
    tdata->mgr = mgr;
    pj_ansi_snprintf(tdata->obj_name, sizeof(tdata->obj_name), "tdta%p", tdata);
    pj_memcpy(pool->obj_name, tdata->obj_name, sizeof(pool->obj_name));

    status = pj_atomic_create(tdata->pool, 0, &tdata->ref_cnt);
    if (status != PJ_SUCCESS) {
	pjsip_endpt_release_pool( mgr->endpt, tdata->pool );
	return status;
    }
    
    //status = pj_lock_create_simple_mutex(pool, "tdta%p", &tdata->lock);
    status = pj_lock_create_null_mutex(pool, "tdta%p", &tdata->lock);
    if (status != PJ_SUCCESS) {
	pjsip_endpt_release_pool( mgr->endpt, tdata->pool );
	return status;
    }

    pj_ioqueue_op_key_init(&tdata->op_key.key, sizeof(tdata->op_key.key));
    pj_list_init(tdata);

#if defined(PJSIP_HAS_TX_DATA_LIST) && PJSIP_HAS_TX_DATA_LIST!=0
    /* Append this just created tdata to transmit buffer list */
    pj_lock_acquire(mgr->lock);
    pj_list_push_back(&mgr->tdata_list, tdata);
    pj_lock_release(mgr->lock);
#endif

#if defined(PJ_DEBUG) && PJ_DEBUG!=0
    pj_atomic_inc( tdata->mgr->tdata_counter );
#endif

    *p_tdata = tdata;
    return PJ_SUCCESS;
}
PJ_DEF(pj_status_t) pjsip_tx_data_create( pjsip_tpmgr *mgr,
					  pjsip_tx_data **p_tdata )
{
    pj_pool_t *pool;
    pjsip_tx_data *tdata;
    pj_status_t status;

    PJ_ASSERT_RETURN(mgr && p_tdata, PJ_EINVAL);

    pool = pjsip_endpt_create_pool( mgr->endpt, "tdta%p",
				    PJSIP_POOL_LEN_TDATA,
				    PJSIP_POOL_INC_TDATA );
    if (!pool)
	return PJ_ENOMEM;

    tdata = PJ_POOL_ZALLOC_T(pool, pjsip_tx_data);
    tdata->pool = pool;
    tdata->mgr = mgr;
    pj_ansi_snprintf(tdata->obj_name, sizeof(tdata->obj_name), "tdta%p", tdata);
    pj_memcpy(pool->obj_name, tdata->obj_name, sizeof(pool->obj_name));

    status = pj_atomic_create(tdata->pool, 0, &tdata->ref_cnt);
    if (status != PJ_SUCCESS) {
	pjsip_endpt_release_pool( mgr->endpt, tdata->pool );
	return status;
    }
    
     
    status = pj_lock_create_null_mutex(pool, "tdta%p", &tdata->lock);
    if (status != PJ_SUCCESS) {
	pjsip_endpt_release_pool( mgr->endpt, tdata->pool );
	return status;
    }

    pj_ioqueue_op_key_init(&tdata->op_key.key, sizeof(tdata->op_key.key));
    pj_list_init(tdata);

#if defined(PJSIP_HAS_TX_DATA_LIST) && PJSIP_HAS_TX_DATA_LIST!=0
     
    pj_lock_acquire(mgr->lock);
    pj_list_push_back(&mgr->tdata_list, tdata);
    pj_lock_release(mgr->lock);
#endif

#if defined(PJ_DEBUG) && PJ_DEBUG!=0
    pj_atomic_inc( tdata->mgr->tdata_counter );
#endif

    *p_tdata = tdata;
    return PJ_SUCCESS;
}