]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/overlays/sssvlv.c
Happy New Year
[openldap] / servers / slapd / overlays / sssvlv.c
index 50e0710d1fa6bc6b853c9e5f2491da846b741f74..e650840530bbad6a8635da848bc192da9ec9eac8 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 2009-2014 The OpenLDAP Foundation.
+ * Copyright 2009-2018 The OpenLDAP Foundation.
  * Portions copyright 2009 Symas Corporation.
  * All rights reserved.
  *
@@ -105,7 +105,7 @@ typedef struct sssvlv_info
 
 typedef struct sort_op
 {
-       Avlnode *so_tree;
+       TAvlnode *so_tree;
        sort_ctrl *so_ctrl;
        sssvlv_info *so_info;
        int so_paged;
@@ -116,6 +116,7 @@ typedef struct sort_op
        int so_vlv_target;
        int so_session;
        unsigned long so_vcontext;
+       int so_running;
 } sort_op;
 
 /* There is only one conn table for all overlay instances */
@@ -396,30 +397,35 @@ static int find_next_session(
 static void free_sort_op( Connection *conn, sort_op *so )
 {
        int sess_id;
-       if ( so->so_tree ) {
-               if ( so->so_paged > SLAP_CONTROL_IGNORED ) {
-                       Avlnode *cur_node, *next_node;
-                       cur_node = so->so_tree;
-                       while ( cur_node ) {
-                               next_node = tavl_next( cur_node, TAVL_DIR_RIGHT );
-                               ch_free( cur_node->avl_data );
-                               ber_memfree( cur_node );
-
-                               cur_node = next_node;
-                       }
-               } else {
-                       tavl_free( so->so_tree, ch_free );
-               }
-               so->so_tree = NULL;
-       }
-
+               
        ldap_pvt_thread_mutex_lock( &sort_conns_mutex );
        sess_id = find_session_by_so( so->so_info->svi_max_percon, conn->c_conn_idx, so );
-       sort_conns[conn->c_conn_idx][sess_id] = NULL;
-       so->so_info->svi_num--;
+       if ( sess_id > -1 ) {
+           sort_conns[conn->c_conn_idx][sess_id] = NULL;
+           so->so_info->svi_num--;
+       }
        ldap_pvt_thread_mutex_unlock( &sort_conns_mutex );
-
-       ch_free( so );
+       
+       if ( sess_id > -1 ){
+           if ( so->so_tree ) {
+                   if ( so->so_paged > SLAP_CONTROL_IGNORED ) {
+                           TAvlnode *cur_node, *next_node;
+                           cur_node = so->so_tree;
+                           while ( cur_node ) {
+                                   next_node = tavl_next( cur_node, TAVL_DIR_RIGHT );
+                                   ch_free( cur_node->avl_data );
+                                   ber_memfree( cur_node );
+
+                                   cur_node = next_node;
+                           }
+                   } else {
+                           tavl_free( so->so_tree, ch_free );
+                   }
+                   so->so_tree = NULL;
+           }
+
+           ch_free( so );
+       }
 }
 
 static void free_sort_ops( Connection *conn, sort_op **sos, int svi_max_percon )
@@ -441,7 +447,7 @@ static void send_list(
        SlapReply               *rs,
        sort_op                 *so)
 {
-       Avlnode *cur_node, *tmp_node;
+       TAvlnode *cur_node, *tmp_node;
        vlv_ctrl *vc = op->o_controls[vlv_cid];
        int i, j, dir, rc;
        BackendDB *be;
@@ -594,8 +600,8 @@ range_err:
 
 static void send_page( Operation *op, SlapReply *rs, sort_op *so )
 {
-       Avlnode         *cur_node               = so->so_tree;
-       Avlnode         *next_node              = NULL;
+       TAvlnode *cur_node = so->so_tree;
+       TAvlnode *next_node = NULL;
        BackendDB *be = op->o_bd;
        Entry *e;
        int rc;
@@ -649,7 +655,7 @@ static void send_entry(
                return;
 
        /* RFC 2891: If critical then send the entries iff they were
-        * succesfully sorted.  If non-critical send all entries
+        * successfully sorted.  If non-critical send all entries
         * whether they were sorted or not.
         */
        if ( (op->o_ctrlflag[sss_cid] != SLAP_CONTROL_CRITICAL) ||
@@ -659,7 +665,7 @@ static void send_entry(
                        send_list( op, rs, so );
                } else {
                        /* Get the first node to send */
-                       Avlnode *start_node = tavl_end(so->so_tree, TAVL_DIR_LEFT);
+                       TAvlnode *start_node = tavl_end(so->so_tree, TAVL_DIR_LEFT);
                        so->so_tree = start_node;
 
                        if ( so->so_paged <= SLAP_CONTROL_IGNORED ) {
@@ -704,6 +710,8 @@ static void send_result(
        if ( so->so_tree == NULL ) {
                /* Search finished, so clean up */
                free_sort_op( op->o_conn, so );
+       } else {
+           so->so_running = 0;
        }
 }
 
@@ -859,26 +867,40 @@ static int sssvlv_op_search(
        sess_id = find_session_by_context( si->svi_max_percon, op->o_conn->c_conn_idx, vc ? vc->vc_context : NO_VC_CONTEXT, ps ? ps->ps_cookie : NO_PS_COOKIE );
        if ( sess_id >= 0 ) {
                so = sort_conns[op->o_conn->c_conn_idx][sess_id];
-               /* Is it a continuation of a VLV search? */
-               if ( !vc || so->so_vlv <= SLAP_CONTROL_IGNORED ||
-                       vc->vc_context != so->so_vcontext ) {
-                       /* Is it a continuation of a paged search? */
-                       if ( !ps || so->so_paged <= SLAP_CONTROL_IGNORED ||
-                               op->o_conn->c_pagedresults_state.ps_cookie != ps->ps_cookie ) {
-                               ok = 0;
-                       } else if ( !ps->ps_size ) {
-                       /* Abandoning current request */
-                               ok = 0;
-                               so->so_nentries = 0;
-                               rs->sr_err = LDAP_SUCCESS;
-                       }
-               }
-               if (( vc && so->so_paged > SLAP_CONTROL_IGNORED ) ||
-                       ( ps && so->so_vlv > SLAP_CONTROL_IGNORED )) {
-                       /* changed from paged to vlv or vice versa, abandon */
-                       ok = 0;
-                       so->so_nentries = 0;
-                       rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+               
+               if( so->so_running > 0 ){
+                   /* another thread is handling, response busy to client */
+                   so = NULL;
+                   ok = 0;
+               } else {
+               
+                   /* Is it a continuation of a VLV search? */
+                   if ( !vc || so->so_vlv <= SLAP_CONTROL_IGNORED ||
+                           vc->vc_context != so->so_vcontext ) {
+                           /* Is it a continuation of a paged search? */
+                           if ( !ps || so->so_paged <= SLAP_CONTROL_IGNORED ||
+                                   op->o_conn->c_pagedresults_state.ps_cookie != ps->ps_cookie ) {
+                                   ok = 0;
+                           } else if ( !ps->ps_size ) {
+                           /* Abandoning current request */
+                                   ok = 0;
+                                   so->so_nentries = 0;
+                                   rs->sr_err = LDAP_SUCCESS;
+                           }
+                   }
+                   if (( vc && so->so_paged > SLAP_CONTROL_IGNORED ) ||
+                           ( ps && so->so_vlv > SLAP_CONTROL_IGNORED )) {
+                           /* changed from paged to vlv or vice versa, abandon */
+                           ok = 0;
+                           so->so_nentries = 0;
+                           rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+                   }
+
+                   if ( ok ) {
+                       /* occupy before mutex unlock */
+                       so->so_running = 1;
+                   }
+               
                }
        /* Are there too many running overall? */
        } else if ( si->svi_num >= si->svi_max ) {
@@ -923,6 +945,7 @@ static int sssvlv_op_search(
                        cb->sc_response         = sssvlv_op_response;
                        cb->sc_next                     = op->o_callback;
                        cb->sc_private          = so;
+                       cb->sc_writewait        = NULL;
 
                        so->so_tree = NULL;
                        so->so_ctrl = sc;
@@ -946,6 +969,7 @@ static int sssvlv_op_search(
                        so->so_vlv = op->o_ctrlflag[vlv_cid];
                        so->so_vcontext = (unsigned long)so;
                        so->so_nentries = 0;
+                       so->so_running = 1;
 
                        op->o_callback          = cb;
                }