From: Stefan Metzmacher Date: Tue, 17 Mar 2009 19:13:34 +0000 (+0100) Subject: tevent: store the location where a request was finished X-Git-Tag: tdb-1.1.5~1075^2~96 X-Git-Url: http://git.samba.org/samba.git/?p=ira%2Fwip.git;a=commitdiff_plain;h=9eaf53d98eced9ea70f411b9936b475c42e4d490 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 --- diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h index 3930092ee59..6c5df6321a5 100644 --- a/lib/tevent/tevent.h +++ b/lib/tevent/tevent.h @@ -252,13 +252,22 @@ bool tevent_req_set_endtime(struct tevent_req *req, struct tevent_context *ev, struct timeval endtime); -void tevent_req_done(struct tevent_req *req); - -bool tevent_req_error(struct tevent_req *req, - uint64_t error); - -bool tevent_req_nomem(const void *p, - struct tevent_req *req); +void _tevent_req_done(struct tevent_req *req, + const char *location); +#define tevent_req_done(req) \ + _tevent_req_done(req, __location__) + +bool _tevent_req_error(struct tevent_req *req, + uint64_t error, + const char *location); +#define tevent_req_error(req, error) \ + _tevent_req_error(req, error, __location__) + +bool _tevent_req_nomem(const void *p, + struct tevent_req *req, + const char *location); +#define tevent_req_nomem(p, req) \ + _tevent_req_nomem(p, req, __location__) struct tevent_req *tevent_req_post(struct tevent_req *req, struct tevent_context *ev); diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h index 88bda244ac4..eebf7670677 100644 --- a/lib/tevent/tevent_internal.h +++ b/lib/tevent/tevent_internal.h @@ -85,7 +85,17 @@ struct tevent_req { * * This for debugging only. */ - const char *location; + const char *create_location; + + /** + * @brief The location where the request was finished + * + * This uses the __location__ macro via the tevent_req_done(), + * tevent_req_error() or tevent_req_nomem() macro. + * + * This for debugging only. + */ + const char *finish_location; /** * @brief The external state - will be queried by the caller diff --git a/lib/tevent/tevent_req.c b/lib/tevent/tevent_req.c index 444f7b330dc..380a6388e29 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,