From 98076cabc2a8b8f71dc3bc1263519827f71a5fcc Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Thu, 5 Jan 2012 20:23:04 +0100 Subject: RESPONDERS: Refactor setent_req_list Makes the setent_add_ref() and setent_notify_*() functions more generic to be reusable by the autofs responder. --- src/responder/common/responder.h | 16 +++++--- src/responder/common/responder_cmd.c | 79 ++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 5 deletions(-) (limited to 'src/responder/common') diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h index 1c85b9d28..0eabe647d 100644 --- a/src/responder/common/responder.h +++ b/src/responder/common/responder.h @@ -94,11 +94,6 @@ struct resp_ctx { void *pvt_ctx; }; -/* Needed for the NSS responder */ -struct getent_ref_tracker { - void *pvt; -}; - struct cli_ctx { struct tevent_context *ev; struct resp_ctx *rctx; @@ -163,6 +158,17 @@ void sss_cmd_done(struct cli_ctx *cctx, void *freectx); int sss_cmd_get_version(struct cli_ctx *cctx); struct cli_protocol_version *register_cli_protocol_version(void); +struct setent_req_list; + +/* A facility for notifying setent requests */ +struct tevent_req *setent_get_req(struct setent_req_list *sl); +errno_t setent_add_ref(TALLOC_CTX *memctx, + void *pvt, + struct setent_req_list **list, + struct tevent_req *req); +void setent_notify(struct setent_req_list *list, errno_t err); +void setent_notify_done(struct setent_req_list *list); + typedef void (*sss_dp_callback_t)(uint16_t err_maj, uint32_t err_min, const char *err_msg, void *ptr); diff --git a/src/responder/common/responder_cmd.c b/src/responder/common/responder_cmd.c index bfac8f979..28315e060 100644 --- a/src/responder/common/responder_cmd.c +++ b/src/responder/common/responder_cmd.c @@ -155,3 +155,82 @@ int sss_cmd_execute(struct cli_ctx *cctx, struct sss_cmd_table *sss_cmds) return EINVAL; } + +struct setent_req_list { + struct setent_req_list *prev; + struct setent_req_list *next; + /* Need to point to the head of the list from a talloc destructor */ + struct setent_req_list *head; + + void *pvt; + + struct tevent_req *req; +}; + +struct tevent_req * +setent_get_req(struct setent_req_list *sl) +{ + return sl->req; +} + +int setent_remove_ref(TALLOC_CTX *ctx) +{ + struct setent_req_list *entry = + talloc_get_type(ctx, struct setent_req_list); + DLIST_REMOVE(entry->head, entry); + return 0; +} + +errno_t setent_add_ref(TALLOC_CTX *memctx, + void *pvt, + struct setent_req_list **list, + struct tevent_req *req) +{ + struct setent_req_list *entry; + + entry = talloc_zero(memctx, struct setent_req_list); + if (!entry) { + return ENOMEM; + } + + entry->req = req; + entry->pvt = pvt; + DLIST_ADD_END(*list, entry, struct setent_req_list *); + entry->head = *list; + + talloc_set_destructor((TALLOC_CTX *)entry, setent_remove_ref); + return EOK; +} + +void setent_notify(struct setent_req_list *list, errno_t err) +{ + struct setent_req_list *reql; + + /* Notify the waiting clients */ + while ((reql = list)) { + /* Each tevent_req_done() call will free + * the request, removing it from the list. + */ + if (err == EOK) { + tevent_req_done(reql->req); + } else { + tevent_req_error(reql->req, err); + } + + if (reql == list) { + /* The consumer failed to free the + * request. Log a bug and continue. + */ + DEBUG(SSSDBG_FATAL_FAILURE, + ("BUG: a callback did not free its request. " + "May leak memory\n")); + /* Skip to the next since a memory leak is non-fatal */ + list = list->next; + } + } +} + +void setent_notify_done(struct setent_req_list *list) +{ + return setent_notify(list, EOK); +} -- cgit