From 67d41d0fc7567cf141b12e866dd227d393e33551 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 28 Feb 2009 15:44:30 -0500 Subject: Make struct tevent_req opaque Move struct tevent_req in tevent_internal, and ad getters and setters for private data and the callback function. This patch also renames 'private_state' into 'data'. What is held in this pointer is in fact data and not a state like enum tevent_req_state. Calling it 'state' is confusing. The functions addedd are: tevent_req_set_callback() - sets req->async.fn and req->async.private_data tevent_req_set_print_fn() - sets req->private_print tevent_req_callback_data() - gets req->async.private_data tevent_req_data() - gets rea->data This way it is much simpler to keep API/ABI compatibility in the future. --- lib/tevent/tevent_req.c | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) (limited to 'lib/tevent/tevent_req.c') diff --git a/lib/tevent/tevent_req.c b/lib/tevent/tevent_req.c index e243c7de5d..9b3e00ec8f 100644 --- a/lib/tevent/tevent_req.c +++ b/lib/tevent/tevent_req.c @@ -47,8 +47,8 @@ char *tevent_req_default_print(struct tevent_req *req, TALLOC_CTX *mem_ctx) req->internal.state, (unsigned long long)req->internal.error, (unsigned long long)req->internal.error, - talloc_get_name(req->private_state), - req->private_state, + talloc_get_name(req->data), + req->data, req->internal.timer ); } @@ -81,14 +81,14 @@ char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req) */ struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx, - void *pstate, - size_t state_size, + void *pdata, + size_t data_size, const char *type, const char *location) { struct tevent_req *req; - void **ppstate = (void **)pstate; - void *state; + void **ppdata = (void **)pdata; + void *data; req = talloc_zero(mem_ctx, struct tevent_req); if (req == NULL) { @@ -98,16 +98,16 @@ struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx, req->internal.location = location; req->internal.state = TEVENT_REQ_IN_PROGRESS; - state = talloc_size(req, state_size); - if (state == NULL) { + data = talloc_size(req, data_size); + if (data == NULL) { talloc_free(req); return NULL; } - talloc_set_name_const(state, type); + talloc_set_name_const(data, type); - req->private_state = state; + req->data = data; - *ppstate = state; + *ppdata = data; return req; } @@ -314,3 +314,23 @@ bool tevent_req_set_endtime(struct tevent_req *req, return true; } +void tevent_req_set_callback(struct tevent_req *req, tevent_req_fn fn, void *pvt) +{ + req->async.fn = fn; + req->async.private_data = pvt; +} + +void *_tevent_req_callback_data(struct tevent_req *req) +{ + return req->async.private_data; +} + +void *_tevent_req_data(struct tevent_req *req) +{ + return req->data; +} + +void tevent_req_set_print_fn(struct tevent_req *req, tevent_req_print_fn fn) +{ + req->private_print = fn; +} -- cgit From 09d1b2324cf02c20daa005e6f5d55dc107303af7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 10 Mar 2009 13:54:57 +0100 Subject: tevent: add tevent_req_received() function This function can be called as last action of a _recv() function, it destroys the data attached to the tevent_req. metze --- lib/tevent/tevent_req.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'lib/tevent/tevent_req.c') diff --git a/lib/tevent/tevent_req.c b/lib/tevent/tevent_req.c index 9b3e00ec8f..3832088b34 100644 --- a/lib/tevent/tevent_req.c +++ b/lib/tevent/tevent_req.c @@ -256,6 +256,27 @@ bool tevent_req_is_in_progress(struct tevent_req *req) return false; } +/** + * @brief This function destroys the attached private data + * @param[in] req The finished request + * + * This function can be called as last action of a _recv() + * function, it destroys the data attached to the tevent_req. + */ +void tevent_req_received(struct tevent_req *req) +{ + talloc_free(req->data); + req->data = NULL; + req->private_print = NULL; + + talloc_free(req->internal.trigger); + req->internal.trigger = NULL; + talloc_free(req->internal.timer); + req->internal.timer = NULL; + + req->internal.state = TEVENT_REQ_RECEIVED; +} + bool tevent_req_poll(struct tevent_req *req, struct tevent_context *ev) { -- cgit From a78cd2a24b818bc7d843a8e56ffaafc9f6578662 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Mar 2009 10:17:50 +0100 Subject: tevent: use TALLOC_FREE() in tevent_req.c metze --- lib/tevent/tevent_req.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'lib/tevent/tevent_req.c') diff --git a/lib/tevent/tevent_req.c b/lib/tevent/tevent_req.c index 3832088b34..3514f31514 100644 --- a/lib/tevent/tevent_req.c +++ b/lib/tevent/tevent_req.c @@ -265,14 +265,11 @@ bool tevent_req_is_in_progress(struct tevent_req *req) */ void tevent_req_received(struct tevent_req *req) { - talloc_free(req->data); - req->data = NULL; + TALLOC_FREE(req->data); req->private_print = NULL; - talloc_free(req->internal.trigger); - req->internal.trigger = NULL; - talloc_free(req->internal.timer); - req->internal.timer = NULL; + TALLOC_FREE(req->internal.trigger); + TALLOC_FREE(req->internal.timer); req->internal.state = TEVENT_REQ_RECEIVED; } @@ -313,8 +310,7 @@ static void tevent_req_timedout(struct tevent_context *ev, struct tevent_req *req = talloc_get_type(private_data, struct tevent_req); - talloc_free(req->internal.timer); - req->internal.timer = NULL; + TALLOC_FREE(req->internal.timer); tevent_req_finish(req, TEVENT_REQ_TIMED_OUT); } @@ -323,7 +319,7 @@ bool tevent_req_set_endtime(struct tevent_req *req, struct tevent_context *ev, struct timeval endtime) { - talloc_free(req->internal.timer); + TALLOC_FREE(req->internal.timer); req->internal.timer = tevent_add_timer(ev, req, endtime, tevent_req_timedout, -- cgit From 4bdf299385220988a4fe16f82aab528283204c7f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Mar 2009 10:18:34 +0100 Subject: tevent: use an immediate event fot tevent_req_post() Now tevent_req_post() never fails metze --- lib/tevent/tevent_req.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) (limited to 'lib/tevent/tevent_req.c') diff --git a/lib/tevent/tevent_req.c b/lib/tevent/tevent_req.c index 3514f31514..444f7b330d 100644 --- a/lib/tevent/tevent_req.c +++ b/lib/tevent/tevent_req.c @@ -97,6 +97,11 @@ struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx, req->internal.private_type = type; req->internal.location = location; req->internal.state = TEVENT_REQ_IN_PROGRESS; + req->internal.trigger = tevent_create_immediate(req); + if (!req->internal.trigger) { + talloc_free(req); + return NULL; + } data = talloc_size(req, data_size); if (data == NULL) { @@ -199,23 +204,18 @@ bool tevent_req_nomem(const void *p, struct tevent_req *req) } /** - * @brief Timed event callback + * @brief Immediate event callback * @param[in] ev Event context - * @param[in] te The timed event - * @param[in] now zero time + * @param[in] im The immediate event * @param[in] priv The async request to be finished */ static void tevent_req_trigger(struct tevent_context *ev, - struct tevent_timer *te, - struct timeval zero, + struct tevent_immediate *im, void *private_data) { struct tevent_req *req = talloc_get_type(private_data, struct tevent_req); - talloc_free(req->internal.trigger); - req->internal.trigger = NULL; - tevent_req_finish(req, req->internal.state); } @@ -223,8 +223,7 @@ static void tevent_req_trigger(struct tevent_context *ev, * @brief Finish a request before the caller had the change to set the callback * @param[in] req The finished request * @param[in] ev The tevent_context for the timed event - * @retval On success req will be returned, - * on failure req will be destroyed + * @retval req will be returned * * An implementation of an async request might find that it can either finish * the request without waiting for an external event, or it can't even start @@ -237,13 +236,8 @@ static void tevent_req_trigger(struct tevent_context *ev, struct tevent_req *tevent_req_post(struct tevent_req *req, struct tevent_context *ev) { - req->internal.trigger = tevent_add_timer(ev, req, tevent_timeval_zero(), - tevent_req_trigger, req); - if (!req->internal.trigger) { - talloc_free(req); - return NULL; - } - + tevent_schedule_immediate(req->internal.trigger, + ev, tevent_req_trigger, req); return req; } -- cgit From 9eaf53d98eced9ea70f411b9936b475c42e4d490 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Mar 2009 20:13:34 +0100 Subject: tevent: store the location where a request was finished This is very useful to find bugs. You can use 'p *req' in gdb to show where tevent_req_done(), tevent_req_error() or tevent_req_nomem() was called. metze --- lib/tevent/tevent_req.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'lib/tevent/tevent_req.c') diff --git a/lib/tevent/tevent_req.c b/lib/tevent/tevent_req.c index 444f7b330d..380a6388e2 100644 --- a/lib/tevent/tevent_req.c +++ b/lib/tevent/tevent_req.c @@ -43,7 +43,7 @@ char *tevent_req_default_print(struct tevent_req *req, TALLOC_CTX *mem_ctx) return talloc_asprintf(mem_ctx, "tevent_req[%p/%s]: state[%d] error[%lld (0x%llX)] " " state[%s (%p)] timer[%p]", - req, req->internal.location, + req, req->internal.create_location, req->internal.state, (unsigned long long)req->internal.error, (unsigned long long)req->internal.error, @@ -95,7 +95,8 @@ struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx, return NULL; } req->internal.private_type = type; - req->internal.location = location; + req->internal.create_location = location; + req->internal.finish_location = NULL; req->internal.state = TEVENT_REQ_IN_PROGRESS; req->internal.trigger = tevent_create_immediate(req); if (!req->internal.trigger) { @@ -116,9 +117,12 @@ struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx, return req; } -static void tevent_req_finish(struct tevent_req *req, enum tevent_req_state state) +static void tevent_req_finish(struct tevent_req *req, + enum tevent_req_state state, + const char *location) { req->internal.state = state; + req->internal.finish_location = location; if (req->async.fn != NULL) { req->async.fn(req); } @@ -133,9 +137,10 @@ static void tevent_req_finish(struct tevent_req *req, enum tevent_req_state stat * function. */ -void tevent_req_done(struct tevent_req *req) +void _tevent_req_done(struct tevent_req *req, + const char *location) { - tevent_req_finish(req, TEVENT_REQ_DONE); + tevent_req_finish(req, TEVENT_REQ_DONE, location); } /** @@ -166,14 +171,16 @@ void tevent_req_done(struct tevent_req *req) * \endcode */ -bool tevent_req_error(struct tevent_req *req, uint64_t error) +bool _tevent_req_error(struct tevent_req *req, + uint64_t error, + const char *location) { if (error == 0) { return false; } req->internal.error = error; - tevent_req_finish(req, TEVENT_REQ_USER_ERROR); + tevent_req_finish(req, TEVENT_REQ_USER_ERROR, location); return true; } @@ -194,12 +201,14 @@ bool tevent_req_error(struct tevent_req *req, uint64_t error) * \endcode */ -bool tevent_req_nomem(const void *p, struct tevent_req *req) +bool _tevent_req_nomem(const void *p, + struct tevent_req *req, + const char *location) { if (p != NULL) { return false; } - tevent_req_finish(req, TEVENT_REQ_NO_MEMORY); + tevent_req_finish(req, TEVENT_REQ_NO_MEMORY, location); return true; } @@ -216,7 +225,8 @@ static void tevent_req_trigger(struct tevent_context *ev, struct tevent_req *req = talloc_get_type(private_data, struct tevent_req); - tevent_req_finish(req, req->internal.state); + tevent_req_finish(req, req->internal.state, + req->internal.finish_location); } /** @@ -306,7 +316,7 @@ static void tevent_req_timedout(struct tevent_context *ev, TALLOC_FREE(req->internal.timer); - tevent_req_finish(req, TEVENT_REQ_TIMED_OUT); + tevent_req_finish(req, TEVENT_REQ_TIMED_OUT, __FUNCTION__); } bool tevent_req_set_endtime(struct tevent_req *req, -- cgit