]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/daemon.c
Plug mutex/rwlock leaks (destroy them)
[openldap] / servers / slapd / daemon.c
index 8e4e853f2c2d3c977c8a2440f93ca440c7373f0b..a504842ae0266acaac5593d44bbe82429ed7b007 100644 (file)
@@ -1,7 +1,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2009 The OpenLDAP Foundation.
+ * Copyright 1998-2010 The OpenLDAP Foundation.
  * Portions Copyright 2007 by Howard Chu, Symas Corporation.
  * All rights reserved.
  *
@@ -73,6 +73,11 @@ ber_socket_t dtblsize;
 slap_ssf_t local_ssf = LDAP_PVT_SASL_LOCAL_SSF;
 struct runqueue_s slapd_rq;
 
+#ifdef LDAP_TCP_BUFFER
+int slapd_tcp_rmem;
+int slapd_tcp_wmem;
+#endif /* LDAP_TCP_BUFFER */
+
 Listener **slap_listeners = NULL;
 
 #ifndef SLAPD_LISTEN_BACKLOG
@@ -984,13 +989,17 @@ slapd_clr_read( ber_socket_t s, int wake )
 void
 slapd_set_read( ber_socket_t s, int wake )
 {
+       int do_wake = 1;
        ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
 
-       assert( SLAP_SOCK_IS_ACTIVE( s ));
-       if (!SLAP_SOCK_IS_READ( s )) SLAP_SOCK_SET_READ( s );
-
+       if( SLAP_SOCK_IS_ACTIVE( s ) && !SLAP_SOCK_IS_READ( s )) {
+               SLAP_SOCK_SET_READ( s );
+       } else {
+               do_wake = 0;
+       }
        ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
-       WAKE_LISTENER(wake);
+       if ( do_wake )
+               WAKE_LISTENER(wake);
 }
 
 time_t
@@ -1315,6 +1324,11 @@ slap_open_listener(
        }
 #endif /* HAVE_TLS */
 
+#ifdef LDAP_TCP_BUFFER
+       l.sl_tcp_rmem = 0;
+       l.sl_tcp_wmem = 0;
+#endif /* LDAP_TCP_BUFFER */
+
        port = (unsigned short) lud->lud_port;
 
        tmp = ldap_pvt_url_scheme2proto(lud->lud_scheme);
