]> git.sur5r.net Git - openldap/commitdiff
PROTOTYPE: New connection management infrastructure designed to
authorKurt Zeilenga <kurt@openldap.org>
Mon, 22 Mar 1999 07:14:54 +0000 (07:14 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Mon, 22 Mar 1999 07:14:54 +0000 (07:14 +0000)
remove race conditions on connection close.
BROKEN: various counters for dn=monitor.
Initial testing on FreeBSD (with and without pthreads) was successfull.
Have not yet tested preemptive threading environments.
Have not built against backends other than LDBM.

20 files changed:
servers/slapd/abandon.c
servers/slapd/acl.c
servers/slapd/add.c
servers/slapd/back-ldbm/dbcache.c
servers/slapd/back-ldbm/search.c
servers/slapd/bind.c
servers/slapd/connection.c
servers/slapd/daemon.c
servers/slapd/init.c
servers/slapd/main.c
servers/slapd/modify.c
servers/slapd/monitor.c
servers/slapd/operation.c
servers/slapd/proto-slap.h
servers/slapd/repl.c
servers/slapd/result.c
servers/slapd/slap.h
servers/slapd/tools/Makefile.in
servers/slapd/tools/mimic.c [new file with mode: 0644]
servers/slapd/unbind.c

index ea29321b3f15ab316a5ef7178227967008fbd878..4a55d34e118809b5b2d17ec3bde3cdb17107f117 100644 (file)
@@ -49,19 +49,28 @@ do_abandon(
         * flag and abort the operation at a convenient time.
         */
 
-       ldap_pvt_thread_mutex_lock( &conn->c_opsmutex );
+       ldap_pvt_thread_mutex_lock( &conn->c_mutex );
+
        for ( o = conn->c_ops; o != NULL; o = o->o_next ) {
+               if ( o->o_msgid == id )
+                       goto found_op;
+       }
+       for ( o = conn->c_pending_ops; o != NULL; o = o->o_next ) {
                if ( o->o_msgid == id )
                        break;
        }
 
+found_op:
+
        if ( o != NULL ) {
                ldap_pvt_thread_mutex_lock( &o->o_abandonmutex );
                o->o_abandon = 1;
                ldap_pvt_thread_mutex_unlock( &o->o_abandonmutex );
+
        } else {
                Debug( LDAP_DEBUG_TRACE, "do_abandon: op not found\n", 0, 0,
                    0 );
        }
-       ldap_pvt_thread_mutex_unlock( &conn->c_opsmutex );
+
+       ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
 }
index f029d3ccfd47b20005e9671cdef33d98c0fa6676..483aba6dd6bb8eb34416ead1410e80dab8d2a83e 100644 (file)
@@ -287,7 +287,9 @@ acl_access_allowed(
                        }
                }
                if ( b->a_addrpat != NULL ) {
-                       if ( regex_matches( b->a_addrpat, conn->c_addr, edn, matches ) ) {
+                       if ( regex_matches( b->a_addrpat, conn->c_client_addr,
+                               edn, matches ) )
+                       {
                                Debug( LDAP_DEBUG_ACL,
                                    "<= acl_access_allowed: matched by clause #%d access %s\n",
                                    i, (b->a_access & ~ACL_SELF) >= access ?
@@ -299,7 +301,8 @@ acl_access_allowed(
                if ( b->a_domainpat != NULL ) {
                        Debug( LDAP_DEBUG_ARGS, "<= check a_domainpath: %s\n",
                                b->a_domainpat, 0, 0 );
-                       if ( regex_matches( b->a_domainpat, conn->c_domain, edn, matches ) ) 
+                       if ( regex_matches( b->a_domainpat, conn->c_client_name,
+                               edn, matches ) ) 
                        {
                                Debug( LDAP_DEBUG_ACL,
                                    "<= acl_access_allowed: matched by clause #%d access %s\n",
index 7dcd020f920549314776e4d93e8f150b135a6811..16eed3a63c3313b57d98dddc2bdf09b3f05ab459 100644 (file)
@@ -151,6 +151,7 @@ add_created_attrs( Operation *op, Entry *e )
        Attribute       **a, **next;
        Attribute       *tmp;
        struct tm       *ltm;
+       time_t          currenttime;
 
        Debug( LDAP_DEBUG_TRACE, "add_created_attrs\n", 0, 0, 0 );
 
@@ -181,7 +182,8 @@ add_created_attrs( Operation *op, Entry *e )
        }
        attr_merge( e, "creatorsname", bvals );
 
-       ldap_pvt_thread_mutex_lock( &currenttime_mutex );
+       currenttime = slap_get_time();
+       ldap_pvt_thread_mutex_lock( &gmtime_mutex );
 #ifndef LDAP_LOCALTIME
        ltm = gmtime( &currenttime );
        strftime( buf, sizeof(buf), "%Y%m%d%H%M%SZ", ltm );
@@ -189,7 +191,7 @@ add_created_attrs( Operation *op, Entry *e )
        ltm = localtime( &currenttime );
        strftime( buf, sizeof(buf), "%y%m%d%H%M%SZ", ltm );
 #endif
-       ldap_pvt_thread_mutex_unlock( &currenttime_mutex );
+       ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
 
        bv.bv_val = buf;
        bv.bv_len = strlen( bv.bv_val );
index f563cb61c196215e5c5cb0b42f7bc219b9584fbf..58b7b8571d34c54ed4889bfb168e22f673dd455e 100644 (file)
@@ -41,9 +41,7 @@ ldbm_cache_open(
            flags, li->li_mode );
 
        lru = 0;
-       ldap_pvt_thread_mutex_lock( &currenttime_mutex );
-       curtime = currenttime;
-       ldap_pvt_thread_mutex_unlock( &currenttime_mutex );
+       curtime = slap_get_time();
        oldtime = curtime;
 
        ldap_pvt_thread_mutex_lock( &li->li_dbcache_mutex );
index 5def38a2b33b3f0c5f4e432ab5ee70d1f3f4a159..04e05931930dca8e1a949e167071657ea815e565 100644 (file)
@@ -139,6 +139,7 @@ ldbm_back_search(
        rcur = strchr( rbuf, '\0' );
        for ( id = idl_firstid( candidates ); id != NOID;
            id = idl_nextid( candidates, id ) ) {
+
                /* check for abandon */
                ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
                if ( op->o_abandon ) {
@@ -153,10 +154,7 @@ ldbm_back_search(
                ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
 
                /* check time limit */
-               ldap_pvt_thread_mutex_lock( &currenttime_mutex );
-               time( &currenttime );
-               if ( tlimit != -1 && currenttime > stoptime ) {
-                       ldap_pvt_thread_mutex_unlock( &currenttime_mutex );
+               if ( tlimit != -1 && slap_get_time() > stoptime ) {
                        send_ldap_search_result( conn, op,
                            LDAP_TIMELIMIT_EXCEEDED, NULL, nrefs > 0 ? rbuf :
                            NULL, nentries );
@@ -167,7 +165,6 @@ ldbm_back_search(
                        }
                        return( 0 );
                }
-               ldap_pvt_thread_mutex_unlock( &currenttime_mutex );
 
                /* get the entry with reader lock */
                if ( (e = id2entry_r( be, id )) == NULL ) {
index cf0b2af328eb65760cf0bdbc633c703acc35942a..223401aa1ba863f0b7ed0dfbe15dc997e8b6a329 100644 (file)
@@ -135,7 +135,7 @@ do_bind(
                        free( cred.bv_val );
                }
 
-               ldap_pvt_thread_mutex_lock( &conn->c_dnmutex );
+               ldap_pvt_thread_mutex_lock( &conn->c_mutex );
 
                conn->c_protocol = version;
 
@@ -149,7 +149,7 @@ do_bind(
                        conn->c_dn = NULL;
                }
 
-               ldap_pvt_thread_mutex_unlock( &conn->c_dnmutex );
+               ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
 
                send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL );
                return;
@@ -168,7 +168,7 @@ do_bind(
                        free( cred.bv_val );
                }
                if ( cred.bv_len == 0 ) {
-                       ldap_pvt_thread_mutex_lock( &conn->c_dnmutex );
+                       ldap_pvt_thread_mutex_lock( &conn->c_mutex );
 
                        conn->c_protocol = version;
 
@@ -182,7 +182,7 @@ do_bind(
                                conn->c_dn = NULL;
                        }
 
-                       ldap_pvt_thread_mutex_unlock( &conn->c_dnmutex );
+                       ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
 
                        send_ldap_result( conn, op, LDAP_SUCCESS,
                                NULL, NULL );
@@ -203,7 +203,7 @@ do_bind(
                ndn = suffixAlias( ndn, op, be );
 
                if ( (*be->be_bind)( be, conn, op, ndn, method, &cred, &edn ) == 0 ) {
-                       ldap_pvt_thread_mutex_lock( &conn->c_dnmutex );
+                       ldap_pvt_thread_mutex_lock( &conn->c_mutex );
 
                        conn->c_protocol = version;
 
@@ -228,7 +228,7 @@ do_bind(
                        Debug( LDAP_DEBUG_TRACE, "do_bind: bound \"%s\" to \"%s\"\n",
                        conn->c_cdn, conn->c_dn, method );
 
-                       ldap_pvt_thread_mutex_unlock( &conn->c_dnmutex );
+                       ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
 
                        /* send this here to avoid a race condition */
                        send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL );
index 75871477337b160daaa42905b991316ab66d4743..4f2a5cec0073a3806518c35b762cd18a5b7a8100 100644 (file)
 
 #include "slap.h"
 
+/* protected by connections_mutex */
+static ldap_pvt_thread_mutex_t connections_mutex;
+static Connection *connections = NULL;
+static int conn_index = -1;
+static long conn_nextid = 0;
+
+static Connection* connection_get( int s );
+
+static int connection_input( Connection *c );
+
 static int connection_op_activate( Connection *conn, Operation *op );
 static int connection_resched( Connection *conn );
 
@@ -18,6 +28,360 @@ struct co_arg {
        Operation       *co_op;
 };
 
+/*
+ * Initialize connection management infrastructure.
+ */
+int connections_init(void)
+{
+       int i;
+
+       assert( connections == NULL );
+
+       if( connections != NULL) { /* probably should assert this */
+               Debug( LDAP_DEBUG_ANY, "connections_init: already initialized.\n",
+                       0, 0, 0 );
+               return -1;
+       }
+
+       /* should check return of every call */
+       ldap_pvt_thread_mutex_init( &connections_mutex );
+
+       connections = (Connection *) calloc( dtblsize, sizeof(Connection) );
+
+       if( connections == NULL ) {
+               Debug( LDAP_DEBUG_ANY,
+                       "connections_init: allocation (%d*%ld) of connection array failed.\n",
+                       dtblsize, (long) sizeof(Connection), 0 );
+               return -1;
+       }
+
+       /*
+        * per entry initialization of the Connection array initialization
+        * will be done by connection_init()
+        */ 
+
+       return 0;
+}
+
+static Connection* connection_get( int s )
+{
+       Connection *c = NULL;
+
+       assert( connections != NULL );
+
+       if(s < 0) {
+               return NULL;
+       }
+
+#ifndef HAVE_WINSOCK
+       assert( connections[s].c_struct_state == SLAP_C_USED );
+       assert( connections[s].c_conn_state != SLAP_C_INVALID );
+       assert( connections[s].c_sb.sb_sd != -1 );
+
+       c = &connections[s];
+#else
+       {
+               int i;
+
+               for(i=0; i<dtblsize; i++) {
+                       if( connections[i].c_struct_state == SLAP_C_STRUCT_UNINITIALIZED ) {
+                               assert( connections[i].c_conn_state == SLAP_C_INVALID );
+                               assert( connections[s].c_sb.sb_sd == 0 );
+                               break;
+                       }
+
+                       if( connections[i].c_struct_state == SLAP_C_STRUCT_UNUSED ) {
+                               assert( connections[i].c_conn_state == SLAP_C_INVALID );
+                               assert( connections[s].c_sb.sb_sd == -1 );
+                               continue;
+                       }
+
+                       assert( connections[i].c_struct_state == SLAP_C_STRUCT_USED );
+                       assert( connections[i].c_conn_state != SLAP_C_INVALID );
+                       assert( connections[s].c_sb.sb_sd != -1 );
+
+                       if( connections[i].c_sb.sb_sd == s ) {
+                               c = &connections[s];
+                               break;
+                       }
+               }
+       }
+#endif
+       if( c != NULL ) {
+               ldap_pvt_thread_mutex_lock( &c->c_mutex );
+       }
+       return c;
+}
+
+static void connection_return( Connection *c )
+{
+       ldap_pvt_thread_mutex_unlock( &c->c_mutex );
+}
+
+long connection_init(
+       int s,
+       const char* name,
+       const char* addr)
+{
+       long id;
+       Connection *c;
+       assert( connections != NULL );
+
+       if( s < 0 ) {
+               return -1;
+       }
+
+       assert( s >= 0 );
+#ifndef HAVE_WINSOCK
+       assert( s < dtblsize );
+#endif
+
+       ldap_pvt_thread_mutex_lock( &connections_mutex );
+
+#ifndef HAVE_WINSOCK
+       c = &connections[s];
+
+#else
+       {
+               int i;
+
+               for( i=0; i < dtblsize; i++ {
+                       if( connections[i].c_struct_state == SLAP_C_UNINITIALIZED ) {
+                               assert( connections[i].c_sb.sb_sd == 0 );
+                               c = &connections[i];
+                               break;
+                       }
+
+                       if( connections[i].c_struct_state == SLAP_C_UNUSED ) {
+                               assert( connections[i].c_sb.sb_sd == -1 );
+                               c = &connections[i];
+                               break;
+                       }
+
+                       assert( connections[i].c_struct_state == SLAP_C_USED );
+                       assert( connections[i].c_conn_state != SLAP_C_INVALID );
+                       assert( connections[i].c_sb.sb_sd != -1 );
+               }
+
+               if( c == NULL ) {
+                       ldap_pvt_thread_mutex_unlock( &connections_mutex );
+                       return -1;
+               }
+       }
+#endif
+
+       assert( c != NULL );
+       assert( c->c_struct_state != SLAP_C_USED );
+       assert( c->c_conn_state == SLAP_C_INVALID );
+
+       if( c->c_struct_state == SLAP_C_UNINITIALIZED ) {
+               c->c_dn = NULL;
+               c->c_cdn = NULL;
+               c->c_client_name = NULL;
+               c->c_client_addr = NULL;
+               c->c_ops = NULL;
+               c->c_pending_ops = NULL;
+
+               lber_pvt_sb_init( &c->c_sb );
+
+               /* should check status of thread calls */
+               ldap_pvt_thread_mutex_init( &c->c_mutex );
+               ldap_pvt_thread_mutex_init( &c->c_write_mutex );
+               ldap_pvt_thread_cond_init( &c->c_write_cv );
+
+               c->c_struct_state = SLAP_C_UNUSED;
+       }
+
+       ldap_pvt_thread_mutex_lock( &c->c_mutex );
+
+       assert( c->c_struct_state == SLAP_C_UNUSED );
+       assert( c->c_dn == NULL );
+       assert( c->c_cdn == NULL );
+       assert( c->c_client_name == NULL );
+       assert( c->c_client_addr == NULL );
+       assert( c->c_ops == NULL );
+       assert( c->c_pending_ops == NULL );
+
+       c->c_client_name = ch_strdup( name == NULL ? "" : name );
+       c->c_client_addr = ch_strdup( addr );
+
+       c->c_n_ops_received = 0;
+#ifdef LDAP_COUNTERS
+       c->c_n_ops_executing = 0;
+       c->c_n_ops_pending = 0;
+       c->c_n_ops_completed = 0;
+#endif
+
+       c->c_starttime = slap_get_time();
+
+       lber_pvt_sb_set_desc( &c->c_sb, s );
+       lber_pvt_sb_set_io( &c->c_sb, &lber_pvt_sb_io_tcp, NULL );
+
+       if( lber_pvt_sb_set_nonblock( &c->c_sb, 1 ) < 0 ) {
+               Debug( LDAP_DEBUG_ANY,
+                       "connection_init(%d, %s, %s): set nonblocking failed\n",
+                       s, c->c_client_name, c->c_client_addr);
+       }
+
+       id = c->c_connid = conn_nextid++;
+
+       c->c_conn_state = SLAP_C_INACTIVE;
+       c->c_struct_state = SLAP_C_USED;
+
+       ldap_pvt_thread_mutex_unlock( &c->c_mutex );
+       ldap_pvt_thread_mutex_unlock( &connections_mutex );
+
+       return id;
+}
+
+static void
+connection_destroy( Connection *c )
+{
+       assert( connections != NULL );
+       assert( c != NULL );
+       assert( c->c_struct_state != SLAP_C_UNUSED );
+       assert( c->c_conn_state != SLAP_C_INVALID );
+       assert( c->c_ops == NULL );
+
+       c->c_struct_state = SLAP_C_UNUSED;
+       c->c_conn_state = SLAP_C_INVALID;
+
+       c->c_version = 0;
+       c->c_protocol = 0;
+
+       c->c_starttime = 0;
+
+       if(c->c_dn != NULL) {
+               free(c->c_dn);
+               c->c_dn = NULL;
+       }
+       if(c->c_cdn != NULL) {
+               free(c->c_cdn);
+               c->c_cdn = NULL;
+       }
+       if(c->c_client_name != NULL) {
+               free(c->c_client_name);
+               c->c_client_name = NULL;
+       }
+       if(c->c_client_addr != NULL) {
+               free(c->c_client_addr);
+               c->c_client_addr = NULL;
+       }
+
+       if ( lber_pvt_sb_in_use(&c->c_sb) ) {
+               int sd = lber_pvt_sb_get_desc(&c->c_sb);
+
+               slapd_remove( sd );
+               lber_pvt_sb_close( &c->c_sb );
+
+               Statslog( LDAP_DEBUG_STATS,
+                   "conn=%d fd=%d closed.\n",
+                       c->c_connid, sd, 0, 0, 0 );
+       }
+
+       lber_pvt_sb_destroy( &c->c_sb );
+}
+
+static void connection_close( Connection *c )
+{
+       assert( connections != NULL );
+       assert( c != NULL );
+       assert( c->c_struct_state == SLAP_C_USED );
+       assert( c->c_conn_state == SLAP_C_CLOSING );
+
+       if( c->c_ops != NULL ) {
+               Debug( LDAP_DEBUG_TRACE,
+                       "connection_close: deferring conn=%ld sd=%d.\n",
+                       c->c_connid, c->c_sb.sb_sd, 0 );
+
+               return;
+       }
+
+       Debug( LDAP_DEBUG_TRACE, "connection_close: conn=%ld sd=%d.\n",
+               c->c_connid, c->c_sb.sb_sd, 0 );
+
+       connection_destroy( c );
+}
+
+long connections_nextid(void)
+{
+       long id;
+       assert( connections != NULL );
+
+       ldap_pvt_thread_mutex_lock( &connections_mutex );
+
+       id = conn_nextid;
+
+       ldap_pvt_thread_mutex_unlock( &connections_mutex );
+
+       return id;
+}
+
+Connection* connection_first(void)
+{
+       assert( connections != NULL );
+
+       ldap_pvt_thread_mutex_lock( &connections_mutex );
+
+       assert( conn_index == -1 );
+       conn_index = 0;
+
+       return connection_next(NULL);
+}
+
+Connection* connection_next(Connection *c)
+{
+       assert( connections != NULL );
+       assert( conn_index != -1 );
+       assert( conn_index <= dtblsize );
+
+       if( c != NULL ) {
+               ldap_pvt_thread_mutex_unlock( &c->c_mutex );
+       }
+
+       c = NULL;
+
+       for(; conn_index < dtblsize; conn_index++) {
+               if( connections[conn_index].c_struct_state == SLAP_C_UNINITIALIZED ) {
+                       assert( connections[conn_index].c_conn_state == SLAP_C_INVALID );
+#ifndef HAVE_WINSOCK
+                       continue;
+#else
+                       break;
+#endif
+               }
+
+               if( connections[conn_index].c_struct_state == SLAP_C_USED ) {
+                       assert( connections[conn_index].c_conn_state != SLAP_C_INVALID );
+                       c = &connections[conn_index++];
+                       break;
+               }
+
+               assert( connections[conn_index].c_struct_state == SLAP_C_UNUSED );
+               assert( connections[conn_index].c_conn_state == SLAP_C_INVALID );
+       }
+
+       if( c != NULL ) {
+               ldap_pvt_thread_mutex_lock( &c->c_mutex );
+       }
+
+       return c;
+}
+
+void connection_done(Connection *c)
+{
+       assert( connections != NULL );
+       assert( conn_index != -1 );
+       assert( conn_index <= dtblsize );
+
+       if( c != NULL ) {
+               ldap_pvt_thread_mutex_unlock( &c->c_mutex );
+       }
+
+       conn_index = -1;
+       ldap_pvt_thread_mutex_unlock( &connections_mutex );
+}
+
 /*
  * connection_activity - handle the request operation op on connection
  * conn.  This routine figures out what kind of operation it is and
@@ -31,13 +395,11 @@ connection_operation( void *arg_v )
        int tag = arg->co_op->o_tag;
        Connection *conn = arg->co_conn;
 
-       ldap_pvt_thread_mutex_lock( &conn->c_opsmutex );
-       conn->c_ops_received++;
-       ldap_pvt_thread_mutex_unlock( &conn->c_opsmutex );
-
+#ifdef LDAP_COUNTERS
        ldap_pvt_thread_mutex_lock( &ops_mutex );
        ops_initiated++;
        ldap_pvt_thread_mutex_unlock( &ops_mutex );
+#endif
 
        switch ( tag ) {
        case LDAP_REQ_BIND:
@@ -91,12 +453,17 @@ connection_operation( void *arg_v )
                break;
        }
 
+#ifdef LDAP_COUNTERS
        ldap_pvt_thread_mutex_lock( &ops_mutex );
        ops_completed++;
        ldap_pvt_thread_mutex_unlock( &ops_mutex );
+#endif
+
+       ldap_pvt_thread_mutex_lock( &conn->c_mutex );
 
-       ldap_pvt_thread_mutex_lock( &conn->c_opsmutex );
+#ifdef LDAP_COUNTERS
        conn->c_ops_completed++;
+#endif
 
        slap_op_remove( &conn->c_ops, arg->co_op );
        slap_op_free( arg->co_op );
@@ -105,11 +472,27 @@ connection_operation( void *arg_v )
        free( (char *) arg );
        arg = NULL;
 
-       if((tag == LDAP_REQ_BIND) && (conn->c_state == SLAP_C_BINDING)) {
-               conn->c_state = SLAP_C_ACTIVE;
+       switch( tag ) {
+#ifdef LDAP_COMPAT30
+       case LDAP_REQ_UNBIND_30:
+#endif
+       case LDAP_REQ_UNBIND:
+               conn->c_conn_state = SLAP_C_CLOSING;
+               break;
+
+       case LDAP_REQ_BIND:
+               if( conn->c_conn_state == SLAP_C_BINDING) {
+                       conn->c_conn_state = SLAP_C_ACTIVE;
+               }
        }
 
-       ldap_pvt_thread_mutex_unlock( &conn->c_opsmutex );
+       if( conn->c_conn_state == SLAP_C_CLOSING ) {
+               Debug( LDAP_DEBUG_TRACE,
+                       "connection_operation: attempting closing conn=%ld sd=%d.\n",
+                       conn->c_connid, conn->c_sb.sb_sd, 0 );
+
+               connection_close( conn );
+       }
 
        ldap_pvt_thread_mutex_lock( &active_threads_mutex );
        active_threads--;
@@ -120,11 +503,58 @@ connection_operation( void *arg_v )
 
        connection_resched( conn );
 
+       ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+
        return NULL;
 }
 
-void
-connection_activity(
+int connection_read(int s)
+{
+       int rc = 0;
+       Connection *c;
+       assert( connections != NULL );
+
+       ldap_pvt_thread_mutex_lock( &connections_mutex );
+
+       c = connection_get( s );
+       if( c == NULL ) {
+               Debug( LDAP_DEBUG_ANY,
+                       "connection_read(%d): no connection!\n",
+                       s, 0, 0 );
+               return -1;
+       }
+
+       Debug( LDAP_DEBUG_TRACE,
+               "connection_read(%d): checking for input on id=%ld\n",
+               s, c->c_connid, 0 );
+
+#define CONNECTION_INPUT_LOOP 1
+
+#ifdef DATA_READY_LOOP
+       while(!rc && lber_pvt_sb_data_ready(&c->c_sb))
+#elif CONNECTION_INPUT_LOOP
+       while(!rc)
+#endif
+       {
+               rc = connection_input( c );
+       }
+
+       if( rc < 0 ) {
+               Debug( LDAP_DEBUG_TRACE,
+                       "connection_read(%d): input error id=%ld, closing.\n",
+                       s, c->c_connid, 0 );
+
+               c->c_conn_state = SLAP_C_CLOSING;
+               connection_close( c );
+       }
+
+       connection_return( c );
+       ldap_pvt_thread_mutex_unlock( &connections_mutex );
+       return 0;
+}
+
+static int
+connection_input(
     Connection *conn
 )
 {
@@ -136,30 +566,32 @@ connection_activity(
        if ( conn->c_currentber == NULL && (conn->c_currentber = ber_alloc())
            == NULL ) {
                Debug( LDAP_DEBUG_ANY, "ber_alloc failed\n", 0, 0, 0 );
-               return;
+               return -1;
        }
 
        errno = 0;
        if ( (tag = ber_get_next( &conn->c_sb, &len, conn->c_currentber ))
-           != LDAP_TAG_MESSAGE ) {
+           != LDAP_TAG_MESSAGE )
+       {
                Debug( LDAP_DEBUG_TRACE,
-                   "ber_get_next on fd %d failed errno %d (%s)\n",
-                   lber_pvt_sb_get_desc(&conn->c_sb), errno, errno > -1 && errno < sys_nerr ?
-                   sys_errlist[errno] : "unknown" );
-               Debug( LDAP_DEBUG_TRACE, "*** got %ld of %lu so far\n",
-                   (long)(conn->c_currentber->ber_rwptr - conn->c_currentber->ber_buf),
-                   conn->c_currentber->ber_len, 0 );
+                       "ber_get_next on fd %d failed errno %d (%s)\n",
+                       lber_pvt_sb_get_desc(&conn->c_sb), errno,
+                       errno > -1 && errno < sys_nerr ?  sys_errlist[errno] : "unknown" );
+               Debug( LDAP_DEBUG_TRACE, "\t*** got %ld of %lu so far\n",
+                       (long)(conn->c_currentber->ber_rwptr - conn->c_currentber->ber_buf),
+                       conn->c_currentber->ber_len, 0 );
 
                if ( errno != EWOULDBLOCK && errno != EAGAIN ) {
                        /* log, close and send error */
                        ber_free( conn->c_currentber, 1 );
                        conn->c_currentber = NULL;
 
-                       close_connection( conn, conn->c_connid, -1 );
+                       return -1;
                }
 
-               return;
+               return 1;
        }
+
        ber = conn->c_currentber;
        conn->c_currentber = NULL;
 
@@ -168,9 +600,7 @@ connection_activity(
                Debug( LDAP_DEBUG_ANY, "ber_get_int returns 0x%lx\n", tag, 0,
                    0 );
                ber_free( ber, 1 );
-
-               close_connection( conn, conn->c_connid, -1 );
-               return;
+               return -1;
        }
 
        if ( (tag = ber_peek_tag( ber, &len )) == LBER_ERROR ) {
@@ -179,8 +609,7 @@ connection_activity(
                    0 );
                ber_free( ber, 1 );
 
-               close_connection( conn, conn->c_connid, -1 );
-               return;
+               return -1;
        }
 
 #ifdef LDAP_COMPAT30
@@ -189,22 +618,27 @@ connection_activity(
        }
 #endif
 
-       op = slap_op_alloc( ber, msgid, tag,
-               conn->c_ops_received, conn->c_connid );
-
-       if ( conn->c_state == SLAP_C_BINDING ) {
-               /* connection is binding to a dn, make 'em wait */
-               ldap_pvt_thread_mutex_lock( &conn->c_opsmutex );
-               slap_op_add( &conn->c_pending_ops, op );
+       op = slap_op_alloc( ber, msgid, tag, conn->c_n_ops_received++ );
 
+       if ( conn->c_conn_state == SLAP_C_BINDING
+               || conn->c_conn_state == SLAP_C_CLOSING )
+       {
                Debug( LDAP_DEBUG_ANY, "deferring operation\n", 0, 0, 0 );
+               slap_op_add( &conn->c_pending_ops, op );
 
-               ldap_pvt_thread_mutex_unlock( &conn->c_opsmutex );
+       } else {
+               connection_op_activate( conn, op );
+       }
 
-               return;
+#ifdef NO_THREADS
+       if ( conn->c_struct_state != SLAP_C_USED ) {
+               /* connection must have got closed underneath us */
+               return 1;
        }
+#endif
+       assert( conn->c_struct_state == SLAP_C_USED );
 
-       connection_op_activate( conn, op );
+       return 0;
 }
 
 static int
@@ -212,29 +646,21 @@ connection_resched( Connection *conn )
 {
        Operation *op;
 
-       if( conn->c_state != SLAP_C_ACTIVE ) {
+       if( conn->c_conn_state != SLAP_C_ACTIVE ) {
                /* other states need different handling */
                return;
        }
 
-       ldap_pvt_thread_mutex_lock( &conn->c_opsmutex );
-
        for( op = slap_op_pop( &conn->c_pending_ops );
                op != NULL;
                op = slap_op_pop( &conn->c_pending_ops ) )
        {
-               ldap_pvt_thread_mutex_unlock( &conn->c_opsmutex );
-
                connection_op_activate( conn, op );
 
-               ldap_pvt_thread_mutex_lock( &conn->c_opsmutex );
-
-               if ( conn->c_state == SLAP_C_BINDING ) {
+               if ( conn->c_conn_state == SLAP_C_BINDING ) {
                        break;
                }
        }
-
-       ldap_pvt_thread_mutex_unlock( &conn->c_opsmutex );
 }
 
 static int connection_op_activate( Connection *conn, Operation *op )
@@ -244,13 +670,11 @@ static int connection_op_activate( Connection *conn, Operation *op )
        int status;
        unsigned long tag = op->o_tag;
 
-       ldap_pvt_thread_mutex_lock( &conn->c_dnmutex );
        if ( conn->c_dn != NULL ) {
                tmpdn = ch_strdup( conn->c_dn );
        } else {
                tmpdn = NULL;
        }
-       ldap_pvt_thread_mutex_unlock( &conn->c_dnmutex );
 
        arg = (struct co_arg *) ch_malloc( sizeof(struct co_arg) );
        arg->co_conn = conn;
@@ -259,16 +683,12 @@ static int connection_op_activate( Connection *conn, Operation *op )
        arg->co_op->o_dn = ch_strdup( tmpdn != NULL ? tmpdn : "" );
        arg->co_op->o_ndn = dn_normalize_case( ch_strdup( arg->co_op->o_dn ) );
 
-       ldap_pvt_thread_mutex_lock( &conn->c_opsmutex );
-
        slap_op_add( &conn->c_ops, arg->co_op );
 
        if(tag == LDAP_REQ_BIND) {
-               conn->c_state = SLAP_C_BINDING;
+               conn->c_conn_state = SLAP_C_BINDING;
        }
 
-       ldap_pvt_thread_mutex_unlock( &conn->c_opsmutex );
-
        if ( tmpdn != NULL ) {
                free( tmpdn );
        }
@@ -281,8 +701,37 @@ static int connection_op_activate( Connection *conn, Operation *op )
                                         connection_operation, (void *) arg );
 
        if ( status != 0 ) {
-               Debug( LDAP_DEBUG_ANY, "ldap_pvt_thread_create failed (%d)\n", status, 0, 0 );
+               Debug( LDAP_DEBUG_ANY,
+               "ldap_pvt_thread_create failed (%d)\n", status, 0, 0 );
+
+               /* should move op to pending list */
        }
 
        return status;
 }
+
+int connection_write(int s)
+{
+       Connection *c;
+       assert( connections != NULL );
+
+       ldap_pvt_thread_mutex_lock( &connections_mutex );
+
+       c = connection_get( s );
+       if( c == NULL ) {
+               Debug( LDAP_DEBUG_ANY,
+                       "connection_write(%d): no connection!\n",
+                       s, 0, 0 );
+               return -1;
+       }
+
+       Debug( LDAP_DEBUG_TRACE,
+               "connection_write(%d): waking output for id=%ld\n",
+               s, c->c_connid, 0 );
+
+       ldap_pvt_thread_cond_signal( &c->c_write_cv );
+
+       connection_return( c );
+       ldap_pvt_thread_mutex_unlock( &connections_mutex );
+       return 0;
+}
index 4596840b005c99385285656f93cc8cb2e51b024a..6294f4fb4ad29b896c0bd2dd5fe8e15e007ef8a0 100644 (file)
@@ -1,10 +1,3 @@
-
-/* Revision history
- *
- * 5-Jun-96    hodges
- *     Added locking of new_conn_mutex when traversing the c[] array.
- */
-
 #include "portable.h"
 
 #include <stdio.h>
@@ -33,26 +26,113 @@ int allow_severity = LOG_INFO;
 int deny_severity = LOG_NOTICE;
 #endif /* TCP Wrappers */
 
-int            dtblsize;
-Connection     *c;
+/* globals */
+int dtblsize;
 
+static ldap_pvt_thread_t       listener_tid;
 static volatile sig_atomic_t slapd_shutdown = 0;
 
-/* a link to the slapd.conf configuration parameters */
-extern char *slapd_pid_file;
-extern char *slapd_args_file;
+struct slap_daemon {
+       ldap_pvt_thread_mutex_t sd_mutex;
+
+       int sd_nactives;
+
+#ifndef HAVE_WINSOCK
+       /* In winsock, accept() returns values higher than dtblsize
+               so don't bother with this optimization */
+       int sd_nfds;
+#endif
+
+       fd_set sd_actives;
+       fd_set sd_readers;
+       fd_set sd_writers;
+} slap_daemon; 
+
+/*
+ * Add a descriptor to daemon control
+ */
+static void slapd_add(int s) {
+       ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
+
+       assert( !FD_ISSET( s, &slap_daemon.sd_actives ));
+       assert( !FD_ISSET( s, &slap_daemon.sd_readers ));
+       assert( !FD_ISSET( s, &slap_daemon.sd_writers ));
+
+       if (s >= slap_daemon.sd_nfds) {
+               slap_daemon.sd_nfds = s + 1;
+       }
+
+       FD_SET( s, &slap_daemon.sd_actives );
+       FD_SET( s, &slap_daemon.sd_readers );
+
+       Debug( LDAP_DEBUG_CONNS, "daemon: added %d%s%s\n", s,
+           FD_ISSET(s, &slap_daemon.sd_readers) ? "r" : "",
+               FD_ISSET(s, &slap_daemon.sd_writers) ? "w" : "" );
+
+       ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
+}
+
+/*
+ * Remove the descriptor from daemon control
+ */
+void slapd_remove(int s) {
+       ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
+
+       assert( s < slap_daemon.sd_nfds );
+       assert( FD_ISSET( s, &slap_daemon.sd_actives ));
+
+       Debug( LDAP_DEBUG_CONNS, "daemon: removing %d%s%s\n", s,
+           FD_ISSET(s, &slap_daemon.sd_readers) ? "r" : "",
+               FD_ISSET(s, &slap_daemon.sd_writers) ? "w" : "" );
+
+       FD_CLR( s, &slap_daemon.sd_actives );
+       FD_CLR( s, &slap_daemon.sd_readers );
+       FD_CLR( s, &slap_daemon.sd_writers );
+
+       ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
+}
+
+void slapd_clr_write(int s, int wake) {
+       ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
+
+       assert( s < slap_daemon.sd_nfds );
+       assert( FD_ISSET( s, &slap_daemon.sd_actives) );
+       assert( FD_ISSET( s, &slap_daemon.sd_writers) );
+       FD_SET( s, &slap_daemon.sd_writers );
+
+       ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
+
+       if( wake ) {
+               ldap_pvt_thread_kill( listener_tid, LDAP_SIGUSR1 );
+       }
+}
+
+void slapd_set_write(int s, int wake) {
+       ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
+
+       FD_SET( s, &slap_daemon.sd_writers );
+
+       ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
 
-void *
-slapd_daemon(
+       if( wake ) {
+               ldap_pvt_thread_kill( listener_tid, LDAP_SIGUSR1 );
+       }
+}
+
+static void slapd_close(int s) {
+       slapd_remove(s);
+
+       Debug( LDAP_DEBUG_CONNS, "daemon: closing %d\n", s, 0, 0 );
+       close(s);
+}
+
+static void *
+slapd_daemon_task(
        void *ptr
 )
 {
        struct sockaddr_in *addr = ptr;
-       int                     i;
-       int                     tcps, ns;
-       fd_set                  readfds;
-       fd_set                  writefds;
-       FILE                    *fp;
+       int     tcps = -1;
 
 #ifdef HAVE_SYSCONF
        dtblsize = sysconf( _SC_OPEN_MAX );
@@ -68,179 +148,201 @@ slapd_daemon(
        }
 #endif /* !FD_SETSIZE */
 
-       c = (Connection *) ch_calloc( (size_t) dtblsize, sizeof(Connection) );
-
-       for ( i = 0; i < dtblsize; i++ ) {
-               c[i].c_dn = NULL;
-               c[i].c_cdn = NULL;
-               c[i].c_addr = NULL;
-               c[i].c_domain = NULL;
-               c[i].c_ops = NULL;
-               lber_pvt_sb_init( &c[i].c_sb );
-               ldap_pvt_thread_mutex_init( &c[i].c_dnmutex );
-               ldap_pvt_thread_mutex_init( &c[i].c_opsmutex );
-               ldap_pvt_thread_mutex_init( &c[i].c_pdumutex );
-               ldap_pvt_thread_cond_init( &c[i].c_wcv );
-       }
+       connections_init();
 
-       if ( (tcps = socket( AF_INET, SOCK_STREAM, 0 )) == -1 ) {
-               Debug( LDAP_DEBUG_ANY, "socket() failed errno %d (%s)", errno,
-                   errno > -1 && errno < sys_nerr ? sys_errlist[errno] :
-                   "unknown", 0 );
-               exit( 1 );
-       }
+       ldap_pvt_thread_mutex_init( &slap_daemon.sd_mutex );
+       FD_ZERO( &slap_daemon.sd_readers );
+       FD_ZERO( &slap_daemon.sd_writers );
 
-       i = 1;
-       if ( setsockopt( tcps, SOL_SOCKET, SO_REUSEADDR, (char *) &i,
-           sizeof(i) ) == -1 ) {
-               Debug( LDAP_DEBUG_ANY, "setsockopt() failed errno %d (%s)",
-                   errno, errno > -1 && errno < sys_nerr ? sys_errlist[errno] :
-                   "unknown", 0 );
-       }
+       if( addr != NULL ) {
+               int     tmp;
 
-       if ( bind( tcps, (struct sockaddr *) addr, sizeof(*addr) ) == -1 ) {
-               Debug( LDAP_DEBUG_ANY, "bind() failed errno %d (%s)\n",
-                   errno, errno > -1 && errno < sys_nerr ? sys_errlist[errno] :
-                   "unknown", 0 );
-               exit( 1 );
-       }
+               if ( (tcps = socket( AF_INET, SOCK_STREAM, 0 )) == -1 ) {
+                       Debug( LDAP_DEBUG_ANY,
+                               "daemon: socket() failed errno %d (%s)", errno,
+                       errno > -1 && errno < sys_nerr ? sys_errlist[errno] :
+                       "unknown", 0 );
+                       exit( 1 );
+               }
 
-       if ( listen( tcps, 5 ) == -1 ) {
-               Debug( LDAP_DEBUG_ANY, "listen() failed errno %d (%s)",
-                   errno, errno > -1 && errno < sys_nerr ? sys_errlist[errno] :
-                   "unknown", 0 );
-               exit( 1 );
-       }
+#ifndef HAVE_WINSOCK
+               if ( tcps >= dtblsize ) {
+                       Debug( LDAP_DEBUG_ANY,
+                               "daemon: listener descriptor %d is too great",
+                               tcps, dtblsize, 0 );
+                       exit( 1 );
+               }
+#endif
 
-       Debug( LDAP_DEBUG_ANY, "slapd starting\n", 0, 0, 0 );
+               tmp = 1;
+               if ( setsockopt( tcps, SOL_SOCKET, SO_REUSEADDR,
+                       (char *) &tmp, sizeof(tmp) ) == -1 )
+               {
+                       Debug( LDAP_DEBUG_ANY,
+                               "slapd(%d): setsockopt() failed errno %d (%s)",
+                       tcps, errno,
+                               errno > -1 && errno < sys_nerr
+                                       ? sys_errlist[errno] : "unknown" );
+
+                       errno = 0;
+               }
 
-       if (( slapd_pid_file != NULL ) &&
-                       (( fp = fopen( slapd_pid_file, "w" )) != NULL )) {
-               fprintf( fp, "%d\n", (int) getpid() );
-               fclose( fp );
-       }
+               if ( bind( tcps, (struct sockaddr *) addr, sizeof(*addr) ) == -1 ) {
+                       Debug( LDAP_DEBUG_ANY, "daemon: bind(%d) failed errno %d (%s)\n",
+                       tcps, errno,
+                               errno > -1 && errno < sys_nerr
+                                       ? sys_errlist[errno] : "unknown" );
+                       exit( 1 );
+               }
+
+               if ( listen( tcps, 5 ) == -1 ) {
+                       Debug( LDAP_DEBUG_ANY,
+                               "daemon: listen(%d, 5) failed errno %d (%s)\n",
+                           tcps, errno,
+                               errno > -1 && errno < sys_nerr
+                                       ? sys_errlist[errno] : "unknown" );
+                       exit( 1 );
+               }
+
+               slapd_add( tcps );
 
-       if (( slapd_args_file != NULL ) &&
-                       (( fp = fopen( slapd_args_file, "w" )) != NULL )) {
-               for ( i = 0; i < g_argc; i++ ) {
-                       fprintf( fp, "%s ", g_argv[i] );
+       } else {
+               if( connection_init( 0, NULL, NULL ) ) {
+                       Debug( LDAP_DEBUG_ANY,
+                               "connection_init(%d) failed.\n",
+                               0, 0, 0 );
+
+                       exit( 1 );
                }
-               fprintf( fp, "\n" );
-               fclose( fp );
+
+               slapd_add( 0 );
        }
 
        while ( !slapd_shutdown ) {
+               int i, ns, nfds;
+
+               fd_set                  readfds;
+               fd_set                  writefds;
+
                struct sockaddr_in      from;
                struct hostent          *hp;
                struct timeval          zero;
                struct timeval          *tvp;
-               int                     len;
-               int                     data_ready;
 
                char    *client_name;
                char    *client_addr;
 
                FD_ZERO( &writefds );
                FD_ZERO( &readfds );
-               FD_SET( tcps, &readfds );
 
                zero.tv_sec = 0;
                zero.tv_usec = 0;
 
-               ldap_pvt_thread_mutex_lock( &active_threads_mutex );
-               Debug( LDAP_DEBUG_CONNS,
-                   "listening for connections on %d, activity on:",
-                   tcps, 0, 0 );
-          
-               data_ready = 0;
+               ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
 
-               ldap_pvt_thread_mutex_lock( &new_conn_mutex );
-               for ( i = 0; i < dtblsize; i++ ) {
-                       if ( (c[i].c_state != SLAP_C_INACTIVE)  
-                               && (c[i].c_state != SLAP_C_CLOSING) )
-                       {
-                               assert(lber_pvt_sb_in_use( &c[i].c_sb ));
-
-                               FD_SET( lber_pvt_sb_get_desc(&c[i].c_sb),
-                                       &readfds );
-                               if (lber_pvt_sb_data_ready(&c[i].c_sb))
-                                       data_ready = 1;
-                               if ( c[i].c_writewaiter ) {
-                                       FD_SET( lber_pvt_sb_get_desc(&c[i].c_sb),
-                                               &writefds );
-                               }
-                               Debug( LDAP_DEBUG_CONNS, " %dr%s", i,
-                                   c[i].c_writewaiter ? "w" : "", 0 );
+#ifdef FD_SET_MANUAL_COPY
+               for( s = 0; s < nfds; s++ ) {
+                       if(FD_ISSET( &slap_sd_writers, s )) {
+                               FD_SET( &writefds, s );
+                       }
+                       if(FD_ISSET( &slap_sd_writers, s )) {
+                               FD_SET( &writefds, s );
                        }
                }
+#else
+               memcpy( &readfds, &slap_daemon.sd_readers, sizeof(fd_set) );
+               memcpy( &writefds, &slap_daemon.sd_writers, sizeof(fd_set) );
+#endif
 
-               Debug( LDAP_DEBUG_CONNS, "\n", 0, 0, 0 );
-               ldap_pvt_thread_mutex_unlock( &new_conn_mutex );
+               FD_SET( tcps, &readfds );
+
+#ifndef HAVE_WINSOCK
+               nfds = slap_daemon.sd_nfds;
+#else
+               nfds = dtblsize;
+#endif
+
+               ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
 
-               Debug( LDAP_DEBUG_CONNS, "before select active_threads %d\n",
-                   active_threads, 0, 0 );
+               ldap_pvt_thread_mutex_lock( &active_threads_mutex );
 #if defined( HAVE_YIELDING_SELECT ) || defined( NO_THREADS )
-               tvp = (data_ready) ? &zero : NULL;
+               tvp = NULL;
 #else
-               tvp = (active_threads || data_ready) ? &zero : NULL;
+               tvp = active_threads ? &zero : NULL;
 #endif
+
+               Debug( LDAP_DEBUG_CONNS,
+                       "daemon: select: tcps=%d active_threads=%d tvp=%s\n",
+                   tcps, active_threads,
+                       tvp == NULL ? "NULL" : "zero" );
+          
+
                ldap_pvt_thread_mutex_unlock( &active_threads_mutex );
 
-               switch ( i = select( dtblsize, &readfds, &writefds, 0, tvp ) ) {
+               switch(ns = select( nfds, &readfds, &writefds, 0, tvp )) {
                case -1:        /* failure - try again */
-                       Debug( LDAP_DEBUG_CONNS,
-                           "select failed errno %d (%s)\n",
-                           errno, errno > -1 && errno < sys_nerr ?
-                           sys_errlist[errno] : "unknown", 0 );
+                       if( errno != EINTR ) {
+                               Debug( LDAP_DEBUG_CONNS,
+                                       "daemon: select failed (%d): %s\n",
+                                       errno,
+                                       errno >= 0 && errno < sys_nerr
+                                               ? sys_errlist[errno] : "unknown",
+                                       0 );
+
+                               slapd_shutdown = -1;
+                       }
+                       errno = 0;
                        continue;
 
                case 0:         /* timeout - let threads run */
-                       Debug( LDAP_DEBUG_CONNS, "select timeout - yielding\n",
+                       Debug( LDAP_DEBUG_CONNS, "daemon: select timeout - yielding\n",
                            0, 0, 0 );
-                       if (!data_ready)
-                               ldap_pvt_thread_yield();
+               ldap_pvt_thread_yield();
                        continue;
 
                default:        /* something happened - deal with it */
-                       Debug( LDAP_DEBUG_CONNS, "select activity on %d descriptors\n", i, 0, 0 );
-                       ;       /* FALL */
+                       Debug( LDAP_DEBUG_CONNS, "daemon: activity on %d descriptors\n",
+                               ns, 0, 0 );
+                       /* FALL THRU */
                }
-               ldap_pvt_thread_mutex_lock( &currenttime_mutex );
-               time( &currenttime );
-               ldap_pvt_thread_mutex_unlock( &currenttime_mutex );
 
-               /* new connection */
-               ldap_pvt_thread_mutex_lock( &new_conn_mutex );
+               slap_set_time();
+
                if ( FD_ISSET( tcps, &readfds ) ) {
-                       len = sizeof(from);
-                       if ( (ns = accept( tcps, (struct sockaddr *) &from,
-                           &len )) == -1 ) {
+                       int s;
+                       int len = sizeof(from);
+                       long id;
+
+                       if ( (s = accept( tcps,
+                               (struct sockaddr *) &from, &len )) == -1 )
+                       {
                                Debug( LDAP_DEBUG_ANY,
-                                   "accept() failed errno %d (%s)", errno,
-                                   errno > -1 && errno < sys_nerr ?
-                                   sys_errlist[errno] : "unknown", 0 );
-                               ldap_pvt_thread_mutex_unlock( &new_conn_mutex );
+                                   "daemon: accept(%d) failed errno %d (%s)", errno,
+                                   tcps, errno >= 0 && errno < sys_nerr ?
+                                   sys_errlist[errno] : "unknown");
                                continue;
                        }
 
+                       assert( !FD_ISSET( 0, &slap_daemon.sd_actives) );
+                       assert( !FD_ISSET( 0, &slap_daemon.sd_readers) );
+                       assert( !FD_ISSET( 0, &slap_daemon.sd_writers) );
+
+#ifndef HAVE_WINSOCK
                        /* make sure descriptor number isn't too great */
-                       if ( ns >= dtblsize ) {
+                       if ( s >= dtblsize ) {
                                Debug( LDAP_DEBUG_ANY,
-                                       "new connection on %d beyond descriptor table size %d\n",
-                                       ns, dtblsize, 0 );
-                               close(ns);
-                               ldap_pvt_thread_mutex_unlock( &new_conn_mutex );
+                                       "daemon: %d beyond descriptor table size %d\n",
+                                       s, dtblsize, 0 );
+                               close(s);
                                continue;
                        }
+#endif
                   
-                       Debug( LDAP_DEBUG_CONNS, "new connection on %d\n", ns,
-                           0, 0 );
+                       Debug( LDAP_DEBUG_CONNS, "daemon: new connection on %d\n",
+                               s, 0, 0 );
 
                        len = sizeof(from);
-
-                       if ( getpeername( ns, (struct sockaddr *) &from, &len )
-                           == 0 ) {
-                               char *s;
+                       if ( getpeername( s, (struct sockaddr *) &from, &len ) == 0 ) {
                                client_addr = inet_ntoa( from.sin_addr );
 
 #if defined(SLAPD_RLOOKUPS) || defined(HAVE_TCPD)
@@ -249,11 +351,12 @@ slapd_daemon(
                                    sizeof(from.sin_addr.s_addr), AF_INET );
 
                                if(hp) {
+                                       char *p;
                                        client_name = hp->h_name;
 
                                        /* normalize the domain */
-                                       for ( s = client_name; *s; s++ ) {
-                                               *s = TOLOWER( (unsigned char) *s );
+                                       for ( p = client_name; *p; p++ ) {
+                                               *p = TOLOWER( (unsigned char) *p );
                                        }
 
                                } else {
@@ -277,72 +380,42 @@ slapd_daemon(
                                /* DENY ACCESS */
                                Statslog( LDAP_DEBUG_ANY,
                                 "fd=%d connection from %s (%s) denied.\n",
-                                       ns,
-                                               client_name == NULL ? "unknown" : client_name,
-                                               client_addr == NULL ? "unknown" : client_addr,
+                                       s,
+                                       client_name == NULL ? "unknown" : client_name,
+                                       client_addr == NULL ? "unknown" : client_addr,
                                  0, 0 );
 
-                               ldap_pvt_thread_mutex_unlock( &new_conn_mutex );
+                               close(s);
                                continue;
                        }
 #endif /* HAVE_TCPD */
 
-
-                       ldap_pvt_thread_mutex_lock( &ops_mutex );
-                       c[ns].c_connid = num_conns++;
-                       ldap_pvt_thread_mutex_unlock( &ops_mutex );
-
-                       Statslog( LDAP_DEBUG_STATS,
-                           "conn=%d fd=%d connection from %s (%s) accepted.\n",
-                               c[ns].c_connid, ns,
+                       if( (id = connection_init(s, client_name, client_addr)) < 0 ) {
+                               Debug( LDAP_DEBUG_ANY,
+                                       "daemon: connection_init(%d, %s, %s) failed.\n",
+                                       s,
                                        client_name == NULL ? "unknown" : client_name,
-                                       client_addr == NULL ? "unknown" : client_addr,
-                            0 );
-
-                       if ( c[ns].c_addr != NULL ) {
-                               free( c[ns].c_addr );
-                       }
-                       c[ns].c_addr = ch_strdup( client_addr );
-
-                       if ( c[ns].c_domain != NULL ) {
-                               free( c[ns].c_domain );
-                       }
-
-                       c[ns].c_domain = ch_strdup( client_name == NULL
-                               ? "" : client_name );
-
-                       ldap_pvt_thread_mutex_lock( &c[ns].c_dnmutex );
-                       if ( c[ns].c_dn != NULL ) {
-                               free( c[ns].c_dn );
-                               c[ns].c_dn = NULL;
-                       }
-                       if ( c[ns].c_cdn != NULL ) {
-                               free( c[ns].c_cdn );
-                               c[ns].c_cdn = NULL;
+                                       client_addr == NULL ? "unknown" : client_addr);
+                               close(s);
+                               continue;
                        }
-                       ldap_pvt_thread_mutex_unlock( &c[ns].c_dnmutex );
 
-                       c[ns].c_starttime = currenttime;
-                       c[ns].c_ops_received = 0;
-                       c[ns].c_ops_executing = 0;
-                       c[ns].c_ops_pending = 0;
-                       c[ns].c_ops_completed = 0;
-
-                       lber_pvt_sb_set_desc( &c[ns].c_sb, ns );
-                       lber_pvt_sb_set_io( &c[ns].c_sb, &lber_pvt_sb_io_tcp, NULL );
-                  
-                       if (lber_pvt_sb_set_nonblock( &c[ns].c_sb, 1)<0) {                         
-                               Debug( LDAP_DEBUG_ANY,
-                                   "FIONBIO ioctl on %d failed\n", ns, 0, 0 );
-                       }
+                       Statslog( LDAP_DEBUG_STATS,
+                               "daemon: conn=%d fd=%d connection from %s (%s) accepted.\n",
+                               id, s,
+                               client_name == NULL ? "unknown" : client_name,
+                               client_addr == NULL ? "unknown" : client_addr,
+                               0 );
 
-                       c[ns].c_state = SLAP_C_ACTIVE;
+                       slapd_add( s );
+                       continue;
                }
-               ldap_pvt_thread_mutex_unlock( &new_conn_mutex );
 
-               Debug( LDAP_DEBUG_CONNS, "activity on:", 0, 0, 0 );
-               for ( i = 0; i < dtblsize; i++ ) {
-                       int     r, w;
+#ifdef LDAP_DEBUG
+               Debug( LDAP_DEBUG_CONNS, "daemon: activity on:", 0, 0, 0 );
+
+               for ( i = 0; i < nfds; i++ ) {
+                       int     a, r, w;
 
                        r = FD_ISSET( i, &readfds );
                        w = FD_ISSET( i, &writefds );
@@ -351,42 +424,70 @@ slapd_daemon(
                                    r ? "r" : "", w ? "w" : "" );
                        }
                }
+
                Debug( LDAP_DEBUG_CONNS, "\n", 0, 0, 0 );
+#endif
 
-               for ( i = 0; i < dtblsize; i++ ) {
-                       if ( i == tcps || (! FD_ISSET( i, &readfds ) &&
-                           ! FD_ISSET( i, &writefds )) ) {
+               /* loop through the writers */
+               for ( i = 0; i < nfds; i++ ) {
+                       if ( i == tcps ) {
                                continue;
                        }
 
                        if ( FD_ISSET( i, &writefds ) ) {
                                Debug( LDAP_DEBUG_CONNS,
-                                   "signaling write waiter on %d\n", i, 0, 0 );
+                                   "daemon: signaling write waiter on %d\n", i, 0, 0 );
+
+                               assert( FD_ISSET( 0, &slap_daemon.sd_actives) );
 
-                               ldap_pvt_thread_mutex_lock( &active_threads_mutex );
-                               active_threads++;
-                               c[i].c_writewaiter = 0;
-                               ldap_pvt_thread_cond_signal( &c[i].c_wcv );
-                               ldap_pvt_thread_mutex_unlock( &active_threads_mutex );
+                               /* clear the write flag */
+                               slapd_clr_write( i, 0 );
+                               
+                               if( connection_write( i ) < 0 ) { 
+                                       FD_CLR( i, &readfds );
+                                       slapd_close( i );
+                               }
+                       }
+               }
+
+               for ( i = 0; i < nfds; i++ ) {
+                       if ( i == tcps ) {
+                               continue;
                        }
 
-                       if ( FD_ISSET( i, &readfds ) || 
-                               lber_pvt_sb_data_ready( &c[i].c_sb ) ) {
+                       if ( FD_ISSET( i, &readfds ) ) {
                                Debug( LDAP_DEBUG_CONNS,
-                                   "read activity on %d\n", i, 0, 0 );
+                                   "daemon: read activity on %d\n", i, 0, 0 );
+
+                               assert( FD_ISSET( i, &slap_daemon.sd_actives) );
 
-                               connection_activity( &c[i] );
+                               if( connection_read( i ) < 0) {
+                                       slapd_close( i );
+                               }
                        }
                }
 
                ldap_pvt_thread_yield();
        }
 
-       Debug( LDAP_DEBUG_TRACE,
-           "slapd shutdown: shutdown initiated.\n",
-           0, 0, 0 );
+       if( slapd_shutdown > 0 ) {
+               Debug( LDAP_DEBUG_TRACE,
+                       "daemon: shutdown requested and initiated.\n",
+                       0, 0, 0 );
+
+       } else if ( slapd_shutdown < 0 ) {
+               Debug( LDAP_DEBUG_TRACE,
+                       "daemon: abnormal condition, shutdown initiated.\n",
+                       0, 0, 0 );
+       } else {
+               Debug( LDAP_DEBUG_TRACE,
+                       "daemon: no active streams, shutdown initiated.\n",
+                       0, 0, 0 );
+       }
 
-       close( tcps );
+       if( tcps >= 0 ) {
+               close( tcps );
+       }
 
        ldap_pvt_thread_mutex_lock( &active_threads_mutex );
        Debug( LDAP_DEBUG_ANY,
@@ -400,10 +501,28 @@ slapd_daemon(
        return NULL;
 }
 
+int slapd_daemon( struct sockaddr_in *addr )
+{
+       int status;
+
+       status = ldap_pvt_thread_create( &listener_tid, 0,
+                slapd_daemon_task, addr );
+
+       if ( status != 0 ) {
+               Debug( LDAP_DEBUG_ANY,
+                   "listener ldap_pvt_thread_create failed (%d)\n", status, 0, 0 );
+               return -1;
+       } else {
+               /* wait for the listener thread to complete */
+               ldap_pvt_thread_join( listener_tid, (void *) NULL );
+       }
+
+       return 0;
+}
+
 void
 slap_set_shutdown( int sig )
 {
-       Debug( LDAP_DEBUG_ANY, "slapd got shutdown signal %d\n", sig, 0, 0 );
        slapd_shutdown = 1;
        ldap_pvt_thread_kill( listener_tid, LDAP_SIGUSR1 );
 
@@ -414,8 +533,6 @@ slap_set_shutdown( int sig )
 void
 slap_do_nothing( int sig )
 {
-       Debug( LDAP_DEBUG_TRACE, "slapd got do_nothing signal %d\n", sig, 0, 0 );
-
        /* reinstall self */
        (void) SIGNAL( sig, slap_do_nothing );
 }
index dca72737b5b6b507eb64a1fa02ae9f7fa9b490a4..f464c61e93d0c483dfea2f551a2e4e9941aef734 100644 (file)
@@ -8,7 +8,6 @@
 #include <ac/string.h>
 #include <ac/time.h>
 
-#include "portable.h"
 #include "slap.h"
 
 /*
@@ -25,8 +24,6 @@ int           ldap_syslog;
 
 int            ldap_syslog_level = LOG_DEBUG;
 char           *default_referral;
-time_t         starttime;
-ldap_pvt_thread_t      listener_tid;
 int            g_argc;
 char           **g_argv;
 
@@ -37,11 +34,7 @@ int                          active_threads;
 ldap_pvt_thread_mutex_t        active_threads_mutex;
 ldap_pvt_thread_cond_t active_threads_cond;
 
-time_t                 currenttime;
-ldap_pvt_thread_mutex_t        currenttime_mutex;
-
-ldap_pvt_thread_mutex_t        new_conn_mutex;
-
+ldap_pvt_thread_mutex_t        gmtime_mutex;
 #ifdef SLAPD_CRYPT
 ldap_pvt_thread_mutex_t        crypt_mutex;
 #endif
@@ -64,6 +57,9 @@ ldap_pvt_thread_mutex_t       replog_mutex;
 static char* slap_name;
 int slapMode = SLAP_UNDEFINED_MODE;
 
+static time_t                  currenttime;
+static ldap_pvt_thread_mutex_t currenttime_mutex;
+
 int
 slap_init( int mode, char *name )
 {
@@ -98,12 +94,13 @@ slap_init( int mode, char *name )
                        ldap_pvt_thread_mutex_init( &active_threads_mutex );
                        ldap_pvt_thread_cond_init( &active_threads_cond );
 
-                       ldap_pvt_thread_mutex_init( &new_conn_mutex );
                        ldap_pvt_thread_mutex_init( &currenttime_mutex );
                        ldap_pvt_thread_mutex_init( &entry2str_mutex );
                        ldap_pvt_thread_mutex_init( &replog_mutex );
                        ldap_pvt_thread_mutex_init( &ops_mutex );
                        ldap_pvt_thread_mutex_init( &num_sent_mutex );
+
+                       ldap_pvt_thread_mutex_init( &gmtime_mutex );
 #ifdef SLAPD_CRYPT
                        ldap_pvt_thread_mutex_init( &crypt_mutex );
 #endif
@@ -162,3 +159,20 @@ int slap_destroy(void)
        return rc;
 }
 
+/* should create a utils.c for these */
+
+void slap_set_time(void)
+{
+       ldap_pvt_thread_mutex_lock( &currenttime_mutex );
+       time( &currenttime );
+       ldap_pvt_thread_mutex_unlock( &currenttime_mutex );
+}
+
+time_t slap_get_time(void)
+{
+       time_t t;
+       ldap_pvt_thread_mutex_lock( &currenttime_mutex );
+       t = currenttime;
+       ldap_pvt_thread_mutex_unlock( &currenttime_mutex );
+       return t;
+}
index f7b446939072e727445bbd64dc8de1ab8cce477b..5cbe8101933410927a19947aea20e1c2239a3001 100644 (file)
@@ -56,13 +56,15 @@ usage( char *name )
     fprintf( stderr, "\n" );
 }
 
+time_t starttime;
+
 int
 main( int argc, char **argv )
 {
        int             i;
        int             inetd = 0;
-       int             rc = 0;
-       struct sockaddr_in      bind_addr;
+       int             status, rc;
+       struct sockaddr_in      bind_addr, *slapd_addr;
        int             udp;
 #ifdef LOG_LOCAL4
     int     syslogUser = DEFAULT_SYSLOG_USER;
@@ -207,130 +209,61 @@ main( int argc, char **argv )
                goto destroy;
        }
 
-       if ( slap_startup(-1)  != 0 ) {
-               rc = 1;
-               goto shutdown;
-       }
-
-       if ( ! inetd ) {
-               int             status;
-
-               (void) SIGNAL( LDAP_SIGUSR1, slap_do_nothing );
-               (void) SIGNAL( LDAP_SIGUSR2, slap_set_shutdown );
+       (void) SIGNAL( LDAP_SIGUSR1, slap_do_nothing );
+       (void) SIGNAL( LDAP_SIGUSR2, slap_set_shutdown );
 #ifdef SIGPIPE
-               (void) SIGNAL( SIGPIPE, SIG_IGN );
+       (void) SIGNAL( SIGPIPE, SIG_IGN );
 #endif
 #ifdef SIGHUP
-               (void) SIGNAL( SIGHUP, slap_set_shutdown );
+       (void) SIGNAL( SIGHUP, slap_set_shutdown );
 #endif
-               (void) SIGNAL( SIGINT, slap_set_shutdown );
-               (void) SIGNAL( SIGTERM, slap_set_shutdown );
+       (void) SIGNAL( SIGINT, slap_set_shutdown );
+       (void) SIGNAL( SIGTERM, slap_set_shutdown );
 
+       if(!inetd) {
 #ifdef LDAP_DEBUG
                lutil_detach( ldap_debug, 0 );
 #else
                lutil_detach( 0, 0 );
 #endif
+       }
 
-               time( &starttime );
+       if ( slap_startup(-1)  != 0 ) {
+               rc = 1;
+               goto shutdown;
+       }
 
-               status = ldap_pvt_thread_create( &listener_tid, 0,
-                                                slapd_daemon, &bind_addr );
-               if ( status != 0 )
-               {
-                       Debug( LDAP_DEBUG_ANY,
-                           "listener ldap_pvt_thread_create failed (%d)\n", status, 0, 0 );
+       if(!inetd) {
+               FILE *fp;
 
-                       rc = 1;
+               slapd_addr = &bind_addr;
 
-               } else {
-                       /* wait for the listener thread to complete */
-                       ldap_pvt_thread_join( listener_tid, (void *) NULL );
-               }
+               Debug( LDAP_DEBUG_ANY, "slapd starting\n", 0, 0, 0 );
 
-       } else {
-               Connection              c;
-               BerElement              ber;
-               unsigned long           len, tag;
-               long                    msgid;
-               int                     flen;
-               struct sockaddr_in      from;
-               struct hostent          *hp;
-
-               c.c_dn = NULL;
-               c.c_cdn = NULL;
-               c.c_ops = NULL;
-          
-               lber_pvt_sb_init( &c.c_sb );
-               lber_pvt_sb_set_desc( &c.c_sb, 0 );
-               lber_pvt_sb_set_io( &c.c_sb, 
-                       (udp) ? &lber_pvt_sb_io_udp : &lber_pvt_sb_io_tcp, 
-                       NULL );
-               /* FIXME: handle udp here */
-
-               ldap_pvt_thread_mutex_init( &c.c_dnmutex );
-               ldap_pvt_thread_mutex_init( &c.c_opsmutex );
-               ldap_pvt_thread_mutex_init( &c.c_pdumutex );
-#ifdef notdefcldap
-               c.c_sb.sb_addrs = (void **) saddrlist;
-               c.c_sb.sb_fromaddr = &faddr;
-               c.c_sb.sb_useaddr = saddrlist[ 0 ] = &saddr;
-#endif
-               flen = sizeof(from);
-               if ( getpeername( 0, (struct sockaddr *) &from, &flen ) == 0 ) {
-#ifdef SLAPD_RLOOKUPS
-                       hp = gethostbyaddr( (char *) &(from.sin_addr.s_addr),
-                           sizeof(from.sin_addr.s_addr), AF_INET );
-#else
-                       hp = NULL;
-#endif
-
-                       Debug( LDAP_DEBUG_ARGS, "connection from %s (%s)\n",
-                           hp == NULL ? "unknown" : hp->h_name,
-                           inet_ntoa( from.sin_addr ), 0 );
-
-                       c.c_addr = inet_ntoa( from.sin_addr );
-                       c.c_domain = ch_strdup( hp == NULL ? "" : hp->h_name );
-               } else {
-                       Debug( LDAP_DEBUG_ARGS, "connection from unknown\n",
-                           0, 0, 0 );
+               if (( slapd_pid_file != NULL ) &&
+                       (( fp = fopen( slapd_pid_file, "w" )) != NULL ))
+               {
+                       fprintf( fp, "%d\n", (int) getpid() );
+                       fclose( fp );
                }
 
-               c.c_state = SLAP_C_ACTIVE;
-
-               ber_init_w_nullc( &ber, 0 );
-
-               while ( (tag = ber_get_next( &c.c_sb, &len, &ber ))
-                   == LDAP_TAG_MESSAGE ) {
-                       ldap_pvt_thread_mutex_lock( &currenttime_mutex );
-                       time( &currenttime );
-                       ldap_pvt_thread_mutex_unlock( &currenttime_mutex );
-
-                       if ( (tag = ber_get_int( &ber, &msgid ))
-                           != LDAP_TAG_MSGID ) {
-                               /* log and send error */
-                               Debug( LDAP_DEBUG_ANY,
-                                  "ber_get_int returns 0x%lx\n", tag, 0, 0 );
-                               ber_free( &ber, 1 );
-                               return 1;
+               if (( slapd_args_file != NULL ) &&
+                       (( fp = fopen( slapd_args_file, "w" )) != NULL ))
+               {
+                       for ( i = 0; i < g_argc; i++ ) {
+                               fprintf( fp, "%s ", g_argv[i] );
                        }
+                       fprintf( fp, "\n" );
+                       fclose( fp );
+               }
 
-                       if ( (tag = ber_peek_tag( &ber, &len ))
-                           == LBER_ERROR ) {
-                               /* log, close and send error */
-                               Debug( LDAP_DEBUG_ANY,
-                                  "ber_peek_tag returns 0x%lx\n", tag, 0, 0 );
-                               ber_free( &ber, 1 );
-                               lber_pvt_sb_close( &c.c_sb );
-                               lber_pvt_sb_destroy( &c.c_sb );
-                               return 1;
-                       }
+       } else {
+               slapd_addr = NULL;
+       }
 
-                       connection_activity( &c );
+       time( &starttime );
 
-                       ber_free( &ber, 1 );
-               }
-       }
+       rc = slapd_daemon( slapd_addr );
 
 shutdown:
        /* remember an error during shutdown */
index 918c97a2787ab2a3b6752f1173bf3c4e7476da37..c3b5fc9cc84629c5d1f6961ddbb5bd2a8f45c56f 100644 (file)
@@ -206,6 +206,7 @@ add_lastmods( Operation *op, LDAPModList **modlist )
        LDAPModList             **m;
        LDAPModList             *tmp;
        struct tm       *ltm;
+       time_t          currenttime;
 
        Debug( LDAP_DEBUG_TRACE, "add_lastmods\n", 0, 0, 0 );
 
@@ -249,7 +250,8 @@ add_lastmods( Operation *op, LDAPModList **modlist )
        tmp->ml_next = *modlist;
        *modlist = tmp;
 
-       ldap_pvt_thread_mutex_lock( &currenttime_mutex );
+       currenttime = slap_get_time();
+       ldap_pvt_thread_mutex_lock( &gmtime_mutex );
 #ifndef LDAP_LOCALTIME
        ltm = gmtime( &currenttime );
        strftime( buf, sizeof(buf), "%Y%m%d%H%M%SZ", ltm );
@@ -257,7 +259,8 @@ add_lastmods( Operation *op, LDAPModList **modlist )
        ltm = localtime( &currenttime );
        strftime( buf, sizeof(buf), "%y%m%d%H%M%SZ", ltm );
 #endif
-       ldap_pvt_thread_mutex_unlock( &currenttime_mutex );
+       ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
+
        bv.bv_val = buf;
        bv.bv_len = strlen( bv.bv_val );
        tmp = (LDAPModList *) ch_calloc( 1, sizeof(LDAPModList) );
index 5554d81c3db567b8f479abf007f539a08f911ca0..65594af1833076b6533f1125c4047d8c1fd08a19 100644 (file)
  * is provided ``as is'' without express or implied warranty.
  */
 
-/* Revision history
- *
- * 5-Jun-96    jeff.hodges@stanford.edu
- *     Added locking of new_conn_mutex when traversing the c[] array.
- *     Added locking of currenttime_mutex to protect call(s) to localtime().
- */
-
 #include "portable.h"
 
 #include <stdio.h>
@@ -40,6 +33,8 @@ monitor_info( Connection *conn, Operation *op )
        int             i, nconns, nwritewaiters, nreadwaiters;
        struct tm       *ltm;
        char            *p;
+       Connection *c;
+       time_t          currenttime;
 
        vals[0] = &val;
        vals[1] = NULL;
@@ -59,7 +54,9 @@ monitor_info( Connection *conn, Operation *op )
        }
        attr_merge( e, "version", vals );
 
+       ldap_pvt_thread_mutex_lock( &active_threads_mutex );
        sprintf( buf, "%d", active_threads );
+       ldap_pvt_thread_mutex_unlock( &active_threads_mutex );
        val.bv_val = buf;
        val.bv_len = strlen( buf );
        attr_merge( e, "threads", vals );
@@ -68,49 +65,49 @@ monitor_info( Connection *conn, Operation *op )
        nwritewaiters = 0;
        nreadwaiters = 0;
 
-       ldap_pvt_thread_mutex_lock( &new_conn_mutex );
-       for ( i = 0; i < dtblsize; i++ ) {
-               if ( lber_pvt_sb_in_use(&(c[i].c_sb)) ) {
-                       nconns++;
-                       if ( c[i].c_writewaiter ) {
-                               nwritewaiters++;
-                       }
-                       if ( c[i].c_gettingber ) {
-                               nreadwaiters++;
-                       }
-                       ldap_pvt_thread_mutex_lock( &currenttime_mutex );
+#ifdef LDAP_COUNTERS
+       /* loop through the connections */
+       for ( c = connection_first() ; c != NULL;  c = connection_next(c) ) {
+               nconns++;
+               if ( c->c_writewaiter ) {
+                       nwritewaiters++;
+               }
+               if ( c->c_currentber != NULL ) {
+                       nreadwaiters++;
+               }
+
+               ldap_pvt_thread_mutex_lock( &gmtime_mutex );
 #ifndef LDAP_LOCALTIME
-                       ltm = gmtime( &c[i].c_starttime );
-                       strftime( buf2, sizeof(buf2), "%Y%m%d%H%M%SZ", ltm );
+               ltm = gmtime( &c->c_starttime );
+               strftime( buf2, sizeof(buf2), "%Y%m%d%H%M%SZ", ltm );
 #else
-                       ltm = localtime( &c[i].c_starttime );
-                       strftime( buf2, sizeof(buf2), "%y%m%d%H%M%SZ", ltm );
+               ltm = localtime( &c->.c_starttime );
+               strftime( buf2, sizeof(buf2), "%y%m%d%H%M%SZ", ltm );
 #endif
-                       ldap_pvt_thread_mutex_unlock( &currenttime_mutex );
-
-                       ldap_pvt_thread_mutex_lock( &c[i].c_dnmutex );
-                       sprintf( buf, "%d : %s : %d : %d : %s : %s%s%s%s", i,
-                           buf2, c[i].c_ops_received, c[i].c_ops_completed,
-                           c[i].c_cdn ? c[i].c_cdn : "NULLDN",
-                           c[i].c_gettingber ? "r" : "",
-                           c[i].c_writewaiter ? "w" : "",
-                           c[i].c_ops_executing ? "x" : "",
-                           c[i].c_ops_pending ? "p" : ""
-                       );
-                       ldap_pvt_thread_mutex_unlock( &c[i].c_dnmutex );
-                       val.bv_val = buf;
-                       val.bv_len = strlen( buf );
-                       attr_merge( e, "connection", vals );
-               }
+               ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
+
+               sprintf( buf, "%d : %s : %d : %d : %s : %s%s%s%s", i,
+                   buf2, c[i].c_ops_received, c[i].c_ops_completed,
+                   c[i].c_cdn ? c[i].c_cdn : "NULLDN",
+                   c[i].c_gettingber ? "r" : "",
+                   c[i].c_writewaiter ? "w" : "",
+                   c[i].c_ops_executing ? "x" : "",
+                   c[i].c_ops_pending ? "p" : ""
+               );
+
+               val.bv_val = buf;
+               val.bv_len = strlen( buf );
+               attr_merge( e, "connection", vals );
        }
-       ldap_pvt_thread_mutex_unlock( &new_conn_mutex );
+       connection_done(c);
+#endif
 
        sprintf( buf, "%d", nconns );
        val.bv_val = buf;
        val.bv_len = strlen( buf );
        attr_merge( e, "currentconnections", vals );
 
-       sprintf( buf, "%d", num_conns );
+       sprintf( buf, "%ld", connections_nextid() );
        val.bv_val = buf;
        val.bv_len = strlen( buf );
        attr_merge( e, "totalconnections", vals );
@@ -130,6 +127,7 @@ monitor_info( Connection *conn, Operation *op )
        val.bv_len = strlen( buf );
        attr_merge( e, "readwaiters", vals );
 
+#ifdef LDAP_COUNTERS
        sprintf( buf, "%ld", ops_initiated );
        val.bv_val = buf;
        val.bv_len = strlen( buf );
@@ -149,8 +147,12 @@ monitor_info( Connection *conn, Operation *op )
        val.bv_val = buf;
        val.bv_len = strlen( buf );
        attr_merge( e, "bytessent", vals );
+#endif
 
-       ldap_pvt_thread_mutex_lock( &currenttime_mutex );
+       slap_set_time();
+       currenttime = slap_get_time();
+
+       ldap_pvt_thread_mutex_lock( &gmtime_mutex );
 #ifndef LDAP_LOCALTIME
        ltm = gmtime( &currenttime );
        strftime( buf, sizeof(buf), "%Y%m%d%H%M%SZ", ltm );
@@ -158,12 +160,10 @@ monitor_info( Connection *conn, Operation *op )
        ltm = localtime( &currenttime );
        strftime( buf, sizeof(buf), "%y%m%d%H%M%SZ", ltm );
 #endif
-       ldap_pvt_thread_mutex_unlock( &currenttime_mutex );
        val.bv_val = buf;
        val.bv_len = strlen( buf );
        attr_merge( e, "currenttime", vals );
 
-       ldap_pvt_thread_mutex_lock( &currenttime_mutex );
 #ifndef LDAP_LOCALTIME
        ltm = gmtime( &starttime );
        strftime( buf, sizeof(buf), "%Y%m%d%H%M%SZ", ltm );
@@ -171,7 +171,8 @@ monitor_info( Connection *conn, Operation *op )
        ltm = localtime( &starttime );
        strftime( buf, sizeof(buf), "%y%m%d%H%M%SZ", ltm );
 #endif
-       ldap_pvt_thread_mutex_unlock( &currenttime_mutex );
+       ldap_pvt_thread_mutex_unlock( &gmtime_mutex );
+
        val.bv_val = buf;
        val.bv_len = strlen( buf );
        attr_merge( e, "starttime", vals );
index 7848357a935b8c7639437ff75346c3117a07f99e..44c821845ecbde47745c3dafbba682c736fcdae5 100644 (file)
@@ -15,8 +15,6 @@ slap_op_free( Operation *op )
 {
        assert( op->o_next == NULL );
 
-       ldap_pvt_thread_mutex_lock( &op->o_abandonmutex );
-
        if ( op->o_ber != NULL ) {
                ber_free( op->o_ber, 1 );
        }
@@ -27,8 +25,8 @@ slap_op_free( Operation *op )
                free( op->o_ndn );
        }
 
-       ldap_pvt_thread_mutex_unlock( &op->o_abandonmutex );
        ldap_pvt_thread_mutex_destroy( &op->o_abandonmutex );
+
        free( (char *) op );
 }
 
@@ -37,8 +35,7 @@ slap_op_alloc(
     BerElement         *ber,
     unsigned long      msgid,
     unsigned long      tag,
-    int                                id,
-    int                                connid
+    long                       id
 )
 {
        Operation       *op;
@@ -46,19 +43,17 @@ slap_op_alloc(
        op = (Operation *) ch_calloc( 1, sizeof(Operation) );
 
        ldap_pvt_thread_mutex_init( &op->o_abandonmutex );
+       op->o_abandon = 0;
+
        op->o_ber = ber;
        op->o_msgid = msgid;
        op->o_tag = tag;
-       op->o_abandon = 0;
 
        op->o_dn = NULL;
        op->o_ndn = NULL;
 
-       ldap_pvt_thread_mutex_lock( &currenttime_mutex );
-       op->o_time = currenttime;
-       ldap_pvt_thread_mutex_unlock( &currenttime_mutex );
+       op->o_time = slap_get_time();
        op->o_opid = id;
-       op->o_connid = connid;
        op->o_next = NULL;
 
        return( op );
index 18fd25614be9f8ed5ab61a4a684daf76b137cbf2..e2876c74d7e55f5cb08f9f2a0567815ce66cd5d5 100644 (file)
@@ -109,8 +109,20 @@ int read_config LDAP_P(( char *fname ));
 /*
  * connection.c
  */
+int connections_init LDAP_P((void));
 
-void connection_activity LDAP_P(( Connection *conn ));
+long connection_init LDAP_P((
+       int s,
+       const char* name, const char* addr));
+
+int connection_write LDAP_P((int s));
+int connection_read LDAP_P((int s));
+
+long connections_nextid(void);
+
+Connection* connection_first LDAP_P((void));
+Connection* connection_next LDAP_P((Connection *));
+void connection_done LDAP_P((Connection *));
 
 /*
  * dn.c
@@ -173,7 +185,7 @@ void monitor_info LDAP_P(( Connection *conn, Operation *op ));
 void slap_op_free LDAP_P(( Operation *op ));
 Operation * slap_op_alloc LDAP_P((
        BerElement *ber, unsigned long msgid,
-       unsigned long tag, int id, int connid ));
+       unsigned long tag, long id ));
 
 int slap_op_add LDAP_P(( Operation **olist, Operation *op ));
 int slap_op_remove LDAP_P(( Operation **olist, Operation *op ));
@@ -202,7 +214,8 @@ void send_ldap_result LDAP_P(( Connection *conn, Operation *op, int err, char *m
        char *text ));
 void send_ldap_search_result LDAP_P(( Connection *conn, Operation *op, int err,
        char *matched, char *text, int nentries ));
-void close_connection LDAP_P(( Connection *conn, int opconnid, int opid ));
+
+void do_close( Connection *conn, long opid );
 
 /*
  * schema.c
@@ -244,7 +257,6 @@ char *suffixAlias LDAP_P(( char *dn, Operation *op, Backend *be ));
  * Other...
  */
 
-extern char            **g_argv;
 extern char            *default_referral;
 extern char            *replogfile;
 extern char            Versionstr[];
@@ -257,35 +269,48 @@ extern int                global_lastmod;
 extern int             global_schemacheck;
 extern int             lber_debug;
 extern int             ldap_syslog;
-extern int             num_conns;
+
+#ifdef LDAP_COUNTERS
+extern ldap_pvt_thread_mutex_t num_sent_mutex;
 extern long            num_bytes_sent;
+
 extern long            num_entries_sent;
+
+extern ldap_pvt_thread_mutex_t ops_mutex;
 extern long            ops_completed;
 extern long            ops_initiated;
+#endif
+
+extern char   *slapd_pid_file;
+extern char   *slapd_args_file;
+extern char            **g_argv;
+extern time_t  starttime;
+
+time_t slap_get_time LDAP_P((void));
+void slap_set_time LDAP_P((void));
 
 extern ldap_pvt_thread_mutex_t active_threads_mutex;
 extern ldap_pvt_thread_cond_t  active_threads_cond;
 
-extern ldap_pvt_thread_mutex_t currenttime_mutex;
 extern ldap_pvt_thread_mutex_t entry2str_mutex;
-extern ldap_pvt_thread_mutex_t new_conn_mutex;
-extern ldap_pvt_thread_mutex_t num_sent_mutex;
-extern ldap_pvt_thread_mutex_t ops_mutex;
 extern ldap_pvt_thread_mutex_t replog_mutex;
+
 #ifdef SLAPD_CRYPT
 extern ldap_pvt_thread_mutex_t crypt_mutex;
 #endif
-extern ldap_pvt_thread_t       listener_tid;
+extern ldap_pvt_thread_mutex_t gmtime_mutex;
+
 extern struct acl      *global_acl;
 extern struct objclass *global_oc;
-extern time_t          currenttime;
 
 extern int     slap_init LDAP_P((int mode, char* name));
 extern int     slap_startup LDAP_P((int dbnum));
 extern int     slap_shutdown LDAP_P((int dbnum));
 extern int     slap_destroy LDAP_P((void));
 
-extern void * slapd_daemon LDAP_P((void *port));
+struct sockaddr_in;
+extern int slapd_daemon LDAP_P((struct sockaddr_in *addr));
+
 extern void    slap_set_shutdown LDAP_P((int sig));
 extern void    slap_do_nothing   LDAP_P((int sig));
 
@@ -303,11 +328,7 @@ extern void        do_unbind LDAP_P((Connection *conn, Operation *op));
 extern int send_search_entry LDAP_P((Backend *be, Connection *conn, Operation *op, Entry *e, char **attrs, int attrsonly));
 extern int str2result LDAP_P(( char *s, int *code, char **matched, char **info ));
 
-#if defined( SLAPD_MONITOR_DN )
-extern Connection      *c;
-extern int             dtblsize;
-extern time_t          starttime;
-#endif
+extern int dtblsize;
 
 #endif /* _proto_slap */
 
index 773687a3d2f8771586a084003d5ffc47e5ae1ac7..f0e79084ad9594d703cbfa51d777c4e7542d23e3 100644 (file)
@@ -46,7 +46,7 @@ replog(
            i++ ) {
                fprintf( fp, "replica: %s\n", be->be_replica[i] );
        }
-       fprintf( fp, "time: %ld\n", (long) currenttime );
+       fprintf( fp, "time: %ld\n", (long) slap_get_time() );
        fprintf( fp, "dn: %s\n", dn );
 
        switch ( optype ) {
index 6d30c29b6d6ee054f4af4bed8534f39eba0a8fba..152af69f7f8648d219b6d474428f95a87bb16a68 100644 (file)
@@ -13,7 +13,6 @@
 
 #include "slap.h"
 
-
 static void
 send_ldap_result2(
     Connection *conn,
@@ -25,7 +24,7 @@ send_ldap_result2(
 )
 {
        BerElement      *ber;
-       int             rc;
+       int             rc, tmp;
        unsigned long   tag, bytes;
 
        if ( err == LDAP_PARTIAL_RESULTS && (text == NULL || *text == '\0') )
@@ -52,12 +51,14 @@ send_ldap_result2(
                break;
        }
 
+
 #ifdef LDAP_COMPAT30
        if ( (ber = ber_alloc_t( conn->c_version == 30 ? 0 : LBER_USE_DER ))
-           == NULLBER ) {
+           == NULLBER )
 #else
-       if ( (ber = der_alloc()) == NULLBER ) {
+       if ( (ber = der_alloc()) == NULLBER )
 #endif
+       {
                Debug( LDAP_DEBUG_ANY, "ber_alloc failed\n", 0, 0, 0 );
                return;
        }
@@ -83,14 +84,15 @@ send_ldap_result2(
        }
 
        /* write only one pdu at a time - wait til it's our turn */
-       ldap_pvt_thread_mutex_lock( &conn->c_pdumutex );
+       ldap_pvt_thread_mutex_lock( &conn->c_write_mutex );
+
+       /* lock the connection */
+       ldap_pvt_thread_mutex_lock( &conn->c_mutex );
 
        /* write the pdu */
        bytes = ber->ber_ptr - ber->ber_buf;
-       ldap_pvt_thread_mutex_lock( &new_conn_mutex );
-       while ( conn->c_connid == op->o_connid && ber_flush( &conn->c_sb, ber,
-           1 ) != 0 ) {
-               ldap_pvt_thread_mutex_unlock( &new_conn_mutex );
+
+       while ( ber_flush( &conn->c_sb, ber, 1 ) != 0 ) {
                /*
                 * we got an error.  if it's ewouldblock, we need to
                 * wait on the socket being writable.  otherwise, figure
@@ -102,35 +104,29 @@ send_ldap_result2(
                    : "unknown", 0 );
 
                if ( errno != EWOULDBLOCK && errno != EAGAIN ) {
-                       close_connection( conn, op->o_connid, op->o_opid );
+                       conn->c_conn_state = SLAP_C_CLOSING;
 
-                       ldap_pvt_thread_mutex_unlock( &conn->c_pdumutex );
+                       ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+                       ldap_pvt_thread_mutex_unlock( &conn->c_write_mutex );
                        return;
                }
 
                /* wait for socket to be write-ready */
-               ldap_pvt_thread_mutex_lock( &active_threads_mutex );
-               active_threads--;
                conn->c_writewaiter = 1;
+               slapd_set_write( conn->c_sb.sb_sd, 1 );
 
-               ldap_pvt_thread_kill( listener_tid, LDAP_SIGUSR1 );
-
-               ldap_pvt_thread_cond_wait( &conn->c_wcv, &active_threads_mutex );
-
-               if( active_threads < 1 ) {
-                       ldap_pvt_thread_cond_signal(&active_threads_cond);
-               }
-               ldap_pvt_thread_mutex_unlock( &active_threads_mutex );
-
-               ldap_pvt_thread_yield();
-               ldap_pvt_thread_mutex_lock( &new_conn_mutex );
+               ldap_pvt_thread_cond_wait( &conn->c_write_cv, &conn->c_mutex );
+               conn->c_writewaiter = 0;
        }
-       ldap_pvt_thread_mutex_unlock( &new_conn_mutex );
-       ldap_pvt_thread_mutex_unlock( &conn->c_pdumutex );
 
+       ldap_pvt_thread_mutex_unlock( &conn->c_write_mutex );
+       ldap_pvt_thread_mutex_unlock( &conn->c_write_mutex );
+
+#ifdef LDAP_COUNTERS
        ldap_pvt_thread_mutex_lock( &num_sent_mutex );
        num_bytes_sent += bytes;
        ldap_pvt_thread_mutex_unlock( &num_sent_mutex );
+#endif
 
        Statslog( LDAP_DEBUG_STATS,
            "conn=%d op=%d RESULT err=%d tag=%lu nentries=%d\n", conn->c_connid,
@@ -186,7 +182,7 @@ send_search_entry(
 {
        BerElement      *ber;
        Attribute       *a;
-       int             i, rc, bytes;
+       int             i, rc=-1, bytes;
        struct acl      *acl;
        char            *edn;
 
@@ -261,7 +257,7 @@ send_search_entry(
                        continue;
                }
 
-               if ( ber_printf( ber, "{s[", a->a_type ) == -1 ) {
+               if (( rc = ber_printf( ber, "{s[", a->a_type )) == -1 ) {
                        Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
                        ber_free( ber, 1 );
                        send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
@@ -278,9 +274,9 @@ send_search_entry(
                                        continue;
                                }
 
-                               if ( ber_printf( ber, "o",
+                               if (( rc = ber_printf( ber, "o",
                                    a->a_vals[i]->bv_val,
-                                   a->a_vals[i]->bv_len ) == -1 )
+                                   a->a_vals[i]->bv_len )) == -1 )
                                {
                                        Debug( LDAP_DEBUG_ANY,
                                            "ber_printf failed\n", 0, 0, 0 );
@@ -293,7 +289,7 @@ send_search_entry(
                        }
                }
 
-               if ( ber_printf( ber, "]}" ) == -1 ) {
+               if (( rc = ber_printf( ber, "]}" )) == -1 ) {
                        Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
                        ber_free( ber, 1 );
                        send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
@@ -317,14 +313,16 @@ send_search_entry(
                return( 1 );
        }
 
+       bytes = ber->ber_ptr - ber->ber_buf;
+
        /* write only one pdu at a time - wait til it's our turn */
-       ldap_pvt_thread_mutex_lock( &conn->c_pdumutex );
+       ldap_pvt_thread_mutex_lock( &conn->c_write_mutex );
 
-       bytes = ber->ber_ptr - ber->ber_buf;
-       ldap_pvt_thread_mutex_lock( &new_conn_mutex );
-       while ( conn->c_connid == op->o_connid && ber_flush( &conn->c_sb, ber,
-           1 ) != 0 ) {
-               ldap_pvt_thread_mutex_unlock( &new_conn_mutex );
+       /* lock the connection */ 
+       ldap_pvt_thread_mutex_lock( &conn->c_mutex );
+
+       /* write the pdu */
+       while ( ber_flush( &conn->c_sb, ber, 1 ) != 0 ) {
                /*
                 * we got an error.  if it's ewouldblock, we need to
                 * wait on the socket being writable.  otherwise, figure
@@ -336,51 +334,40 @@ send_search_entry(
                    : "unknown", 0 );
 
                if ( errno != EWOULDBLOCK && errno != EAGAIN ) {
-                       close_connection( conn, op->o_connid, op->o_opid );
+                       conn->c_conn_state = SLAP_C_CLOSING;
 
-                       ldap_pvt_thread_mutex_unlock( &conn->c_pdumutex );
+                       ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+                       ldap_pvt_thread_mutex_unlock( &conn->c_write_mutex );
                        return( -1 );
                }
 
                /* wait for socket to be write-ready */
-               ldap_pvt_thread_mutex_lock( &active_threads_mutex );
-               active_threads--;
                conn->c_writewaiter = 1;
-               ldap_pvt_thread_kill( listener_tid, LDAP_SIGUSR1 );
-               ldap_pvt_thread_cond_wait( &conn->c_wcv, &active_threads_mutex );
-
-               if( active_threads < 1 ) {
-                       ldap_pvt_thread_cond_signal(&active_threads_cond);
-               }
-               ldap_pvt_thread_mutex_unlock( &active_threads_mutex );
+               slapd_set_write( conn->c_sb.sb_sd, 1 );
 
-               ldap_pvt_thread_yield();
-               ldap_pvt_thread_mutex_lock( &new_conn_mutex );
+               ldap_pvt_thread_cond_wait( &conn->c_write_cv, &conn->c_mutex );
+               conn->c_writewaiter = 0;
        }
-       ldap_pvt_thread_mutex_unlock( &new_conn_mutex );
-       ldap_pvt_thread_mutex_unlock( &conn->c_pdumutex );
 
+       ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+       ldap_pvt_thread_mutex_unlock( &conn->c_write_mutex );
+
+#ifdef LDAP_COUNTERS
        ldap_pvt_thread_mutex_lock( &num_sent_mutex );
        num_bytes_sent += bytes;
        num_entries_sent++;
        ldap_pvt_thread_mutex_unlock( &num_sent_mutex );
+#endif
 
-       ldap_pvt_thread_mutex_lock( &new_conn_mutex );
-       if ( conn->c_connid == op->o_connid ) {
-               rc = 0;
-               Statslog( LDAP_DEBUG_STATS2, "conn=%d op=%d ENTRY dn=\"%s\"\n",
-                   conn->c_connid, op->o_opid, e->e_dn, 0, 0 );
-       } else {
-               rc = -1;
-       }
-       ldap_pvt_thread_mutex_unlock( &new_conn_mutex );
+       Statslog( LDAP_DEBUG_STATS2, "conn=%d op=%d ENTRY dn=\"%s\"\n",
+           conn->c_connid, op->o_opid, e->e_dn, 0, 0 );
 
        Debug( LDAP_DEBUG_TRACE, "<= send_search_entry\n", 0, 0, 0 );
 
-       return( rc );
+       rc = 0;
 
 error_return:;
-       return( 1 );
+       return( rc );
 }
 
 int
@@ -436,26 +423,3 @@ str2result(
 
        return( rc );
 }
-
-/*
- * close_connection - close a connection. takes the connection to close,
- * the connid associated with the operation generating the close (so we
- * don't accidentally close a connection that's not ours), and the opid
- * of the operation generating the close (for logging purposes).
- */
-void
-close_connection( Connection *conn, int opconnid, int opid )
-{
-       ldap_pvt_thread_mutex_lock( &new_conn_mutex );
-       if ( lber_pvt_sb_in_use(&conn->c_sb) && conn->c_connid == opconnid ) {
-               Statslog( LDAP_DEBUG_STATS,
-                   "conn=%d op=%d fd=%d closed errno=%d\n", conn->c_connid,
-                   opid, lber_pvt_sb_get_desc(&conn->c_sb), errno, 0 );
-               lber_pvt_sb_close( &conn->c_sb );
-               lber_pvt_sb_destroy( &conn->c_sb );
-               conn->c_version = 0;
-               conn->c_protocol = 0;
-               conn->c_state = SLAP_C_INACTIVE;
-       }
-       ldap_pvt_thread_mutex_unlock( &new_conn_mutex );
-}
index 837de9025b67a202f61e37aa0089117be78b14f3..dabf8c7bec159ad75ea5fe168e462bdab9e2c979 100644 (file)
@@ -380,27 +380,33 @@ struct backend_info {
  */
 
 typedef struct slap_op {
+       long    o_opid;         /* id of this operation           */
+       long    o_msgid;        /* msgid of the request           */
+
+       ldap_pvt_thread_t       o_tid;          /* thread handling this op        */
+
        BerElement      *o_ber;         /* ber of the request             */
-       long            o_msgid;        /* msgid of the request           */
+
        unsigned long   o_tag;          /* tag of the request             */
        time_t          o_time;         /* time op was initiated          */
        char            *o_dn;          /* dn bound when op was initiated */
        char            *o_ndn;         /* normalized dn bound when op was initiated */
-       int             o_authtype;     /* auth method used to bind dn    */
+       int                     o_authtype;     /* auth method used to bind dn    */
                                        /* values taken from ldap.h       */
                                        /* LDAP_AUTH_*                    */
-       int             o_opid;         /* id of this operation           */
-       int             o_connid;       /* id of conn initiating this op  */
+
+/*      long   o_connid;       *//* id of conn initiating this op  */
+
 #ifdef LDAP_CONNECTIONLESS
        int             o_cldap;        /* != 0 if this came in via CLDAP */
        struct sockaddr o_clientaddr;   /* client address if via CLDAP    */
        char            o_searchbase;   /* search base if via CLDAP       */
 #endif
-       struct slap_op  *o_next;        /* next operation in list         */
-       ldap_pvt_thread_t       o_tid;          /* thread handling this op        */
-       int             o_abandon;      /* signals op has been abandoned  */
-       ldap_pvt_thread_mutex_t o_abandonmutex; /* signals op has been abandoned  */
 
+       ldap_pvt_thread_mutex_t o_abandonmutex; /* protects o_abandon  */
+       int             o_abandon;      /* abandon flag */
+
+       struct slap_op  *o_next;        /* next operation in list         */
        void    *o_private;     /* anything the backend needs     */
 } Operation;
 
@@ -408,41 +414,56 @@ typedef struct slap_op {
  * represents a connection from an ldap client
  */
 
-#define SLAP_C_INACTIVE        0x0
-#define SLAP_C_ACTIVE  0x1
-#define SLAP_C_BINDING 0x2
-#define SLAP_C_CLOSING 0x3
+/* structure state (protected by connections_mutex) */
+#define SLAP_C_UNINITIALIZED   0x0     /* MUST BE ZERO (0) */
+#define SLAP_C_UNUSED                  0x1
+#define SLAP_C_USED                            0x2
+
+/* connection state (protected by c_mutex ) */
+#define SLAP_C_INVALID                 0x0     /* MUST BE ZERO (0) */
+#define SLAP_C_INACTIVE                        0x1     /* zero threads */
+#define SLAP_C_ACTIVE                  0x2 /* one or more threads */
+#define SLAP_C_BINDING                 0x3     /* binding */
+#define SLAP_C_CLOSING                 0x4     /* closing */
 
 typedef struct slap_conn {
-       int                     c_state;        /* connection state */
+       int                     c_struct_state; /* structure management state */
+       int                     c_conn_state;   /* connection state */
+
+       ldap_pvt_thread_mutex_t c_mutex; /* protect the connection */
        Sockbuf         c_sb;           /* ber connection stuff           */
-       char            *c_cdn;         /* DN provided by the client */
-       char            *c_dn;          /* DN bound to this conn  */
-       ldap_pvt_thread_mutex_t c_dnmutex;      /* mutex for c_dn field           */
+
+       /* only can be changed by connect_init */
+       time_t          c_starttime;    /* when the connection was opened */
+       long            c_connid;       /* id of this connection for stats*/
+       char            *c_client_addr; /* address of client */
+       char            *c_client_name; /* name of client */
+
+       /* only can be changed by binding thread */
+       char    *c_cdn;         /* DN provided by the client */
+       char    *c_dn;          /* DN bound to this conn  */
        int             c_protocol;     /* version of the LDAP protocol used by client */
        int             c_authtype;     /* auth method used to bind c_dn  */
 #ifdef LDAP_COMPAT
        int             c_version;      /* for compatibility w/2.0, 3.0   */
 #endif
-       char            *c_addr;        /* address of client on this conn */
-       char            *c_domain;      /* domain of client on this conn  */
+
        Operation       *c_ops;                 /* list of operations being processed */
        Operation       *c_pending_ops; /* list of pending operations */
-       ldap_pvt_thread_mutex_t c_opsmutex;     /* mutex for c_ops list & stats   */
-       ldap_pvt_thread_mutex_t c_pdumutex;     /* only one pdu written at a time */
-       ldap_pvt_thread_cond_t  c_wcv;          /* used to wait for sd write-ready*/
-       int             c_gettingber;   /* in the middle of ber_get_next  */
-       BerElement      *c_currentber;  /* ber we're getting              */
-       int             c_writewaiter;  /* signals write-ready sd waiter  */
-       int             c_pduwaiters;   /* signals threads waiting 4 pdu  */
-       time_t          c_starttime;    /* when the connection was opened */
 
-       long    c_connid;       /* id of this connection for stats*/
+       ldap_pvt_thread_mutex_t c_write_mutex;  /* only one pdu written at a time */
+       ldap_pvt_thread_cond_t  c_write_cv;             /* used to wait for sd write-ready*/
 
-       long    c_ops_received;         /* num of ops received (next op_id) */
-       long    c_ops_executing;        /* num of ops currently executing */
-       long    c_ops_pending;          /* num of ops pending execution */
-       long    c_ops_completed;        /* num of ops completed */
+       BerElement      *c_currentber;  /* ber we're attempting to read */
+       int             c_writewaiter;  /* true if writer is waiting */
+
+       long    c_n_ops_received;               /* num of ops received (next op_id) */
+#ifdef LDAP_COUNTERS
+       long    c_n_ops_executing;      /* num of ops currently executing */
+       long    c_n_ops_pending;                /* num of ops pending execution */
+       long    c_n_ops_completed;      /* num of ops completed */
+#endif
 } Connection;
 
 #if defined(LDAP_SYSLOG) && defined(LDAP_DEBUG)
index f53ed416295b7e3dbf7d764f959b509c99e123c6..f8e8195e389be1138e266741ee800c37501a16e2 100644 (file)
@@ -31,7 +31,8 @@ PROGRAMS2=ldif2index-bdb2 ldif2ldbm-bdb2 \
        ldif2id2entry-bdb2 ldif2id2children-bdb2
 
 SRCS = centipede.c ldbmcat.c ldbmtest.c sizecount.c \
-       ldif.c ldif2id2children.c ldif2id2entry.c ldif2index.c ldif2ldbm.c
+       ldif.c ldif2id2children.c ldif2id2entry.c ldif2index.c ldif2ldbm.c \
+       mimic.c
 
 SRCS2 = ldif2id2children-bdb2.c ldif2id2entry-bdb2.c \
        ldif2index-bdb2.c ldif2ldbm-bdb2.c
@@ -41,8 +42,9 @@ XSRCS = edb2-vers.c
 EDB2LDIFSRCS   = edb2ldif.c ldapsyntax.c
 EDB2LDIFOBJS   = edb2ldif.o ldapsyntax.o
 
-OBJS2  = ../config.o ../ch_malloc.o ../backend.o ../charray.o \
-               ../aclparse.o ../schema.o ../result.o ../filterentry.o \
+OBJS2  = mimic.o \
+               ../config.o ../ch_malloc.o ../backend.o ../charray.o \
+               ../aclparse.o ../schema.o ../filterentry.o \
                ../acl.o ../phonetic.o ../attr.o ../value.o ../entry.o \
                ../dn.o ../filter.o ../str2filter.o ../ava.o ../init.o \
                ../schemaparse.o
diff --git a/servers/slapd/tools/mimic.c b/servers/slapd/tools/mimic.c
new file mode 100644 (file)
index 0000000..87359d3
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Mimic unused interfaces of slapd...
+ * needed for linking.
+ */
+#include "portable.h"
+
+#include <stdio.h>
+
+#include "../slap.h"
+
+void
+send_ldap_result(
+       Connection  *conn, 
+       Operation   *op,
+       int     err,
+       char    *matched,
+       char    *text
+)        
+{
+       assert(0);
+}
+
+void
+send_ldap_search_result(
+       Connection  *conn, 
+       Operation   *op,
+       int     err,
+       char    *matched,
+       char    *text,
+       int             nentries
+)        
+{
+       assert(0);
+}
+
+int
+send_search_entry(
+       Backend *be,
+       Connection  *conn, 
+       Operation   *op,
+       Entry   *e,
+       char    **attrs,
+       int             attrsonly
+)        
+{
+       assert(0);
+       return -1;
+}
index 1416393343a1c4e395298ee0d0a6d73cf3c8e98e..f351e554099ecd8d24c883ed989640f627583023 100644 (file)
@@ -41,7 +41,4 @@ do_unbind(
 
        /* pass the unbind to all backends */
        backend_unbind( conn, op );
-       
-       /* close the connection to the client */
-       close_connection( conn, op->o_connid, op->o_opid );
 }