From 5fa0c57c3868014f0f230d5980a079cc515f6ad8 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Fri, 14 May 2010 10:18:33 +0200 Subject: [PATCH 02/10] Refactor data provider callbacks --- src/Makefile.am | 1 + src/providers/data_provider_be.c | 137 ----------------------- src/providers/data_provider_callbacks.c | 182 +++++++++++++++++++++++++++++++ src/providers/dp_backend.h | 10 +- 4 files changed, 188 insertions(+), 142 deletions(-) create mode 100644 src/providers/data_provider_callbacks.c diff --git a/src/Makefile.am b/src/Makefile.am index 86c497e..c7a10e7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -399,6 +399,7 @@ sssd_be_SOURCES = \ providers/data_provider_be.c \ providers/data_provider_fo.c \ providers/data_provider_opts.c \ + providers/data_provider_callbacks.c \ $(SSSD_FAILOVER_OBJ) \ $(SSSD_UTIL_OBJ) sssd_be_LDADD = $(SSSD_LIBS) $(CARES_LIBS) diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c index 9ef436e..9a7f8cf 100644 --- a/src/providers/data_provider_be.c +++ b/src/providers/data_provider_be.c @@ -169,143 +169,6 @@ void be_mark_offline(struct be_ctx *ctx) ctx->run_online_cb = true; } - -struct be_conn_online_cb { - struct be_conn_online_cb *prev; - struct be_conn_online_cb *next; - - be_conn_online_callback_t cb; - void *pvt; - - struct be_ctx *be; -}; - -static int online_cb_destructor(TALLOC_CTX *ptr); -int be_add_online_cb(TALLOC_CTX *mem_ctx, - struct be_ctx *ctx, - be_conn_online_callback_t cb, - void *pvt, - struct be_conn_online_cb **online_cb) -{ - struct be_conn_online_cb *on_cb; - - if (!ctx || !cb) { - return EINVAL; - } - - on_cb = talloc(mem_ctx, struct be_conn_online_cb); - if (!on_cb) { - return ENOMEM; - } - - on_cb->cb = cb; - on_cb->pvt = pvt; - on_cb->be = ctx; - - DLIST_ADD(ctx->online_cb_list, on_cb); - - talloc_set_destructor((TALLOC_CTX *)on_cb, online_cb_destructor); - - /* Make sure we run the callback for the first - * connection after startup. - */ - ctx->run_online_cb = true; - - if (online_cb) { - *online_cb = on_cb; - } - - return EOK; -} - -static int online_cb_destructor(TALLOC_CTX *ptr) -{ - struct be_conn_online_cb *cb = - talloc_get_type(ptr, struct be_conn_online_cb); - DLIST_REMOVE(cb->be->online_cb_list, cb); - return 0; -} - - -struct be_online_cb_ctx { - struct be_ctx *be; - struct be_conn_online_cb *callback; -}; - -static void be_run_online_cb_step(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval current_time, - void *pvt); -void be_run_online_cb(struct be_ctx *be) { - struct timeval soon; - struct tevent_timer *te; - struct be_online_cb_ctx *cb_ctx; - - if (be->run_online_cb && be->online_cb_list) { - /* Reset the flag. We only want to run these - * callbacks when transitioning to online - */ - be->run_online_cb = false; - - DEBUG(3, ("Going online. Running callbacks.\n")); - - cb_ctx = talloc(be, struct be_online_cb_ctx); - if (!cb_ctx) { - DEBUG(0, ("Out of memory. Could not invoke callbacks\n")); - return; - } - cb_ctx->be = be; - cb_ctx->callback = be->online_cb_list; - - /* Delay 30ms so we don't block any other events */ - soon = tevent_timeval_current_ofs(0, 30000); - te = tevent_add_timer(be->ev, cb_ctx, soon, - be_run_online_cb_step, - cb_ctx); - if (!te) { - DEBUG(0, ("Out of memory. Could not invoke callbacks\n")); - talloc_free(cb_ctx); - } - } -} - -static void be_run_online_cb_step(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval current_time, - void *pvt) -{ - struct be_online_cb_ctx *cb_ctx = - talloc_get_type(pvt, struct be_online_cb_ctx); - struct tevent_timer *tev; - struct timeval soon; - - /* Call the callback */ - cb_ctx->callback->cb(cb_ctx->callback->pvt); - - if (cb_ctx->callback->next) { - cb_ctx->callback = cb_ctx->callback->next; - - /* Delay 30ms so we don't block any other events */ - soon = tevent_timeval_current_ofs(0, 30000); - tev = tevent_add_timer(cb_ctx->be->ev, cb_ctx, soon, - be_run_online_cb_step, - cb_ctx); - if (!te) { - DEBUG(0, ("Out of memory. Could not invoke callbacks\n")); - goto final; - } - return; - } - -final: - /* Steal the timer event onto the be_ctx so it doesn't - * get freed with the cb_ctx - */ - talloc_steal(cb_ctx->be, te); - talloc_free(cb_ctx); -} - - static int be_check_online(DBusMessage *message, struct sbus_connection *conn) { struct be_client *becli; diff --git a/src/providers/data_provider_callbacks.c b/src/providers/data_provider_callbacks.c new file mode 100644 index 0000000..00bc8fd --- /dev/null +++ b/src/providers/data_provider_callbacks.c @@ -0,0 +1,182 @@ +/* + SSSD + + Data Provider Process - Callback + + Authors: + + Stephen Gallagher + Sumit Bose + + Copyright (C) 2010 Red Hat + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "util/util.h" +#include "providers/dp_backend.h" + +struct be_cb { + struct be_cb *prev; + struct be_cb *next; + + be_callback_t cb; + void *pvt; + + struct be_cb *list; + struct be_ctx *be; +}; + +struct be_cb_ctx { + struct be_ctx *be; + struct be_cb *callback; +}; + +static int cb_destructor(TALLOC_CTX *ptr) +{ + struct be_cb *cb = talloc_get_type(ptr, struct be_cb); + DLIST_REMOVE(cb->list, cb); + return 0; +} + +static int be_add_cb(TALLOC_CTX *mem_ctx, struct be_ctx *ctx, + be_callback_t cb, void *pvt, struct be_cb **cb_list, + struct be_cb **return_cb) +{ + struct be_cb *new_cb; + + if (!ctx || !cb) { + return EINVAL; + } + + new_cb = talloc(mem_ctx, struct be_cb); + if (!new_cb) { + return ENOMEM; + } + + new_cb->cb = cb; + new_cb->pvt = pvt; + new_cb->list = *cb_list; + new_cb->be = ctx; + + DLIST_ADD(*cb_list, new_cb); + + talloc_set_destructor((TALLOC_CTX *) new_cb, cb_destructor); + + if (return_cb) { + *return_cb = new_cb; + } + + return EOK; +} + +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 tevent_timer *tev; + struct timeval soon; + + /* Call the callback */ + cb_ctx->callback->cb(cb_ctx->callback->pvt); + + if (cb_ctx->callback->next) { + cb_ctx->callback = cb_ctx->callback->next; + + /* Delay 30ms so we don't block any other events */ + soon = tevent_timeval_current_ofs(0, 30000); + tev = tevent_add_timer(cb_ctx->be->ev, cb_ctx, soon, + be_run_cb_step, + cb_ctx); + if (!te) { + DEBUG(0, ("Out of memory. Could not invoke callbacks\n")); + goto final; + } + return; + } + +final: + /* Steal the timer event onto the be_ctx so it doesn't + * get freed with the cb_ctx + */ + talloc_steal(cb_ctx->be, te); + talloc_free(cb_ctx); +} + +static errno_t be_run_cb(struct be_ctx *be, struct be_cb *cb_list) { + struct timeval soon; + struct tevent_timer *te; + struct be_cb_ctx *cb_ctx; + + cb_ctx = talloc(be, struct be_cb_ctx); + if (!cb_ctx) { + DEBUG(0, ("Out of memory. Could not invoke callbacks\n")); + return ENOMEM; + } + cb_ctx->be = be; + cb_ctx->callback = cb_list; + + /* Delay 30ms so we don't block any other events */ + soon = tevent_timeval_current_ofs(0, 30000); + te = tevent_add_timer(be->ev, cb_ctx, soon, + be_run_cb_step, + cb_ctx); + if (!te) { + DEBUG(0, ("Out of memory. Could not invoke callbacks\n")); + talloc_free(cb_ctx); + return ENOMEM; + } + + return EOK; +} + +int be_add_online_cb(TALLOC_CTX *mem_ctx, struct be_ctx *ctx, be_callback_t cb, + void *pvt, struct be_cb **online_cb) +{ + int ret; + + ret = be_add_cb(mem_ctx, ctx, cb, pvt, &ctx->online_cb_list, online_cb); + if (ret != EOK) { + DEBUG(1, ("be_add_cb failed.\n")); + return ret; + } + + /* Make sure we run the callback for the first + * connection after startup. + */ + ctx->run_online_cb = true; + + return EOK; +} + +void be_run_online_cb(struct be_ctx *be) { + int ret; + + if (be->run_online_cb && be->online_cb_list) { + /* Reset the flag. We only want to run these + * callbacks when transitioning to online + */ + be->run_online_cb = false; + + DEBUG(3, ("Going online. Running callbacks.\n")); + + ret = be_run_cb(be, be->online_cb_list); + if (ret != EOK) { + DEBUG(1, ("be_run_cb failed.\n")); + } + + } else { + DEBUG(9, ("Online call back list is empty, nothing to do.\n")); + } +} diff --git a/src/providers/dp_backend.h b/src/providers/dp_backend.h index ec0510e..43d79ba 100644 --- a/src/providers/dp_backend.h +++ b/src/providers/dp_backend.h @@ -40,7 +40,7 @@ typedef void (*be_shutdown_fn)(void *); typedef void (*be_req_fn_t)(struct be_req *); typedef void (*be_async_callback_t)(struct be_req *, int, int, const char *); -typedef void (*be_conn_online_callback_t)(void *); +typedef void (*be_callback_t)(void *); enum bet_type { BET_NULL = 0, @@ -83,7 +83,7 @@ struct be_client { struct be_failover_ctx; -struct be_conn_online_cb; +struct be_cb; struct be_ctx { struct tevent_context *ev; @@ -97,7 +97,7 @@ struct be_ctx { /* Functions to be invoked when the * backend goes online */ - struct be_conn_online_cb *online_cb_list; + struct be_cb *online_cb_list; bool run_online_cb; struct be_offline_status offstat; @@ -143,9 +143,9 @@ void be_mark_offline(struct be_ctx *ctx); int be_add_online_cb(TALLOC_CTX *mem_ctx, struct be_ctx *ctx, - be_conn_online_callback_t cb, + be_callback_t cb, void *pvt, - struct be_conn_online_cb **online_cb); + struct be_cb **online_cb); void be_run_online_cb(struct be_ctx *be); /* from data_provider_fo.c */ -- 1.6.6.1