From: Stephan Bosch Date: Sun, 11 Mar 2018 18:18:06 +0000 (+0100) Subject: lib-auth-client: auth-master - Add support for request destroy callback X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e820fc0f5d94238252d396517bf799fbed53e6a3;p=thirdparty%2Fdovecot%2Fcore.git lib-auth-client: auth-master - Add support for request destroy callback --- diff --git a/src/lib-auth-client/auth-master-private.h b/src/lib-auth-client/auth-master-private.h index d8f0fb04a1..e9fed3c2df 100644 --- a/src/lib-auth-client/auth-master-private.h +++ b/src/lib-auth-client/auth-master-private.h @@ -19,6 +19,11 @@ enum auth_master_request_state { AUTH_MASTER_REQUEST_STATE_ABORTED, }; +struct auth_master_request_destroy_callback { + auth_master_request_destroy_callback_t *callback; + void *context; +}; + struct auth_master_request { int refcount; pool_t pool; @@ -39,6 +44,8 @@ struct auth_master_request { auth_master_request_callback_t *callback; void *context; + ARRAY(struct auth_master_request_destroy_callback) destroy_callbacks; + bool sent:1; bool aborted:1; bool removed:1; diff --git a/src/lib-auth-client/auth-master-request.c b/src/lib-auth-client/auth-master-request.c index 7b80a58e8d..8c7a1636ff 100644 --- a/src/lib-auth-client/auth-master-request.c +++ b/src/lib-auth-client/auth-master-request.c @@ -61,6 +61,7 @@ static void auth_master_request_ref(struct auth_master_request *req) static bool auth_master_request_unref(struct auth_master_request **_req) { struct auth_master_request *req = *_req; + const struct auth_master_request_destroy_callback *dc; *_req = NULL; @@ -72,6 +73,13 @@ static bool auth_master_request_unref(struct auth_master_request **_req) return TRUE; auth_master_request_remove(req); + + if (array_is_created(&req->destroy_callbacks)) { + array_foreach(&req->destroy_callbacks, dc) + dc->callback(dc->context); + array_free(&req->destroy_callbacks); + } + event_unref(&req->event); pool_unref(&req->pool); return FALSE; @@ -400,3 +408,34 @@ unsigned int auth_master_request_count(struct auth_master_connection *conn) { return conn->requests_count; } + +#undef auth_master_request_add_destroy_callback +void auth_master_request_add_destroy_callback( + struct auth_master_request *req, + auth_master_request_destroy_callback_t *callback, void *context) +{ + struct auth_master_request_destroy_callback *dc; + + if (!array_is_created(&req->destroy_callbacks)) + i_array_init(&req->destroy_callbacks, 2); + dc = array_append_space(&req->destroy_callbacks); + dc->callback = callback; + dc->context = context; +} + +void auth_master_request_remove_destroy_callback( + struct auth_master_request *req, + auth_master_request_destroy_callback_t *callback) +{ + const struct auth_master_request_destroy_callback *dcs; + unsigned int i, count; + + dcs = array_get(&req->destroy_callbacks, &count); + for (i = 0; i < count; i++) { + if (dcs[i].callback == callback) { + array_delete(&req->destroy_callbacks, i, 1); + return; + } + } + i_unreached(); +} diff --git a/src/lib-auth-client/auth-master.h b/src/lib-auth-client/auth-master.h index 693f0ebf99..e7765f95bd 100644 --- a/src/lib-auth-client/auth-master.h +++ b/src/lib-auth-client/auth-master.h @@ -28,6 +28,8 @@ struct auth_master_reply { const char *errormsg; }; +typedef void +auth_master_request_destroy_callback_t(void *context); /* Returns 1 upon full completion, 0 upon successful partial completion (will be called again) and -1 upon error. */ typedef int @@ -55,6 +57,20 @@ bool auth_master_request_wait(struct auth_master_request *req); unsigned int auth_master_request_count(struct auth_master_connection *conn); +/* Call the given callback function when the request is destroyed. */ +void auth_master_request_add_destroy_callback( + struct auth_master_request *req, + auth_master_request_destroy_callback_t *callback, void *context) + ATTR_NULL(3); +#define auth_master_request_add_destroy_callback(stream, callback, context) \ + auth_master_request_add_destroy_callback(stream + \ + CALLBACK_TYPECHECK(callback, void (*)(typeof(context))), \ + (auth_master_request_destroy_callback_t *)callback, context) +/* Remove the destroy callback. */ +void auth_master_request_remove_destroy_callback( + struct auth_master_request *req, + auth_master_request_destroy_callback_t *callback); + /* * Connection */