Debug( LDAP_DEBUG_ANY, "request_bind: "
"ber_alloc failed\n" );
- operation_unlink( op );
+ OPERATION_UNLINK(op);
CONNECTION_LOCK(client);
goto fail;
}
done:
- operation_unlink( op );
+ OPERATION_UNLINK(op);
ber_free( ber, 1 );
return rc;
}
"connid=%lu msgid=%d invalid integer sent in abandon request\n",
c->c_connid, op->o_client_msgid );
- operation_unlink( op );
+ OPERATION_UNLINK(op);
CONNECTION_LOCK_DESTROY(c);
return -1;
}
operation_abandon( request );
done:
- operation_unlink( op );
+ OPERATION_UNLINK(op);
return rc;
}
operation_send_reject( op, LDAP_OTHER, "internal error", 0 );
}
- operation_unlink( op );
+ OPERATION_UNLINK(op);
if ( rc ) {
CONNECTION_LOCK_DESTROY(client);
}
case LDAP_REQ_UNBIND:
/* There is never a response for this operation */
op->o_res = LLOAD_OP_COMPLETED;
- operation_unlink( op );
+ OPERATION_UNLINK(op);
Debug( LDAP_DEBUG_STATS, "handle_one_request: "
"received unbind, closing client connid=%lu\n",
}
CONNECTION_UNLOCK(c);
- operation_unlink( op );
+ OPERATION_UNLINK(op);
CONNECTION_LOCK(c);
} while ( c->c_ops );
}
int
-try_release_ref( uintptr_t *refp, void *object, dispose_cb *cb )
+try_release_ref(
+ uintptr_t *refp,
+ void *object,
+ dispose_cb *unlink_cb,
+ dispose_cb *destroy_cb )
{
uintptr_t refcnt, new_refcnt;
assert( new_refcnt == refcnt - 1 );
if ( !new_refcnt ) {
- epoch_append( object, cb );
+ if ( unlink_cb ) {
+ unlink_cb( object );
+ }
+ epoch_append( object, destroy_cb );
}
return refcnt;
* @return 0 if reference was already zero, non-zero if reference
* count was non-zero at the time of call
*/
-int try_release_ref( uintptr_t *refp, void *object, dispose_cb *cb );
+int try_release_ref(
+ uintptr_t *refp,
+ void *object,
+ dispose_cb *unlink_cb,
+ dispose_cb *destroy_cb );
/** @brief Read reference count
*
output = c->c_pendingber;
if ( output == NULL && (output = ber_alloc()) == NULL ) {
checked_unlock( &c->c_io_mutex );
- operation_unlink( op );
+ OPERATION_UNLINK(op);
CONNECTION_LOCK_DESTROY(c);
return -1;
}
op->o_res = LLOAD_OP_COMPLETED;
CONNECTION_UNLOCK(c);
- operation_unlink( op );
+ OPERATION_UNLINK(op);
return -1;
#endif /* HAVE_TLS */
/*
* Operation reference tracking:
* - o_refcnt is set to 1, never incremented
- * - operation_unlink sets it to 0 and on transition from 1 clears both
+ * - OPERATION_UNLINK sets it to 0 and on transition from 1 clears both
* connection links (o_client, o_upstream)
*/
struct LloadOperation {
uintptr_t o_refcnt;
+#define OPERATION_UNLINK(op) \
+ try_release_ref( &(op)->o_refcnt, (op), \
+ (dispose_cb *)operation_unlink, \
+ (dispose_cb *)operation_destroy )
LloadConnection *o_client;
unsigned long o_client_connid;
uintptr_t prev_refcnt;
int result = 0;
- if ( !( prev_refcnt = try_release_ref(
- &op->o_refcnt, op, (dispose_cb *)operation_destroy ) ) ) {
- return result;
- }
-
- assert( prev_refcnt == 1 );
+ assert( op->o_refcnt == 0 );
Debug( LDAP_DEBUG_TRACE, "operation_unlink: "
"unlinking operation between client connid=%lu and upstream "
}
done:
- operation_unlink( op );
+ OPERATION_UNLINK(op);
}
void
connection_write_cb( -1, 0, c );
done:
- operation_unlink( op );
+ OPERATION_UNLINK(op);
}
/*
if ( upstream->c_type != LLOAD_C_BIND && rc == LDAP_SUCCESS ) {
rc = operation_send_abandon( op, upstream );
}
- operation_unlink( op );
+ OPERATION_UNLINK(op);
}
if ( rc == LDAP_SUCCESS ) {
op->o_res = LLOAD_OP_COMPLETED;
if ( !op->o_pin_id ) {
- operation_unlink( op );
+ OPERATION_UNLINK(op);
}
return rc;