andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 5 months ago
Clone
dc8c34
From 627d47e423e6c1c113f24ef7f29a2e5728cf70e4 Mon Sep 17 00:00:00 2001
dc8c34
From: Noriko Hosoi <nhosoi@redhat.com>
dc8c34
Date: Sun, 26 Apr 2015 14:46:44 -0700
dc8c34
Subject: [PATCH 316/319] Ticket #48146 - async simple paged results issue
dc8c34
dc8c34
Description: When the last page of the single paged results is returned,
dc8c34
the search results structure is freed in the simple paged results code
dc8c34
(in op_shared_search).  The search results structure is stashed in the
dc8c34
simple paged results object across the pages.  The free and the clean up
dc8c34
of the stashed address should have been atomic, but it was not.
dc8c34
dc8c34
https://fedorahosted.org/389/ticket/48146
dc8c34
dc8c34
Reviewed by mreynolds@redhat.com (Thank you, Mark!!)
dc8c34
dc8c34
(cherry picked from commit 947477f2e2367337a8c220d8c9d03a62bf1bbf1c)
dc8c34
(cherry picked from commit ec8801a69adbe2f502513fabcbb79bc5e38bf197)
dc8c34
(cherry picked from commit c4ab1196a597ff6845535cf5068be7c5524ec0cb)
dc8c34
(cherry picked from commit 31cd2a52cc6a8b73a26016a0e1e6910c265a44d7)
dc8c34
---
dc8c34
 ldap/servers/slapd/opshared.c     | 18 +++++++-----------
dc8c34
 ldap/servers/slapd/pagedresults.c | 36 +++++++++++-------------------------
dc8c34
 2 files changed, 18 insertions(+), 36 deletions(-)
dc8c34
dc8c34
diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
dc8c34
index bef19d1..3e55729 100644
dc8c34
--- a/ldap/servers/slapd/opshared.c
dc8c34
+++ b/ldap/servers/slapd/opshared.c
dc8c34
@@ -874,7 +874,10 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
dc8c34
             slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET, &sr);
dc8c34
             if (PAGEDRESULTS_SEARCH_END == pr_stat) {
dc8c34
               if (sr) { /* in case a left over sr is found, clean it up */
dc8c34
+                PR_Lock(pb->pb_conn->c_mutex);
dc8c34
+                pagedresults_set_search_result(pb->pb_conn, operation, NULL, 1, pr_idx);
dc8c34
                 be->be_search_results_release(&sr);
dc8c34
+                PR_Unlock(pb->pb_conn->c_mutex);
dc8c34
               }
dc8c34
               if (NULL == next_be) {
dc8c34
                 /* no more entries && no more backends */
dc8c34
@@ -890,17 +893,10 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
dc8c34
               slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET_SIZE_ESTIMATE, &estimate);
dc8c34
               pagedresults_lock(pb->pb_conn, pr_idx);
dc8c34
               if ((pagedresults_set_current_be(pb->pb_conn, be, pr_idx) < 0) ||
dc8c34
-                  (pagedresults_set_search_result(pb->pb_conn, operation,
dc8c34
-                                                  sr, 0, pr_idx) < 0) ||
dc8c34
-                  (pagedresults_set_search_result_count(pb->pb_conn, operation,
dc8c34
-                                                        curr_search_count,
dc8c34
-                                                        pr_idx) < 0) ||
dc8c34
-                  (pagedresults_set_search_result_set_size_estimate(pb->pb_conn,
dc8c34
-                                                                 operation,
dc8c34
-                                                                 estimate,
dc8c34
-                                                                 pr_idx) < 0) ||
dc8c34
-                  (pagedresults_set_with_sort(pb->pb_conn, operation,
dc8c34
-                                              with_sort, pr_idx) < 0)) {
dc8c34
+                  (pagedresults_set_search_result(pb->pb_conn, operation, sr, 0, pr_idx) < 0) ||
dc8c34
+                  (pagedresults_set_search_result_count(pb->pb_conn, operation, curr_search_count, pr_idx) < 0) ||
dc8c34
+                  (pagedresults_set_search_result_set_size_estimate(pb->pb_conn, operation, estimate, pr_idx) < 0) ||
dc8c34
+                  (pagedresults_set_with_sort(pb->pb_conn, operation, with_sort, pr_idx) < 0)) {
dc8c34
                 pagedresults_unlock(pb->pb_conn, pr_idx);
dc8c34
                 goto free_and_return;
dc8c34
               }
dc8c34
diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c
dc8c34
index d589708..e61c000 100644
dc8c34
--- a/ldap/servers/slapd/pagedresults.c
dc8c34
+++ b/ldap/servers/slapd/pagedresults.c
dc8c34
@@ -100,26 +100,20 @@ pagedresults_parse_control_value( Slapi_PBlock *pb,
dc8c34
     ber_free(ber, 1);
dc8c34
     if ( cookie.bv_len <= 0 ) {
dc8c34
         int i;
dc8c34
-        int maxlen;
dc8c34
         /* first time? */
dc8c34
-        maxlen = conn->c_pagedresults.prl_maxlen;
dc8c34
+        int maxlen = conn->c_pagedresults.prl_maxlen;
dc8c34
         if (conn->c_pagedresults.prl_count == maxlen) {
dc8c34
             if (0 == maxlen) { /* first time */
dc8c34
                 conn->c_pagedresults.prl_maxlen = 1;
dc8c34
-                conn->c_pagedresults.prl_list =
dc8c34
-                    (PagedResults *)slapi_ch_calloc(1,
dc8c34
-                                                sizeof(PagedResults));
dc8c34
+                conn->c_pagedresults.prl_list = (PagedResults *)slapi_ch_calloc(1, sizeof(PagedResults));
dc8c34
             } else {
dc8c34
                 /* new max length */
dc8c34
                 conn->c_pagedresults.prl_maxlen *= 2;
dc8c34
-                conn->c_pagedresults.prl_list =
dc8c34
-                    (PagedResults *)slapi_ch_realloc(
dc8c34
+                conn->c_pagedresults.prl_list = (PagedResults *)slapi_ch_realloc(
dc8c34
                                 (char *)conn->c_pagedresults.prl_list,
dc8c34
-                                sizeof(PagedResults) *
dc8c34
-                                conn->c_pagedresults.prl_maxlen);
dc8c34
+                                sizeof(PagedResults) * conn->c_pagedresults.prl_maxlen);
dc8c34
                 /* initialze newly allocated area */
dc8c34
-                memset(conn->c_pagedresults.prl_list + maxlen, '\0',
dc8c34
-                           sizeof(PagedResults) * maxlen);
dc8c34
+                memset(conn->c_pagedresults.prl_list + maxlen, '\0', sizeof(PagedResults) * maxlen);
dc8c34
             }
dc8c34
             *index = maxlen; /* the first position in the new area */
dc8c34
         } else {
dc8c34
@@ -276,8 +270,8 @@ pagedresults_free_one( Connection *conn, Operation *op, int index )
dc8c34
                 prp->pr_current_be->be_search_results_release &&
dc8c34
                 prp->pr_search_result_set) {
dc8c34
                 prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set));
dc8c34
-                prp->pr_current_be = NULL;
dc8c34
             }
dc8c34
+            prp->pr_current_be = NULL;
dc8c34
             if (prp->pr_mutex) {
dc8c34
                 /* pr_mutex is reused; back it up and reset it. */
dc8c34
                 prmutex = prp->pr_mutex;
dc8c34
@@ -314,8 +308,8 @@ pagedresults_free_one_msgid_nolock( Connection *conn, ber_int_t msgid )
dc8c34
                         prp->pr_current_be->be_search_results_release &&
dc8c34
                         prp->pr_search_result_set) {
dc8c34
                         prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set));
