/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 1998-2014 The OpenLDAP Foundation.
+ * Copyright 1998-2018 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
sd = c->c_sd;
c->c_sd = AC_SOCKET_INVALID;
- c->c_conn_state = SLAP_C_INVALID;
- c->c_struct_state = SLAP_C_UNUSED;
c->c_close_reason = "?"; /* should never be needed */
sb = c->c_sb;
ber_len_t max = sockbuf_max_incoming;
ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
}
+ c->c_conn_state = SLAP_C_INVALID;
+ c->c_struct_state = SLAP_C_UNUSED;
/* c must be fully reset by this point; when we call slapd_remove
* it may get immediately reused by a new connection.
SlapReply rs = {REP_RESULT};
next = LDAP_STAILQ_NEXT( o, o_next );
+ /* don't abandon an op twice */
+ if ( o->o_abandon )
+ continue;
op.orn_msgid = o->o_msgid;
o->o_abandon = 1;
op.o_bd = frontendDB;
op->o_counters = vsc;
}
+void
+connection_op_finish( Operation *op )
+{
+ Connection *conn = op->o_conn;
+ void *memctx_null = NULL;
+ slap_op_t opidx = slap_req2op( op->o_tag );
+ assert( opidx != SLAP_OP_LAST );
+
+ INCR_OP_COMPLETED( opidx );
+
+ 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++;
+ connection_resched( conn );
+ ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+}
+
static void *
connection_operation( void *ctx, void *arg_v )
{
void *memctx_null = NULL;
ber_len_t memsiz;
+ gettimeofday( &op->o_qtime, NULL );
+ op->o_qtime.tv_usec -= op->o_tusec;
+ if ( op->o_qtime.tv_usec < 0 ) {
+ op->o_qtime.tv_usec += 1000000;
+ op->o_qtime.tv_sec--;
+ }
+ op->o_qtime.tv_sec -= op->o_time;
conn_counter_init( op, ctx );
ldap_pvt_thread_mutex_lock( &op->o_counters->sc_mutex );
/* FIXME: returns 0 in case of failure */
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
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;
+#ifdef LDAP_X_TXN
+ if ( rc != LDAP_X_TXN_SPECIFY_OKAY )
+#endif
+ {
+ 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++;
connection_resched( conn );
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
- slap_op_free( op, ctx );
+#ifdef LDAP_X_TXN
+ if ( rc != LDAP_X_TXN_SPECIFY_OKAY )
+#endif
+ {
+ slap_op_free( op, ctx );
+ }
return NULL;
}
assert( c->c_conn_state == SLAP_C_CLIENT );
c->c_listener = NULL;
- c->c_conn_state = SLAP_C_INVALID;
- c->c_struct_state = SLAP_C_UNUSED;
c->c_sd = AC_SOCKET_INVALID;
c->c_close_reason = "?"; /* should never be needed */
sb = c->c_sb;
ber_len_t max = sockbuf_max_incoming;
ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
}
+ c->c_conn_state = SLAP_C_INVALID;
+ c->c_struct_state = SLAP_C_UNUSED;
slapd_remove( s, sb, 0, 1, 0 );
connection_return( c );