Blame SOURCES/0064-Ticket-48146-async-simple-paged-results-issue.patch

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