]> git.sur5r.net Git - openldap/commitdiff
Added ld_req_mutex and ld_res_mutex to protect ld_requests and ld_responses
authorHoward Chu <hyc@openldap.org>
Thu, 13 Feb 2003 10:43:16 +0000 (10:43 +0000)
committerHoward Chu <hyc@openldap.org>
Thu, 13 Feb 2003 10:43:16 +0000 (10:43 +0000)
queues for multithreaded access to LDAP*'s. Also used to protect writes and
reads of ld_sb, respectively. Appears to work...

libraries/libldap/abandon.c
libraries/libldap/ldap-int.h
libraries/libldap/open.c
libraries/libldap/request.c
libraries/libldap/result.c
libraries/libldap/unbind.c

index aa3f9d5885da9373cc8a7a03e148de61f0ef43ef..7945aa5fdfa656e61dbcb6cd6f527092d176c5c8 100644 (file)
@@ -32,7 +32,8 @@ static int do_abandon LDAP_P((
        ber_int_t origid,
        ber_int_t msgid,
        LDAPControl **sctrls,
-       LDAPControl **cctrls));
+       LDAPControl **cctrls,
+       int lock));
 
 /*
  * ldap_abandon_ext - perform an ldap extended abandon operation.
@@ -67,7 +68,7 @@ ldap_abandon_ext(
        rc = ldap_int_client_controls( ld, cctrls );
        if( rc != LDAP_SUCCESS ) return rc;
 
-       return do_abandon( ld, msgid, msgid, sctrls, cctrls );
+       return do_abandon( ld, msgid, msgid, sctrls, cctrls, 1 );
 }
 
 
@@ -101,7 +102,8 @@ do_abandon(
        ber_int_t origid,
        ber_int_t msgid,
        LDAPControl **sctrls,
-       LDAPControl **cctrls)
+       LDAPControl **cctrls,
+       int lock)
 {
        BerElement      *ber;
        int             i, err, sendabandon;
@@ -118,6 +120,9 @@ do_abandon(
 
        sendabandon = 1;
 
+#ifdef LDAP_R_COMPILE
+       if ( lock ) ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
+#endif
        /* find the request that we are abandoning */
        for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) {
                if ( lr->lr_msgid == msgid ) {  /* this message */
@@ -125,9 +130,12 @@ do_abandon(
                }
                if ( lr->lr_origid == msgid ) {/* child:  abandon it */
                        (void) do_abandon( ld,
-                               msgid, lr->lr_msgid, sctrls, cctrls );
+                               msgid, lr->lr_msgid, sctrls, cctrls, 0 );
                }
        }
+#ifdef LDAP_R_COMPILE
+       if ( lock ) ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
+#endif
 
        if ( lr != NULL ) {
                if ( origid == msgid && lr->lr_parent != NULL ) {
@@ -213,12 +221,18 @@ do_abandon(
                                        sb = ld->ld_sb;
                                }
 
+#ifdef LDAP_R_COMPILE
+       if ( lock ) ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
+#endif
                                if ( ber_flush( sb, ber, 1 ) != 0 ) {
                                        ld->ld_errno = LDAP_SERVER_DOWN;
                                        err = -1;
                                } else {
                                        err = 0;
                                }
+#ifdef LDAP_R_COMPILE
+       if ( lock ) ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
+#endif
                        }
                }
        }
index a769f287af49bc586b475b2ef6f57db525b1b842..586b892304cccc3938651c16c1ed7c3b797f9ac7 100644 (file)
@@ -302,6 +302,11 @@ struct ldap {
        LDAPRequest     *ld_requests;   /* list of outstanding requests */
        LDAPMessage     *ld_responses;  /* list of outstanding responses */
 
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_t ld_req_mutex;
+       ldap_pvt_thread_mutex_t ld_res_mutex;
+#endif
+
        ber_int_t               *ld_abandoned;  /* array of abandoned requests */
 
        LDAPCache       *ld_cache;      /* non-null if cache is initialized */
index 149ac4a31a972c30d380cee96dabd8724c540b7a..31db8f49a14b760c0ac09df972a26c6d0bee3b0b 100644 (file)
@@ -160,6 +160,10 @@ ldap_create( LDAP **ldp )
                return LDAP_NO_MEMORY;
        }
 
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_init( &ld->ld_req_mutex );
+       ldap_pvt_thread_mutex_init( &ld->ld_res_mutex );
+#endif
        *ldp = ld;
        return LDAP_SUCCESS;
 }
