https://fedorahosted.org/sssd/ticket/1776
From 89e48e89881b45aa1a1ae3d21b7d0d0f37a38362 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <[email protected]>
Date: Mon, 21 Jan 2013 17:18:30 +0100
Subject: [PATCH] fix backend callbacks: remove callback properly from dlist

https://fedorahosted.org/sssd/ticket/1776

Although cb->list got updated when the callback is removed,
this change did not propagate to be_ctx->*_cb_list which
caused dlist having invalid records.
---
 src/providers/data_provider_callbacks.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/src/providers/data_provider_callbacks.c b/src/providers/data_provider_callbacks.c
index 0f8fca0b191c6fe14a038b73c37a2735db4b96d6..3081b8df3fe28f692ed511c587b2c93e9ab2af57 100644
--- a/src/providers/data_provider_callbacks.c
+++ b/src/providers/data_provider_callbacks.c
@@ -34,7 +34,7 @@ struct be_cb {
     be_callback_t cb;
     void *pvt;
 
-    struct be_cb *list;
+    struct be_cb **list;
     struct be_ctx *be;
 };
 
@@ -46,7 +46,7 @@ struct be_cb_ctx {
 static int cb_destructor(TALLOC_CTX *ptr)
 {
     struct be_cb *cb = talloc_get_type(ptr, struct be_cb);
-    DLIST_REMOVE(cb->list, cb);
+    DLIST_REMOVE(*(cb->list), cb);
     return 0;
 }
 
@@ -67,7 +67,7 @@ static int be_add_cb(TALLOC_CTX *mem_ctx, struct be_ctx *ctx,
 
     new_cb->cb = cb;
     new_cb->pvt = pvt;
-    new_cb->list = *cb_list;
+    new_cb->list = cb_list;
     new_cb->be = ctx;
 
     DLIST_ADD(*cb_list, new_cb);
@@ -85,14 +85,18 @@ static void be_run_cb_step(struct tevent_context *ev, struct tevent_timer *te,
                            struct timeval current_time, void *pvt)
 {
     struct be_cb_ctx *cb_ctx = talloc_get_type(pvt, struct be_cb_ctx);
+    struct be_cb *next_cb;
     struct tevent_timer *tev;
     struct timeval soon;
 
+    /* Store next callback in case this callback frees itself */
+    next_cb = cb_ctx->callback->next;
+
     /* Call the callback */
     cb_ctx->callback->cb(cb_ctx->callback->pvt);
 
-    if (cb_ctx->callback->next) {
-        cb_ctx->callback = cb_ctx->callback->next;
+    if (next_cb) {
+        cb_ctx->callback = next_cb;
 
         /* Delay 30ms so we don't block any other events */
         soon = tevent_timeval_current_ofs(0, 30000);
@@ -119,6 +123,10 @@ static errno_t be_run_cb(struct be_ctx *be, struct be_cb *cb_list) {
     struct tevent_timer *te;
     struct be_cb_ctx *cb_ctx;
 
+    if (cb_list == NULL) {
+        return EOK;
+    }
+
     cb_ctx = talloc(be, struct be_cb_ctx);
     if (!cb_ctx) {
         DEBUG(0, ("Out of memory. Could not invoke callbacks\n"));
@@ -158,6 +166,7 @@ int be_add_reconnect_cb(TALLOC_CTX *mem_ctx, struct be_ctx *ctx, be_callback_t c
 void be_run_reconnect_cb(struct be_ctx *be)
 {
     struct be_cb *callback = be->reconnect_cb_list;
+    struct be_cb *next_cb;
 
     if (callback) {
         DEBUG(SSSDBG_TRACE_FUNC, ("Reconnecting. Running callbacks.\n"));
@@ -168,8 +177,11 @@ void be_run_reconnect_cb(struct be_ctx *be)
          * a little while
          */
         do {
+            /* Store next callback in case this callback frees itself */
+            next_cb = callback->next;
+
             callback->cb(callback->pvt);
-            callback = callback->next;
+            callback = next_cb;
         } while(callback != NULL);
     } else {
         DEBUG(SSSDBG_TRACE_INTERNAL, ("Reconnect call back list is empty, nothing to do.\n"));
-- 
1.7.11.7

_______________________________________________
sssd-devel mailing list
[email protected]
https://lists.fedorahosted.org/mailman/listinfo/sssd-devel

Reply via email to