rc = frontendDB->be_add( op, rs );
LDAP_SLIST_REMOVE(&op->o_extra, &oex.oe, OpExtra, oe_next);
+ if ( rc == SLAPD_ASYNCOP ) {
+ /* skip cleanup */
+ return rc;
+ }
+
#ifdef LDAP_X_TXN
if ( rc == LDAP_X_TXN_SPECIFY_OKAY ) {
/* skip cleanup */
return rc;
}
+static int
+over_op_func_cleanup( Operation *op, SlapReply *rs )
+{
+ slap_callback *cb = op->o_callback;
+ if ( rs->sr_type == REP_RESULT && cb != NULL) {
+ op->o_callback = cb->sc_next;
+ ch_free( cb );
+ }
+}
+
static int
over_op_func(
Operation *op,
db.be_flags |= SLAP_DBFLAG_OVERLAY;
op->o_bd = &db;
}
- cb->sc_cleanup = NULL;
+ cb->sc_cleanup = over_op_func_cleanup;
cb->sc_response = over_back_response;
cb->sc_writewait = NULL;
cb->sc_next = op->o_callback;
op->o_bd = frontendDB;
rs->sr_err = frontendDB->be_compare( op, rs );
+ if ( rs->sr_err == SLAPD_ASYNCOP ) {
+ /* skip cleanup */
+ return rs->sr_err;
+ }
cleanup:;
op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
op->o_counters = vsc;
}
+void
+connection_op_finish( Operation *op )
+{
+ Connection *conn = op->o_conn;
+ void *memctx_null = NULL;
+
+ ldap_pvt_thread_mutex_lock( &conn->c_mutex );
+
+ if ( op->o_tag == LDAP_REQ_BIND && conn->c_conn_state == SLAP_C_BINDING )
+ conn->c_conn_state = SLAP_C_ACTIVE;
+
+ ber_set_option( op->o_ber, LBER_OPT_BER_MEMCTX, &memctx_null );
+
+ LDAP_STAILQ_REMOVE( &conn->c_ops, op, Operation, o_next);
+ LDAP_STAILQ_NEXT(op, o_next) = NULL;
+ conn->c_n_ops_executing--;
+ conn->c_n_ops_completed++;
+ ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+}
+
static void *
connection_operation( void *ctx, void *arg_v )
{
if ( rc == SLAPD_DISCONNECT ) {
tag = LBER_ERROR;
+ } else if ( rc == SLAPD_ASYNCOP ) {
+ /* someone has claimed ownership of the op
+ * to complete it later. Don't do anything
+ * else with it now. Detach memctx too.
+ */
+ slap_sl_mem_setctx( ctx, NULL );
+ ldap_pvt_thread_mutex_lock( &conn->c_mutex );
+ connection_resched( conn );
+ ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+ return NULL;
+
} else if ( opidx != SLAP_OP_LAST ) {
/* increment completed operations count
* only if operation was initiated
op->o_bd = frontendDB;
rs->sr_err = frontendDB->be_delete( op, rs );
+ if ( rs->sr_err == SLAPD_ASYNCOP ) {
+ /* skip cleanup */
+ return rs->sr_err;
+ }
#ifdef LDAP_X_TXN
if( rs->sr_err == LDAP_X_TXN_SPECIFY_OKAY ) {
op->o_bd = frontendDB;
rs->sr_err = frontendDB->be_modify( op, rs );
+ if ( rs->sr_err == SLAPD_ASYNCOP ) {
+ /* skip cleanup */
+ return rs->sr_err;
+ }
#ifdef LDAP_X_TXN
if( rs->sr_err == LDAP_X_TXN_SPECIFY_OKAY ) {
op->o_bd = frontendDB;
rs->sr_err = frontendDB->be_modrdn( op, rs );
+ if ( rs->sr_err == SLAPD_ASYNCOP ) {
+ /* skip cleanup */
+ return rs->sr_err;
+ }
#ifdef LDAP_X_TXN
if( rs->sr_err == LDAP_X_TXN_SPECIFY_OKAY ) {
/* skip cleanup */
+ return rs->sr_err;
}
#endif
LDAP_SLAPD_F (int) connection_read_activate LDAP_P((ber_socket_t s));
LDAP_SLAPD_F (int) connection_write LDAP_P((ber_socket_t s));
+LDAP_SLAPD_F (void) connection_op_finish LDAP_P((
+ Operation *op ));
+
LDAP_SLAPD_F (unsigned long) connections_nextid(void);
LDAP_SLAPD_F (Connection *) connection_first LDAP_P(( ber_socket_t * ));
op->o_bd = frontendDB;
rs->sr_err = frontendDB->be_search( op, rs );
+ if ( rs->sr_err == SLAPD_ASYNCOP ) {
+ /* skip cleanup */
+ return rs->sr_err;
+ }
return_results:;
if ( !BER_BVISNULL( &op->o_req_dn ) ) {
/* unknown config file directive */
#define SLAP_CONF_UNKNOWN (-1026)
+/* pseudo error code indicating async operation */
+#define SLAPD_ASYNCOP (-1027)
+
/* We assume "C" locale, that is US-ASCII */
#define ASCII_SPACE(c) ( (c) == ' ' )
#define ASCII_LOWER(c) ( (c) >= 'a' && (c) <= 'z' )