@@ -419,6 +423,7 @@ int ldap_open_internal_connection( LDAP **ldp, ber_socket_t *fdp )
        lr->lr_msgid = 0;
        lr->lr_status = LDAP_REQST_INPROGRESS;
        lr->lr_res_errno = LDAP_SUCCESS;
+       /* no mutex lock needed, we just created this ld here */
        (*ldp)->ld_requests = lr;
 
        /* Attach the passed socket as the *LDAP's connection */
index dedb1ee2868f081471ef717238f1c0251d29b22a..0a61770bc07f93ca05c6d28f74efd059ebdf4ec1 100644 (file)
@@ -186,7 +186,7 @@ ldap_send_server_request(
        LDAPreqinfo *bind )
 {
        LDAPRequest     *lr;
-       int incparent;
+       int incparent, rc;
 
 #ifdef NEW_LOGGING
        LDAP_LOG ( OPERATION, ENTRY, "ldap_send_server_request\n", 0, 0, 0 );
@@ -232,11 +232,19 @@ ldap_send_server_request(
         * LDAP_BUSY and let the caller retry later. We only allow a single
         * request to be in WRITING state.
         */
+       rc = 0;
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
+#endif
        if ( ld->ld_requests &&
                ld->ld_requests->lr_status == LDAP_REQST_WRITING &&
                ldap_int_flush_request( ld, ld->ld_requests ) < 0 ) {
-               return -1;
+               rc = -1;
        }
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
+#endif
+       if ( rc ) return rc;
 
        if (( lr = (LDAPRequest *)LDAP_CALLOC( 1, sizeof( LDAPRequest ))) ==
            NULL ) {
@@ -268,17 +276,23 @@ ldap_send_server_request(
                lr->lr_origid = lr->lr_msgid;
        }
 
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
+#endif
        if (( lr->lr_next = ld->ld_requests ) != NULL ) {
                lr->lr_next->lr_prev = lr;
        }
        ld->ld_requests = lr;
        lr->lr_prev = NULL;
 
+       ld->ld_errno = LDAP_SUCCESS;
        if ( ldap_int_flush_request( ld, lr ) == -1 ) {
-               return -1;
+               msgid = -1;
        }
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
+#endif
 
-       ld->ld_errno = LDAP_SUCCESS;
        return( msgid );
 }
 
@@ -572,6 +586,9 @@ ldap_dump_requests_and_responses( LDAP *ld )
        LDAPRequest     *lr;
        LDAPMessage     *lm, *l;
 
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
+#endif
        fprintf( stderr, "** Outstanding Requests:\n" );
        if (( lr = ld->ld_requests ) == NULL ) {
                fprintf( stderr, "   Empty\n" );
@@ -587,7 +604,10 @@ ldap_dump_requests_and_responses( LDAP *ld )
            fprintf( stderr, "   outstanding referrals %d, parent count %d\n",
                    lr->lr_outrefcnt, lr->lr_parentcnt );
        }
-
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
+       ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
+#endif
        fprintf( stderr, "** Response Queue:\n" );
        if (( lm = ld->ld_responses ) == NULL ) {
                fprintf( stderr, "   Empty\n" );
@@ -605,6 +625,9 @@ ldap_dump_requests_and_responses( LDAP *ld )
                        }
                }
        }
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
+#endif
 }
 #endif /* LDAP_DEBUG */
 
@@ -1241,6 +1264,9 @@ ldap_find_request_by_msgid( LDAP *ld, ber_int_t msgid )
 {
        LDAPRequest     *lr;
 
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
+#endif
        for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) {
                if( lr->lr_status == LDAP_REQST_COMPLETED ) {
                        continue;       /* Skip completed requests */
@@ -1249,6 +1275,9 @@ ldap_find_request_by_msgid( LDAP *ld, ber_int_t msgid )
                        break;
                }
        }
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
+#endif
 
        return( lr );
 }
