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_cmd.c | 79 ++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) (limited to 'src/responder/common/responder_cmd.c') diff --git a/src/responder/common/responder_cmd.c b/src/responder/common/responder_cmd.c index bfac8f97..28315e06 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