]> git.sur5r.net Git - openldap/commitdiff
ITS#8725 Add SLAPD_ASYNCOP return code
authorHoward Chu <hyc@openldap.org>
Mon, 16 Jan 2017 21:21:33 +0000 (21:21 +0000)
committerHoward Chu <hyc@openldap.org>
Thu, 7 Sep 2017 17:07:39 +0000 (18:07 +0100)
Tell frontend the op will finish asynchronously, leave it alone

servers/slapd/add.c
servers/slapd/backover.c
servers/slapd/compare.c
servers/slapd/connection.c
servers/slapd/delete.c
servers/slapd/modify.c
servers/slapd/modrdn.c
servers/slapd/proto-slap.h
servers/slapd/search.c
servers/slapd/slap.h

index 99b8656dce91b0d3ffb66c322935ea9df7a85b82..d0b3b772fdfaac0b154452ccaeba31d78f5641f6 100644 (file)
@@ -194,6 +194,11 @@ do_add( Operation *op, SlapReply *rs )
        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 */
index 8914920998c2e5da01f061804a42d8899be77474..a673fb36c62575948712cd53fd7e45c79cbd809a 100644 (file)
@@ -717,6 +717,16 @@ 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,
@@ -743,7 +753,7 @@ over_op_func(
                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;
index a656e12b05217e510f46de8239c9b85d2e253aad..b36062d3958d7eda5af8be7bd06ffa1f8e7f5195 100644 (file)
@@ -125,6 +125,10 @@ do_compare(
 
        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 );
index 5fe8d148fd7462fd904233162f2eecc5a34cdfe7..4d464b0b45f061f909d0911949b581155c736425 100644 (file)
@@ -1040,6 +1040,26 @@ conn_counter_init( Operation *op, void *ctx )
        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 )
 {
@@ -1147,6 +1167,17 @@ operations_error:
        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
index 7afcfeabe2b1e6105035f16268bbc8a3723d45ae..70a3354345d670121ef32a1811e14392fd02c1bb 100644 (file)
@@ -93,6 +93,10 @@ do_delete(
 
        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 ) {
index a554cf71c33e587f47131fb9d82e313e4adcfa99..d074ce2746ee08a3477ed6e5b27c1a97006a23aa 100644 (file)
@@ -175,6 +175,10 @@ do_modify(
 
        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 ) {
index 23579c1e98e6ef46b303a735303fa5734747e3f4..67340f2f5ef9bf28e5e374045f0568f725c86d9c 100644 (file)
@@ -185,9 +185,14 @@ do_modrdn(
        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
 
index 9d3d39bfe1d406b4e57ec779943a09246a32c2f7..7478067ea432b2770babc7383faf8f5679c7f5a4 100644 (file)
@@ -806,6 +806,9 @@ LDAP_SLAPD_F (const char *) connection_state2str LDAP_P(( int state ))
 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 * ));
index 74bd3f219e7a0928275e46477bdd566dbf410335..01b90e3d9bcd961785eaac6d781b2f239fa1ce82 100644 (file)
@@ -245,6 +245,10 @@ do_search(
 
        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 ) ) {
index e401650a868889ade5d835c73487df28698cba27..ede7b793da9ca3f941a45a2019f96eacb57b2b6e 100644 (file)
@@ -155,6 +155,9 @@ LDAP_BEGIN_DECL
 /* 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' )