|
|
df9752 |
From 22b0f8f0de1ee208a8c06c171bc2069da0adcc87 Mon Sep 17 00:00:00 2001
|
|
|
df9752 |
From: Noriko Hosoi <nhosoi@redhat.com>
|
|
|
df9752 |
Date: Mon, 6 Jul 2015 14:06:11 -0700
|
|
|
df9752 |
Subject: [PATCH] Ticket #48192 - Individual abandoned simple paged results
|
|
|
df9752 |
request has no chance to be cleaned up
|
|
|
df9752 |
|
|
|
df9752 |
Description: There was a small window that the search on the next page
|
|
|
df9752 |
after the previous page abandoned referred the cleaned up simple paged
|
|
|
df9752 |
object.
|
|
|
df9752 |
|
|
|
df9752 |
This patch introduces a pagedresults_is_abandoned helper function to
|
|
|
df9752 |
check the simple paged results was abandoned or not with some improvements
|
|
|
df9752 |
based upon the comments by rmeggins@redhat.com (Thank you!!):
|
|
|
df9752 |
1) adding locking when getting a simplepaged object in pagedresults_is_
|
|
|
df9752 |
abandoned_or_notavailable as well as in pagedresults_{un}lock.
|
|
|
df9752 |
2) sending "Simple Paged Results Search abandoned" if the previous page
|
|
|
df9752 |
with the same cookie in the same connection was abandoned.
|
|
|
df9752 |
|
|
|
df9752 |
https://fedorahosted.org/389/ticket/48192
|
|
|
df9752 |
|
|
|
df9752 |
Reviewed by rmeggins@redhat.com (Thank you, Rich!!)
|
|
|
df9752 |
|
|
|
df9752 |
(cherry picked from commit e4d83c91fc88fcf9e6c823c608c629ac10e362f8)
|
|
|
df9752 |
(cherry picked from commit b513a502250f93cfb43df000c2140b27c4ef0d39)
|
|
|
df9752 |
(cherry picked from commit 7b17c488de280f29264920b4e53dce862ed5b7e4)
|
|
|
df9752 |
---
|
|
|
df9752 |
ldap/servers/slapd/opshared.c | 22 ++++++++++++++++------
|
|
|
df9752 |
ldap/servers/slapd/pagedresults.c | 24 +++++++++++++++++++++++-
|
|
|
df9752 |
ldap/servers/slapd/proto-slap.h | 1 +
|
|
|
df9752 |
3 files changed, 40 insertions(+), 7 deletions(-)
|
|
|
df9752 |
|
|
|
df9752 |
diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
|
|
|
df9752 |
index 4be5366..1bad7ef 100644
|
|
|
df9752 |
--- a/ldap/servers/slapd/opshared.c
|
|
|
df9752 |
+++ b/ldap/servers/slapd/opshared.c
|
|
|
df9752 |
@@ -709,12 +709,20 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
|
|
|
df9752 |
*/
|
|
|
df9752 |
pr_search_result = pagedresults_get_search_result(pb->pb_conn, operation, pr_idx);
|
|
|
df9752 |
if (pr_search_result) {
|
|
|
df9752 |
- slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET, pr_search_result );
|
|
|
df9752 |
- rc = send_results_ext (pb, 1, &pnentries, pagesize, &pr_stat);
|
|
|
df9752 |
+ if (pagedresults_is_abandoned_or_notavailable(pb->pb_conn, pr_idx)) {
|
|
|
df9752 |
+ pagedresults_unlock(pb->pb_conn, pr_idx);
|
|
|
df9752 |
+ /* Previous operation was abandoned and the simplepaged object is not in use. */
|
|
|
df9752 |
+ send_ldap_result(pb, 0, NULL, "Simple Paged Results Search abandoned", 0, NULL);
|
|
|
df9752 |
+ rc = LDAP_SUCCESS;
|
|
|
df9752 |
+ goto free_and_return;
|
|
|
df9752 |
+ } else {
|
|
|
df9752 |
+ slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_SET, pr_search_result );
|
|
|
df9752 |
+ rc = send_results_ext (pb, 1, &pnentries, pagesize, &pr_stat);
|
|
|
df9752 |
|
|
|
df9752 |
- /* search result could be reset in the backend/dse */
|
|
|
df9752 |
- slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET, &sr);
|
|
|
df9752 |
- pagedresults_set_search_result(pb->pb_conn, operation, sr, 0, pr_idx);
|
|
|
df9752 |
+ /* search result could be reset in the backend/dse */
|
|
|
df9752 |
+ slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET, &sr);
|
|
|
df9752 |
+ pagedresults_set_search_result(pb->pb_conn, operation, sr, 0, pr_idx);
|
|
|
df9752 |
+ }
|
|
|
df9752 |
} else {
|
|
|
df9752 |
pr_stat = PAGEDRESULTS_SEARCH_END;
|
|
|
df9752 |
}
|
|
|
df9752 |
@@ -744,7 +752,9 @@ op_shared_search (Slapi_PBlock *pb, int send_result)
|
|
|
df9752 |
if (PAGEDRESULTS_SEARCH_END == pr_stat) {
|
|
|
df9752 |
pagedresults_lock(pb->pb_conn, pr_idx);
|
|
|
df9752 |
slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_SET, NULL);
|
|
|
df9752 |
- pagedresults_free_one(pb->pb_conn, operation, pr_idx);
|
|
|
df9752 |
+ if (!pagedresults_is_abandoned_or_notavailable(pb->pb_conn, pr_idx)) {
|
|
|
df9752 |
+ pagedresults_free_one(pb->pb_conn, operation, pr_idx);
|
|
|
df9752 |
+ }
|
|
|
df9752 |
pagedresults_unlock(pb->pb_conn, pr_idx);
|
|
|
df9752 |
if (next_be) {
|
|
|
df9752 |
/* no more entries, but at least another backend */
|
|
|
df9752 |
diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c
|
|
|
df9752 |
index a7fe2cd..010e5c1 100644
|
|
|
df9752 |
--- a/ldap/servers/slapd/pagedresults.c
|
|
|
df9752 |
+++ b/ldap/servers/slapd/pagedresults.c
|
|
|
df9752 |
@@ -890,6 +890,8 @@ pagedresults_reset_processing(Connection *conn, int index)
|
|
|
df9752 |
* If there are multiple slots, the connection may be a permanent one.
|
|
|
df9752 |
* Do not return timed out here. But let the next request take care the
|
|
|
df9752 |
* timedout slot(s).
|
|
|
df9752 |
+ *
|
|
|
df9752 |
+ * must be called within conn->c_mutex
|
|
|
df9752 |
*/
|
|
|
df9752 |
int
|
|
|
df9752 |
pagedresults_is_timedout_nolock(Connection *conn)
|
|
|
df9752 |
@@ -918,7 +920,10 @@ pagedresults_is_timedout_nolock(Connection *conn)
|
|
|
df9752 |
return 0;
|
|
|
df9752 |
}
|
|
|
df9752 |
|
|
|
df9752 |
-/* reset all timeout */
|
|
|
df9752 |
+/*
|
|
|
df9752 |
+ * reset all timeout
|
|
|
df9752 |
+ * must be called within conn->c_mutex
|
|
|
df9752 |
+ */
|
|
|
df9752 |
int
|
|
|
df9752 |
pagedresults_reset_timedout_nolock(Connection *conn)
|
|
|
df9752 |
{
|
|
|
df9752 |
@@ -981,7 +986,9 @@ pagedresults_lock( Connection *conn, int index )
|
|
|
df9752 |
if (!conn || (index < 0) || (index >= conn->c_pagedresults.prl_maxlen)) {
|
|
|
df9752 |
return;
|
|
|
df9752 |
}
|
|
|
df9752 |
+ PR_Lock(conn->c_mutex);
|
|
|
df9752 |
prp = conn->c_pagedresults.prl_list + index;
|
|
|
df9752 |
+ PR_Unlock(conn->c_mutex);
|
|
|
df9752 |
if (prp->pr_mutex) {
|
|
|
df9752 |
PR_Lock(prp->pr_mutex);
|
|
|
df9752 |
}
|
|
|
df9752 |
@@ -995,9 +1002,24 @@ pagedresults_unlock( Connection *conn, int index )
|
|
|
df9752 |
if (!conn || (index < 0) || (index >= conn->c_pagedresults.prl_maxlen)) {
|
|
|
df9752 |
return;
|
|
|
df9752 |
}
|
|
|
df9752 |
+ PR_Lock(conn->c_mutex);
|
|
|
df9752 |
prp = conn->c_pagedresults.prl_list + index;
|
|
|
df9752 |
+ PR_Unlock(conn->c_mutex);
|
|
|
df9752 |
if (prp->pr_mutex) {
|
|
|
df9752 |
PR_Unlock(prp->pr_mutex);
|
|
|
df9752 |
}
|
|
|
df9752 |
return;
|
|
|
df9752 |
}
|
|
|
df9752 |
+
|
|
|
df9752 |
+int
|
|
|
df9752 |
+pagedresults_is_abandoned_or_notavailable( Connection *conn, int index )
|
|
|
df9752 |
+{
|
|
|
df9752 |
+ PagedResults *prp;
|
|
|
df9752 |
+ if (!conn || (index < 0) || (index >= conn->c_pagedresults.prl_maxlen)) {
|
|
|
df9752 |
+ return 1; /* not abandoned, but do not want to proceed paged results op. */
|
|
|
df9752 |
+ }
|
|
|
df9752 |
+ PR_Lock(conn->c_mutex);
|
|
|
df9752 |
+ prp = conn->c_pagedresults.prl_list + index;
|
|
|
df9752 |
+ PR_Unlock(conn->c_mutex);
|
|
|
df9752 |
+ return prp->pr_flags & CONN_FLAG_PAGEDRESULTS_ABANDONED;
|
|
|
df9752 |
+}
|
|
|
df9752 |
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
|
|
|
df9752 |
index c5c412d..4c0d1ce 100644
|
|
|
df9752 |
--- a/ldap/servers/slapd/proto-slap.h
|
|
|
df9752 |
+++ b/ldap/servers/slapd/proto-slap.h
|
|
|
df9752 |
@@ -1515,6 +1515,7 @@ int pagedresults_cleanup_all(Connection *conn, int needlock);
|
|
|
df9752 |
void op_set_pagedresults(Operation *op);
|
|
|
df9752 |
void pagedresults_lock(Connection *conn, int index);
|
|
|
df9752 |
void pagedresults_unlock(Connection *conn, int index);
|
|
|
df9752 |
+int pagedresults_is_abandoned_or_notavailable(Connection *conn, int index);
|
|
|
df9752 |
|
|
|
df9752 |
/*
|
|
|
df9752 |
* sort.c
|
|
|
df9752 |
--
|
|
|
df9752 |
1.9.3
|
|
|
df9752 |
|