"marking connection connid=%lu closing\n",
c->c_connid );
- /* We were approached from the connection list or cn=monitor */
+ /* Caller makes sure we're safe to unlock */
assert( IS_ALIVE( c, c_refcnt ) );
/* Need to acquire this first, even if we won't need it */
int gentle = 1;
CONNECTION_LOCK(client);
- assert( client->c_restricted >= LLOAD_OP_RESTRICTED_UPSTREAM );
- assert( client->c_linked_upstream );
-
client->c_restricted = LLOAD_OP_NOT_RESTRICTED;
client->c_linked_upstream = NULL;
CONNECTION_UNLOCK(client);
CONNECTION_LOCK(c);
};
+ /* Let all clients unlink */
+ node = ldap_tavl_end( c->c_linked, TAVL_DIR_LEFT );
+ while ( node ) {
+ LloadConnection *client;
+ int cmp = 0;
+
+ /*
+ * The upstream is CLOSING so it won't get new clients in, but
+ * releasing c_mutex allows clients to unregister themselves.
+ */
+ client = (LloadConnection *)node->avl_data;
+ while ( !acquire_ref( &client->c_refcnt ) ) {
+ node = ldap_tavl_next( node, TAVL_DIR_RIGHT );
+ if ( !node ) {
+ break;
+ }
+ client = node->avl_data;
+ }
+ if ( !node ) break;
+
+ CONNECTION_UNLOCK(c);
+ linked_upstream_lost( client );
+ CONNECTION_LOCK(c);
+
+ node = ldap_tavl_find3( c->c_linked, client, lload_upstream_entry_cmp, &cmp );
+ if ( node && cmp <= 0 ) {
+ TAvlnode *next = ldap_tavl_next( node, TAVL_DIR_RIGHT );
+ if ( client == node->avl_data ) {
+ ldap_tavl_delete( &c->c_linked, client, lload_upstream_entry_cmp );
+ }
+ node = next;
+ }
+ RELEASE_REF( client, c_refcnt, client->c_destroy );
+ }
+
+ if ( c->c_state == LLOAD_C_CLOSING && c->c_ops ) {
+ CONNECTION_UNLOCK(c);
+ } else {
+ CONNECTION_DESTROY(c);
+ }
+
out:
ber_free( ber, 1 );
if ( c->c_state == LLOAD_C_CLOSING && c->c_ops ) {