PJ_DEF(pj_status_t) pjsip_transport_shutdown2(pjsip_transport *tp,
					      pj_bool_t force)
{
    pjsip_tpmgr *mgr;
    pj_status_t status;
    pjsip_tp_state_callback state_cb;

    PJ_LOG(4, (THIS_FILE, "Transport %s shutting down, force=%d",
			  tp->obj_name, force));

    pj_lock_acquire(tp->lock);

    mgr = tp->tpmgr;
    pj_lock_acquire(mgr->lock);

    /* Do nothing if transport is being shutdown/destroyed already */
    if (tp->is_shutdown || tp->is_destroying) {
	pj_lock_release(mgr->lock);
	pj_lock_release(tp->lock);
	return PJ_SUCCESS;
    }

    status = PJ_SUCCESS;

    /* Instruct transport to shutdown itself */
    if (tp->do_shutdown)
	status = tp->do_shutdown(tp);

    if (status == PJ_SUCCESS)
	tp->is_shutdown = PJ_TRUE;

    /* Notify application of transport shutdown */
    state_cb = pjsip_tpmgr_get_state_cb(tp->tpmgr);
    if (state_cb) {
	pjsip_transport_state_info state_info;

	pj_bzero(&state_info, sizeof(state_info));
	state_info.status = PJ_ECANCELLED;
	(*state_cb)(tp, (force? PJSIP_TP_STATE_DISCONNECTED:
		    PJSIP_TP_STATE_SHUTDOWN), &state_info);
    }

    /* If transport reference count is zero, start timer count-down */
    if (pj_atomic_get(tp->ref_cnt) == 0) {
	pjsip_transport_add_ref(tp);
	pjsip_transport_dec_ref(tp);
    }

    pj_lock_release(mgr->lock);
    pj_lock_release(tp->lock);

    return status;
}
PJ_DEF(pj_status_t) pjsip_transport_shutdown2(pjsip_transport *tp,
					      pj_bool_t force)
{
    pjsip_tpmgr *mgr;
    pj_status_t status;
    pjsip_tp_state_callback state_cb;

    PJ_LOG(4, (THIS_FILE, "Transport %s shutting down, force=%d",
			  tp->obj_name, force));

    pj_lock_acquire(tp->lock);

    mgr = tp->tpmgr;
    pj_lock_acquire(mgr->lock);

     
    if (tp->is_shutdown || tp->is_destroying) {
	pj_lock_release(mgr->lock);
	pj_lock_release(tp->lock);
	return PJ_SUCCESS;
    }

    status = PJ_SUCCESS;

     
    if (tp->do_shutdown)
	status = tp->do_shutdown(tp);

    if (status == PJ_SUCCESS)
	tp->is_shutdown = PJ_TRUE;

     
    state_cb = pjsip_tpmgr_get_state_cb(tp->tpmgr);
    if (state_cb) {
	pjsip_transport_state_info state_info;

	pj_bzero(&state_info, sizeof(state_info));
	state_info.status = PJ_ECANCELLED;
	(*state_cb)(tp, (force? PJSIP_TP_STATE_DISCONNECTED:
		    PJSIP_TP_STATE_SHUTDOWN), &state_info);
    }

     
    if (pj_atomic_get(tp->ref_cnt) == 0) {
	pjsip_transport_add_ref(tp);
	pjsip_transport_dec_ref(tp);
    }

    pj_lock_release(mgr->lock);
    pj_lock_release(tp->lock);

    return status;
}