@@ -1478,7 +1492,7 @@ slap_open_listener(
                 * create/unlink the socket; likely need exec perms to access
                 * the socket (ITS#4709) */
                {
-                       mode_t old_umask;
+                       mode_t old_umask = 0;
 
                        if ( (*sal)->sa_family == AF_LOCAL ) {
                                old_umask = umask( 0 );
@@ -1486,7 +1500,7 @@ slap_open_listener(
 #endif /* LDAP_PF_LOCAL */
                        rc = bind( s, *sal, addrlen );
 #ifdef LDAP_PF_LOCAL
-                       if ( (*sal)->sa_family == AF_LOCAL ) {
+                       if ( old_umask != 0 ) {
                                umask( old_umask );
                        }
                }
@@ -1610,6 +1624,7 @@ slapd_daemon_init( const char *urls )
                        "daemon: lutil_pair() failed rc=%d\n", rc, 0, 0 );
                return rc;
        }
+       ber_pvt_socket_set_nonblock( wake_sds[1], 1 );
 
        SLAP_SOCK_INIT;
 
@@ -1705,9 +1720,12 @@ close_listeners(
 
        for ( l = 0; slap_listeners[l] != NULL; l++ ) {
                Listener *lr = slap_listeners[l];
+               slap_listeners[l] = NULL;
 
                if ( lr->sl_sd != AC_SOCKET_INVALID ) {
-                       if ( remove ) slapd_remove( lr->sl_sd, NULL, 0, 0, 0 );
+                       int s = lr->sl_sd;
+                       lr->sl_sd = AC_SOCKET_INVALID;
+                       if ( remove ) slapd_remove( s, NULL, 0, 0, 0 );
 
 #ifdef LDAP_PF_LOCAL
                        if ( lr->sl_sa.sa_addr.sa_family == AF_LOCAL ) {
@@ -1715,7 +1733,7 @@ close_listeners(
                        }
 #endif /* LDAP_PF_LOCAL */
 
-                       slapd_close( lr->sl_sd );
+                       slapd_close( s );
                }
 
                if ( lr->sl_url.bv_val ) {
@@ -1727,7 +1745,6 @@ close_listeners(
                }
 
                free( lr );
-               slap_listeners[l] = NULL;
        }
 }
 
@@ -2081,6 +2098,131 @@ slapd_daemon_task(
                        continue;
 #endif /* LDAP_CONNECTIONLESS */
 
+               /* FIXME: TCP-only! */
+#ifdef LDAP_TCP_BUFFER
+               if ( 1 ) {
+                       int origsize, size, realsize, rc;
+                       socklen_t optlen;
+                       char buf[ SLAP_TEXT_BUFLEN ];
+
+                       size = 0;
+                       if ( slap_listeners[l]->sl_tcp_rmem > 0 ) {
+                               size = slap_listeners[l]->sl_tcp_rmem;
+                       } else if ( slapd_tcp_rmem > 0 ) {
+                               size = slapd_tcp_rmem;
+                       }
+
+                       if ( size > 0 ) {
+                               optlen = sizeof( origsize );
+                               rc = getsockopt( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ),
+                                       SOL_SOCKET,
+                                       SO_RCVBUF,
+                                       (void *)&origsize,
+                                       &optlen );
+
+                               if ( rc ) {
+                                       int err = sock_errno();
+                                       Debug( LDAP_DEBUG_ANY,
+                                               "slapd_daemon_task: getsockopt(SO_RCVBUF) failed errno=%d (%s)\n",
+                                               err, sock_errstr(err), 0 );
+                               }
+
+                               optlen = sizeof( size );
+                               rc = setsockopt( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ),
+                                       SOL_SOCKET,
+                                       SO_RCVBUF,
+                                       (const void *)&size,
+                                       optlen );
+
+                               if ( rc ) {
+                                       int err = sock_errno();
+                                       Debug( LDAP_DEBUG_ANY,
+                                               "slapd_daemon_task: setsockopt(SO_RCVBUF) failed errno=%d (%s)\n",
+                                               err, sock_errstr(err), 0 );
+                               }
+
+                               optlen = sizeof( realsize );
+                               rc = getsockopt( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ),
+                                       SOL_SOCKET,
+                                       SO_RCVBUF,
+                                       (void *)&realsize,
+                                       &optlen );
+
+                               if ( rc ) {
+                                       int err = sock_errno();
+                                       Debug( LDAP_DEBUG_ANY,
+                                               "slapd_daemon_task: getsockopt(SO_RCVBUF) failed errno=%d (%s)\n",
+                                               err, sock_errstr(err), 0 );
+                               }
+
+                               snprintf( buf, sizeof( buf ),
+                                       "url=%s (#%d) RCVBUF original size=%d requested size=%d real size=%d", 
+                                       slap_listeners[l]->sl_url.bv_val, l, origsize, size, realsize );
+                               Debug( LDAP_DEBUG_ANY,
+                                       "slapd_daemon_task: %s\n",
+                                       buf, 0, 0 );
+                       }
+
+                       size = 0;
+                       if ( slap_listeners[l]->sl_tcp_wmem > 0 ) {
+                               size = slap_listeners[l]->sl_tcp_wmem;
+                       } else if ( slapd_tcp_wmem > 0 ) {
+                               size = slapd_tcp_wmem;
+                       }
+
+                       if ( size > 0 ) {
+                               optlen = sizeof( origsize );
+                               rc = getsockopt( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ),
+                                       SOL_SOCKET,
+                                       SO_SNDBUF,
+                                       (void *)&origsize,
+                                       &optlen );
+
+                               if ( rc ) {
+                                       int err = sock_errno();
+                                       Debug( LDAP_DEBUG_ANY,
+                                               "slapd_daemon_task: getsockopt(SO_SNDBUF) failed errno=%d (%s)\n",
+                                               err, sock_errstr(err), 0 );
+                               }
+
+                               optlen = sizeof( size );
+                               rc = setsockopt( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ),
+                                       SOL_SOCKET,
+                                       SO_SNDBUF,
+                                       (const void *)&size,
+                                       optlen );
+
+                               if ( rc ) {
+                                       int err = sock_errno();
+                                       Debug( LDAP_DEBUG_ANY,
+                                               "slapd_daemon_task: setsockopt(SO_SNDBUF) failed errno=%d (%s)",
+                                               err, sock_errstr(err), 0 );
+                               }
+
+                               optlen = sizeof( realsize );
+                               rc = getsockopt( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ),
+                                       SOL_SOCKET,
+                                       SO_SNDBUF,
+                                       (void *)&realsize,
+                                       &optlen );
+
+                               if ( rc ) {
+                                       int err = sock_errno();
+                                       Debug( LDAP_DEBUG_ANY,
+                                               "slapd_daemon_task: getsockopt(SO_SNDBUF) failed errno=%d (%s)\n",
+                                               err, sock_errstr(err), 0 );
+                               }
+
+                               snprintf( buf, sizeof( buf ),
+                                       "url=%s (#%d) SNDBUF original size=%d requested size=%d real size=%d", 
+                                       slap_listeners[l]->sl_url.bv_val, l, origsize, size, realsize );
+                               Debug( LDAP_DEBUG_ANY,
+                                       "slapd_daemon_task: %s\n",
+                                       buf, 0, 0 );
+                       }
+               }
+#endif /* LDAP_TCP_BUFFER */
+
                if ( listen( SLAP_FD2SOCK( slap_listeners[l]->sl_sd ), SLAPD_LISTEN_BACKLOG ) == -1 ) {
                        int err = sock_errno();
 
@@ -2662,7 +2804,7 @@ connectionless_init( void )
                if ( !c ) {
                        Debug( LDAP_DEBUG_TRACE,
                                "connectionless_init: failed on %s (%d)\n",
-                               lr->sl_url, lr->sl_sd, 0 );
+                               lr->sl_url.bv_val, lr->sl_sd, 0 );
                        return -1;
                }
                lr->sl_is_udp++;