/* protected by req_mutex */ void ldap_free_request( LDAP *ld, LDAPRequest *lr ) { LDAP_ASSERT_MUTEX_OWNER( &ld->ld_req_mutex ); Debug( LDAP_DEBUG_TRACE, "ldap_free_request (origid %d, msgid %d)\n", lr->lr_origid, lr->lr_msgid, 0 ); /* free all referrals (child requests) */ while ( lr->lr_child ) { ldap_free_request( ld, lr->lr_child ); } if ( lr->lr_parent != NULL ) { LDAPRequest **lrp; --lr->lr_parent->lr_outrefcnt; for ( lrp = &lr->lr_parent->lr_child; *lrp && *lrp != lr; lrp = &(*lrp)->lr_refnext ); if ( *lrp == lr ) { *lrp = lr->lr_refnext; } } ldap_free_request_int( ld, lr ); }
/* protected by req_mutex */ void ldap_return_request( LDAP *ld, LDAPRequest *lrx, int freeit ) { LDAPRequest *lr; for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) { if ( lr == lrx ) { if ( lr->lr_refcnt > 0 ) { lr->lr_refcnt--; } else if ( lr->lr_refcnt < 0 ) { lr->lr_refcnt++; if ( lr->lr_refcnt == 0 ) { lr = NULL; } } break; } } if ( lr == NULL ) { ldap_free_request_int( ld, lrx ); } else if ( freeit ) { ldap_free_request( ld, lrx ); } }
void ldap_return_request( LDAP *ld, LDAPRequest *lrx, int freeit ) { LDAPRequest *lr; #ifdef LDAP_R_COMPILE ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex ); #endif for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) { if ( lr == lrx ) { if ( lr->lr_refcnt > 0 ) { lr->lr_refcnt--; } else if ( lr->lr_refcnt < 0 ) { lr->lr_refcnt++; if ( lr->lr_refcnt == 0 ) { lr = NULL; } } break; } } if ( lr == NULL ) { ldap_free_request_int( ld, lrx ); } else if ( freeit ) { ldap_free_request( ld, lrx ); } #ifdef LDAP_R_COMPILE ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex ); #endif }
/* protected by ld_conn_mutex */ void ldap_free_connection( LDAP *ld, LDAPConn *lc, int force, int unbind ) { LDAPConn *tmplc, *prevlc; LDAP_ASSERT_MUTEX_OWNER( &ld->ld_conn_mutex ); Debug( LDAP_DEBUG_TRACE, "ldap_free_connection %d %d\n", force, unbind, 0 ); if ( force || --lc->lconn_refcnt <= 0 ) { /* remove from connections list first */ for ( prevlc = NULL, tmplc = ld->ld_conns; tmplc != NULL; tmplc = tmplc->lconn_next ) { if ( tmplc == lc ) { if ( prevlc == NULL ) { ld->ld_conns = tmplc->lconn_next; } else { prevlc->lconn_next = tmplc->lconn_next; } if ( ld->ld_defconn == lc ) { ld->ld_defconn = NULL; } break; } prevlc = tmplc; } /* process connection callbacks */ { struct ldapoptions *lo; ldaplist *ll; ldap_conncb *cb; lo = &ld->ld_options; LDAP_MUTEX_LOCK( &lo->ldo_mutex ); if ( lo->ldo_conn_cbs ) { for ( ll=lo->ldo_conn_cbs; ll; ll=ll->ll_next ) { cb = ll->ll_data; cb->lc_del( ld, lc->lconn_sb, cb ); } } LDAP_MUTEX_UNLOCK( &lo->ldo_mutex ); lo = LDAP_INT_GLOBAL_OPT(); LDAP_MUTEX_LOCK( &lo->ldo_mutex ); if ( lo->ldo_conn_cbs ) { for ( ll=lo->ldo_conn_cbs; ll; ll=ll->ll_next ) { cb = ll->ll_data; cb->lc_del( ld, lc->lconn_sb, cb ); } } LDAP_MUTEX_UNLOCK( &lo->ldo_mutex ); } if ( lc->lconn_status == LDAP_CONNST_CONNECTED ) { ldap_mark_select_clear( ld, lc->lconn_sb ); if ( unbind ) { ldap_send_unbind( ld, lc->lconn_sb, NULL, NULL ); } } if ( lc->lconn_ber != NULL ) { ber_free( lc->lconn_ber, 1 ); } ldap_int_sasl_close( ld, lc ); #ifdef HAVE_GSSAPI ldap_int_gssapi_close( ld, lc ); #endif ldap_free_urllist( lc->lconn_server ); /* FIXME: is this at all possible? * ldap_ld_free() in unbind.c calls ldap_free_connection() * with force == 1 __after__ explicitly calling * ldap_free_request() on all requests */ if ( force ) { LDAPRequest *lr; for ( lr = ld->ld_requests; lr; ) { LDAPRequest *lr_next = lr->lr_next; if ( lr->lr_conn == lc ) { ldap_free_request_int( ld, lr ); } lr = lr_next; } } if ( lc->lconn_sb != ld->ld_sb ) { ber_sockbuf_free( lc->lconn_sb ); } else { ber_int_sb_close( lc->lconn_sb ); } if ( lc->lconn_rebind_queue != NULL) { int i; for( i = 0; lc->lconn_rebind_queue[i] != NULL; i++ ) { LDAP_VFREE( lc->lconn_rebind_queue[i] ); } LDAP_FREE( lc->lconn_rebind_queue ); } LDAP_FREE( lc ); Debug( LDAP_DEBUG_TRACE, "ldap_free_connection: actually freed\n", 0, 0, 0 ); } else { lc->lconn_lastused = time( NULL ); Debug( LDAP_DEBUG_TRACE, "ldap_free_connection: refcnt %d\n", lc->lconn_refcnt, 0, 0 ); } }