dc8c34
-                        prp->pr_current_be = NULL;
dc8c34
                     }
dc8c34
+                    prp->pr_current_be = NULL;
dc8c34
                     prp->pr_flags |= CONN_FLAG_PAGEDRESULTS_ABANDONED;
dc8c34
                     prp->pr_flags &= ~CONN_FLAG_PAGEDRESULTS_PROCESSING;
dc8c34
                     conn->c_pagedresults.prl_count--;
dc8c34
@@ -404,16 +398,8 @@ pagedresults_set_search_result(Connection *conn, Operation *op, void *sr,
dc8c34
     if (conn && (index > -1)) {
dc8c34
         if (!locked) PR_Lock(conn->c_mutex);
dc8c34
         if (index < conn->c_pagedresults.prl_maxlen) {
dc8c34
-            if (sr) { /* set */
dc8c34
-                if (NULL ==
dc8c34
-                    conn->c_pagedresults.prl_list[index].pr_search_result_set) {
dc8c34
-                    conn->c_pagedresults.prl_list[index].pr_search_result_set = sr;
dc8c34
-                    rc = 0;
dc8c34
-                }
dc8c34
-            } else {  /* reset */
dc8c34
-                conn->c_pagedresults.prl_list[index].pr_search_result_set = sr;
dc8c34
-                rc = 0;
dc8c34
-            }
dc8c34
+            conn->c_pagedresults.prl_list[index].pr_search_result_set = sr;
dc8c34
+            rc = 0;
dc8c34
         }
dc8c34
         if (!locked) PR_Unlock(conn->c_mutex);
dc8c34
     }
dc8c34
@@ -732,9 +718,9 @@ pagedresults_cleanup(Connection *conn, int needlock)
dc8c34
         if (prp->pr_current_be && prp->pr_search_result_set &&
dc8c34
             prp->pr_current_be->be_search_results_release) {
dc8c34
             prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set));
dc8c34
-            prp->pr_current_be = NULL;
dc8c34
             rc = 1;
dc8c34
         }
dc8c34
+        prp->pr_current_be = NULL;
dc8c34
         if (prp->pr_mutex) {
dc8c34
             PR_DestroyLock(prp->pr_mutex);
dc8c34
         }
dc8c34
@@ -780,9 +766,9 @@ pagedresults_cleanup_all(Connection *conn, int needlock)
dc8c34
         if (prp->pr_current_be && prp->pr_search_result_set &&
dc8c34
             prp->pr_current_be->be_search_results_release) {
dc8c34
             prp->pr_current_be->be_search_results_release(&(prp->pr_search_result_set));
dc8c34
-            prp->pr_current_be = NULL;
dc8c34
             rc = 1;
dc8c34
         }
dc8c34
+        prp->pr_current_be = NULL;
dc8c34
     }
dc8c34
     slapi_ch_free((void **)&conn->c_pagedresults.prl_list);
dc8c34
     conn->c_pagedresults.prl_maxlen = 0;
dc8c34
-- 
dc8c34
1.9.3
dc8c34