/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 1998-2004 The OpenLDAP Foundation.
+ * Copyright 1998-2005 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#include "portable.h"
#include <stdio.h>
+#ifdef HAVE_LIMITS_H
#include <limits.h>
+#endif
#include <ac/socket.h>
#include <ac/errno.h>
free(c->c_ndn.bv_val);
}
BER_BVZERO( &c->c_ndn );
+ if(c->c_sasl_authz_dn.bv_val != NULL) {
+ free(c->c_sasl_authz_dn.bv_val);
+ }
+ BER_BVZERO( &c->c_sasl_authz_dn );
c->c_authz_backend = NULL;
}
/* wake write blocked operations */
slapd_clr_write( sd, 1 );
- ldap_pvt_thread_cond_signal( &c->c_write_cv );
+ if ( c->c_writewaiter ) {
+ ldap_pvt_thread_cond_signal( &c->c_write_cv );
+ ldap_pvt_thread_mutex_unlock( &c->c_mutex );
+ ldap_pvt_thread_yield();
+ ldap_pvt_thread_mutex_lock( &c->c_mutex );
+ }
}
}
}
if ( op->o_cancel == SLAP_CANCEL_REQ ) {
- op->o_cancel = LDAP_TOO_LATE;
+ if ( rc == SLAPD_ABANDON )
+ op->o_cancel = SLAP_CANCEL_ACK;
+ else
+ op->o_cancel = LDAP_TOO_LATE;
}
while ( op->o_cancel != SLAP_CANCEL_NONE &&
op->o_cancel != SLAP_CANCEL_DONE )
ber_set_option( op->o_ber, LBER_OPT_BER_MEMCTX, &memctx_null );
-#if 0 /* DELETE ME */
- if ( op->o_cancel != SLAP_CANCEL_ACK &&
- ( op->o_sync_mode & SLAP_SYNC_PERSIST ) )
- {
- slap_sl_mem_detach( ctx, memctx );
- } else if ( op->o_sync_slog_size != -1 ) {
- slap_sl_mem_detach( ctx, memctx );
- LDAP_STAILQ_REMOVE( &conn->c_ops, op, slap_op, o_next);
- LDAP_STAILQ_NEXT(op, o_next) = NULL;
- conn->c_n_ops_executing--;
- conn->c_n_ops_completed++;
-
- } else
-#endif
- {
- LDAP_STAILQ_REMOVE( &conn->c_ops, op, slap_op, o_next);
- LDAP_STAILQ_NEXT(op, o_next) = NULL;
- slap_op_free( op );
- conn->c_n_ops_executing--;
- conn->c_n_ops_completed++;
- }
+ LDAP_STAILQ_REMOVE( &conn->c_ops, op, slap_op, o_next);
+ LDAP_STAILQ_NEXT(op, o_next) = NULL;
+ slap_op_free( op );
+ conn->c_n_ops_executing--;
+ conn->c_n_ops_completed++;
switch( tag ) {
case LBER_ERROR:
}
#endif
if(tag == LDAP_REQ_BIND) {
- /* immediately abandon all exiting operations upon BIND */
+ /* immediately abandon all existing operations upon BIND */
connection_abandon( conn );
}
if (!op->o_dn.bv_len) {
op->o_authz = op->o_conn->c_authz;
- ber_dupbv( &op->o_dn, &op->o_conn->c_dn );
- ber_dupbv( &op->o_ndn, &op->o_conn->c_ndn );
+ if ( BER_BVISNULL( &op->o_conn->c_sasl_authz_dn )) {
+ ber_dupbv( &op->o_dn, &op->o_conn->c_dn );
+ ber_dupbv( &op->o_ndn, &op->o_conn->c_ndn );
+ } else {
+ ber_dupbv( &op->o_dn, &op->o_conn->c_sasl_authz_dn );
+ ber_dupbv( &op->o_ndn, &op->o_conn->c_sasl_authz_dn );
+ }
}
op->o_authtype = op->o_conn->c_authtype;
ber_dupbv( &op->o_authmech, &op->o_conn->c_authmech );
int connection_write(ber_socket_t s)
{
Connection *c;
+ Operation *op;
assert( connections != NULL );
c = connection_get( s );
- slapd_clr_write( s, 0);
-
if( c == NULL ) {
Debug( LDAP_DEBUG_ANY,
"connection_write(%ld): no connection!\n",
return -1;
}
+ slapd_clr_write( s, 0);
+
c->c_n_write++;
Debug( LDAP_DEBUG_TRACE,
if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_WRITE, NULL ) ) {
slapd_set_write( s, 1 );
}
+ /* If there are ops pending because of a writewaiter, start
+ * one up.
+ */
+ while ((op = LDAP_STAILQ_FIRST( &c->c_pending_ops )) != NULL) {
+ if ( !c->c_writewaiter ) break;
+ if ( c->c_n_ops_executing > connection_pool_max/2 ) {
+ break;
+ }
+ LDAP_STAILQ_REMOVE_HEAD( &c->c_pending_ops, o_next );
+ LDAP_STAILQ_NEXT(op, o_next) = NULL;
+ /* pending operations should not be marked for abandonment */
+ assert(!op->o_abandon);
+
+ c->c_n_ops_pending--;
+ c->c_n_ops_executing++;
+
+ connection_op_activate( op );
+
+ break;
+ }
connection_return( c );
ldap_pvt_thread_mutex_unlock( &connections_mutex );
return 0;