index ac60a337c54764dda07cc9850109c3a2177ef566..b003e475a5a57e1fe5f956893ab180f14062b5e4 100644 (file)
@@ -141,6 +141,9 @@ chkResponseList(
            msgid, all, 0 );
 #endif
        lastlm = NULL;
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
+#endif
        for ( lm = ld->ld_responses; lm != NULL; lm = nextlm ) {
                nextlm = lm->lm_next;
 
@@ -207,6 +210,9 @@ chkResponseList(
            }
            lm->lm_next = NULL;
     }
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
+#endif
 
 #ifdef LDAP_DEBUG
        if( lm == NULL) {
@@ -308,7 +314,13 @@ wait4msg(
                }
 
                    if ( lc == NULL ) {
+#ifdef LDAP_R_COMPILE
+                           ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
+#endif
                            rc = ldap_int_select( ld, tvp );
+#ifdef LDAP_R_COMPILE
+                           ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
+#endif
 
 
 #ifdef LDAP_DEBUG
@@ -338,12 +350,18 @@ wait4msg(
                                    rc = -2;    /* select interrupted: loop */
                            } else {
                                    rc = -2;
+#ifdef LDAP_R_COMPILE
+                                   ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
+#endif
                                    if ( ld->ld_requests &&
                                                ld->ld_requests->lr_status == LDAP_REQST_WRITING &&
                                                ldap_is_write_ready( ld,
                                                        ld->ld_requests->lr_conn->lconn_sb ) ) {
                                                ldap_int_flush_request( ld, ld->ld_requests );
                                        }
+#ifdef LDAP_R_COMPILE
+                                   ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
+#endif
                                    for ( lc = ld->ld_conns; rc == -2 && lc != NULL;
                                        lc = nextlc ) {
                                            nextlc = lc->lconn_next;
@@ -417,18 +435,23 @@ try_read1msg(
 #endif
 
 retry:
-    if ( lc->lconn_ber == NULL ) {
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
+#endif
+       if ( lc->lconn_ber == NULL ) {
                lc->lconn_ber = ldap_alloc_ber_with_options(ld);
 
                if( lc->lconn_ber == NULL ) {
+#ifdef LDAP_R_COMPILE
+                       ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
+#endif
                        return -1;
                }
-    }
+       }
 
        ber = lc->lconn_ber;
        assert( LBER_VALID (ber) );
 
-retry2:
        /* get the next message */
        errno = 0;
 #ifdef LDAP_CONNECTIONLESS
@@ -437,8 +460,18 @@ retry2:
                ber_int_sb_read(sb, &from, sizeof(struct sockaddr));
        }
 #endif
-       if ( (tag = ber_get_next( sb, &len, ber ))
-           != LDAP_TAG_MESSAGE ) {
+       tag = ber_get_next( sb, &len, ber );
+       if ( tag == LDAP_TAG_MESSAGE ) {
+               /*
+                * We read a complete message.
+                * The connection should no longer need this ber.
+                */
+               lc->lconn_ber = NULL;
+       }
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
+#endif
+       if ( tag != LDAP_TAG_MESSAGE ) {
                if ( tag == LBER_DEFAULT) {
 #ifdef LDAP_DEBUG                 
 #ifdef NEW_LOGGING
@@ -462,12 +495,6 @@ retry2:
                return -1;
        }
 
-       /*
-     * We read a complete message.
-        * The connection should no longer need this ber.
-        */
-    lc->lconn_ber = NULL;
-
        /* message id */
        if ( ber_get_int( ber, &id ) == LBER_ERROR ) {
                ber_free( ber, 1 );
@@ -483,12 +510,10 @@ retry2:
                Debug( LDAP_DEBUG_ANY, "abandoned\n", 0, 0, 0);
 #endif
 retry_ber:
+               ber_free( ber, 1 );
                if ( ber_sockbuf_ctrl( sb, LBER_SB_OPT_DATA_READY, NULL ) ) {
-                       ber_free_buf( ber );
-                       ber_init2( ber, NULL, ld->ld_lberoptions );
-                       goto retry2;
+                       goto retry;
                }
-               ber_free( ber, 1 );
                return( -2 );   /* continue looking */
        }
 
@@ -832,6 +857,9 @@ lr->lr_res_matched ? lr->lr_res_matched : "" );
         * search response.
         */
 
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
+#endif
        prev = NULL;
        for ( l = ld->ld_responses; l != NULL; l = l->lm_next ) {
                if ( l->lm_msgid == new->lm_msgid )
@@ -843,8 +871,7 @@ lr->lr_res_matched ? lr->lr_res_matched : "" );
        if ( l == NULL ) {
                if ( foundit ) {
                        *result = new;
-                       ld->ld_errno = LDAP_SUCCESS;
-                       return( tag );
+                       goto leave;
                }
 
                new->lm_next = ld->ld_responses;
@@ -877,11 +904,16 @@ lr->lr_res_matched ? lr->lr_res_matched : "" );
                else
                        prev->lm_next = l->lm_next;
                *result = l;
-               ld->ld_errno = LDAP_SUCCESS;
-               return( tag );
        }
 
 leave:
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
+#endif
+       if ( foundit ) {
+               ld->ld_errno = LDAP_SUCCESS;
+               return( tag );
+       }
        if ( ber_sockbuf_ctrl( sb, LBER_SB_OPT_DATA_READY, NULL ) ) {
                goto retry;
        }
@@ -1056,6 +1088,7 @@ int
 ldap_msgdelete( LDAP *ld, int msgid )
 {
        LDAPMessage     *lm, *prev;
+       int rc = 0;
 
        assert( ld != NULL );
 
@@ -1066,24 +1099,30 @@ ldap_msgdelete( LDAP *ld, int msgid )
 #endif
 
        prev = NULL;
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
+#endif
        for ( lm = ld->ld_responses; lm != NULL; lm = lm->lm_next ) {
                if ( lm->lm_msgid == msgid )
                        break;
                prev = lm;
        }
 
-       if ( lm == NULL )
-               return( -1 );
-
-       if ( prev == NULL )
-               ld->ld_responses = lm->lm_next;
-       else
-               prev->lm_next = lm->lm_next;
-
-       if ( ldap_msgfree( lm ) == LDAP_RES_SEARCH_ENTRY )
-               return( -1 );
+       if ( lm == NULL ) {
+               rc = -1;
+       } else {
+               if ( prev == NULL )
+                       ld->ld_responses = lm->lm_next;
+               else
+                       prev->lm_next = lm->lm_next;
+       }
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
+#endif
+       if ( lm && ldap_msgfree( lm ) == LDAP_RES_SEARCH_ENTRY )
+               rc = -1;
 
-       return( 0 );
+       return( rc );
 }
 
 
index a34939abc06111a9e6a628db48909ebad8b79afb..2ac13904a69602b3415dacbf93e56ae0095b1a28 100644 (file)
@@ -79,20 +79,31 @@ ldap_ld_free(
        int             err = LDAP_SUCCESS;
 
        /* free LDAP structure and outstanding requests/responses */
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
+#endif
        while ( ld->ld_requests != NULL ) {
                ldap_free_request( ld, ld->ld_requests );
        }
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
+#endif
 
        /* free and unbind from all open connections */
        while ( ld->ld_conns != NULL ) {
                ldap_free_connection( ld, ld->ld_conns, 1, close );
        }
 
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
+#endif
        for ( lm = ld->ld_responses; lm != NULL; lm = next ) {
                next = lm->lm_next;
                ldap_msgfree( lm );
        }
-
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
+#endif
 
        if ( ld->ld_error != NULL ) {
                LDAP_FREE( ld->ld_error );
@@ -158,6 +169,10 @@ ldap_ld_free(
 
        ber_sockbuf_free( ld->ld_sb );   
    
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_destroy( &ld->ld_req_mutex );
+       ldap_pvt_thread_mutex_destroy( &ld->ld_res_mutex );
+#endif
        LDAP_FREE( (char *) ld );
    
        return( err );
@@ -214,12 +229,18 @@ ldap_send_unbind(
                return( ld->ld_errno );
        }
 
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
+#endif
+       ld->ld_errno = LDAP_SUCCESS;
        /* send the message */
        if ( ber_flush( sb, ber, 1 ) == -1 ) {
                ld->ld_errno = LDAP_SERVER_DOWN;
                ber_free( ber, 1 );
-               return( ld->ld_errno );
        }
+#ifdef LDAP_R_COMPILE
+       ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
+#endif
 
-       return( LDAP_SUCCESS );
+       return( ld->ld_errno );
 }