tevent: store the location where a request was finished
authorStefan Metzmacher <metze@samba.org>
Tue, 17 Mar 2009 19:13:34 +0000 (20:13 +0100)
committerStefan Metzmacher <metze@samba.org>
Tue, 17 Mar 2009 19:17:01 +0000 (20:17 +0100)
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.h
lib/tevent/tevent_internal.h
lib/tevent/tevent_req.c

index 3930092ee5930605d3a5f9df103489c5eab83edb..6c5df6321a5be6d972bc7588ed33f639773401ef 100644 (file)
@@ -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);
index 88bda244ac421651cb965115d6eb76118c5216ef..eebf76706773a51eb83d8cff158acba25a80ef9d 100644 (file)
@@ -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
index 444f7b330dccd1a7cf7a1cd34bcc539ec5f03604..380a6388e29bca675071d819894f55b2cae1d88b 100644 (file)
@@ -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,