summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMartin Schwenke <martin@meltin.net>2012-06-05 16:00:07 +1000
committerStefan Metzmacher <metze@samba.org>2012-06-08 19:00:05 +0200
commit796acbd9ffd20f13f320641b8a27f86624f3d701 (patch)
tree5185331f59a2197a68ada44ca27f8ab0435d2608 /lib
parent653cb76edfc3e9c2c426a6f8ec6ecfb253bd54d9 (diff)
downloadsamba-796acbd9ffd20f13f320641b8a27f86624f3d701.tar.gz
samba-796acbd9ffd20f13f320641b8a27f86624f3d701.tar.bz2
samba-796acbd9ffd20f13f320641b8a27f86624f3d701.zip
lib/tevent: Add trace point callback
Set/get a single callback function to be invoked at various trace points. Define "before wait" and "after wait" trace points - more trace points can be added later if required. CTDB wants this to log long waits and events. Pair-programmed-with: Amitay Isaacs <amitay@gmail.com> Signed-off-by: Martin Schwenke <martin@meltin.net> Signed-off-by: Stefan Metzmacher <metze@samba.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/tevent/tevent.h43
-rw-r--r--lib/tevent/tevent_debug.c23
-rw-r--r--lib/tevent/tevent_epoll.c2
-rw-r--r--lib/tevent/tevent_internal.h8
-rw-r--r--lib/tevent/tevent_poll.c2
-rw-r--r--lib/tevent/tevent_select.c2
-rw-r--r--lib/tevent/tevent_standard.c2
-rwxr-xr-x[-rw-r--r--]lib/tevent/wscript0
8 files changed, 82 insertions, 0 deletions
diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h
index c38f7c36e1..c8719fa4f1 100644
--- a/lib/tevent/tevent.h
+++ b/lib/tevent/tevent.h
@@ -501,6 +501,49 @@ int tevent_set_debug(struct tevent_context *ev,
*/
int tevent_set_debug_stderr(struct tevent_context *ev);
+enum tevent_trace_point {
+ /**
+ * Corresponds to a trace point just before waiting
+ */
+ TEVENT_TRACE_BEFORE_WAIT,
+ /**
+ * Corresponds to a trace point just after waiting
+ */
+ TEVENT_TRACE_AFTER_WAIT,
+};
+
+typedef void (*tevent_trace_callback_t)(enum tevent_trace_point,
+ void *private_data);
+
+/**
+ * Register a callback to be called at certain trace points
+ *
+ * @param[in] ev Event context
+ * @param[in] cb Trace callback
+ * @param[in] private_data Data to be passed to callback
+ *
+ * @note The callback will be called at trace points defined by
+ * tevent_trace_point. Call with NULL to reset.
+ */
+void tevent_set_trace_callback(struct tevent_context *ev,
+ tevent_trace_callback_t cb,
+ void *private_data);
+
+/**
+ * Retrieve the current trace callback
+ *
+ * @param[in] ev Event context
+ * @param[out] cb Registered trace callback
+ * @param[out] private_data Registered data to be passed to callback
+ *
+ * @note This can be used to allow one component that wants to
+ * register a callback to respect the callback that another component
+ * has already registered.
+ */
+void tevent_get_trace_callback(struct tevent_context *ev,
+ tevent_trace_callback_t *cb,
+ void *private_data);
+
/**
* @}
*/
diff --git a/lib/tevent/tevent_debug.c b/lib/tevent/tevent_debug.c
index 3f4112831a..31da7b9683 100644
--- a/lib/tevent/tevent_debug.c
+++ b/lib/tevent/tevent_debug.c
@@ -94,3 +94,26 @@ void tevent_debug(struct tevent_context *ev, enum tevent_debug_level level,
va_end(ap);
}
+void tevent_set_trace_callback(struct tevent_context *ev,
+ tevent_trace_callback_t cb,
+ void *private_data)
+{
+ ev->tracing.callback = cb;
+ ev->tracing.private_data = private_data;
+}
+
+void tevent_get_trace_callback(struct tevent_context *ev,
+ tevent_trace_callback_t *cb,
+ void *private_data)
+{
+ *cb = ev->tracing.callback;
+ *(void**)private_data = ev->tracing.private_data;
+}
+
+void tevent_trace_point_callback(struct tevent_context *ev,
+ enum tevent_trace_point tp)
+{
+ if (ev->tracing.callback != NULL) {
+ ev->tracing.callback(tp, ev->tracing.private_data);
+ }
+}
diff --git a/lib/tevent/tevent_epoll.c b/lib/tevent/tevent_epoll.c
index 33e1d3f20f..5f93de2c57 100644
--- a/lib/tevent/tevent_epoll.c
+++ b/lib/tevent/tevent_epoll.c
@@ -264,7 +264,9 @@ static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval
return 0;
}
+ tevent_trace_point_callback(epoll_ev->ev, TEVENT_TRACE_BEFORE_WAIT);
ret = epoll_wait(epoll_ev->epoll_fd, events, MAXEVENTS, timeout);
+ tevent_trace_point_callback(epoll_ev->ev, TEVENT_TRACE_AFTER_WAIT);
if (ret == -1 && errno == EINTR && epoll_ev->ev->signal_events) {
if (tevent_common_check_signal(epoll_ev->ev)) {
diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h
index 472beb5c94..877510f9f4 100644
--- a/lib/tevent/tevent_internal.h
+++ b/lib/tevent/tevent_internal.h
@@ -258,6 +258,11 @@ struct tevent_context {
tevent_nesting_hook hook_fn;
void *hook_private;
} nesting;
+
+ struct {
+ tevent_trace_callback_t callback;
+ void *private_data;
+ } tracing;
};
@@ -313,3 +318,6 @@ bool tevent_poll_init(void);
#ifdef HAVE_EPOLL
bool tevent_epoll_init(void);
#endif
+
+void tevent_trace_point_callback(struct tevent_context *ev,
+ enum tevent_trace_point);
diff --git a/lib/tevent/tevent_poll.c b/lib/tevent/tevent_poll.c
index 2e202aa7ec..7ae3c42188 100644
--- a/lib/tevent/tevent_poll.c
+++ b/lib/tevent/tevent_poll.c
@@ -201,7 +201,9 @@ static int poll_event_loop_poll(struct tevent_context *ev,
timeout += (tvalp->tv_usec + 999) / 1000;
}
+ tevent_trace_point_callback(poll_ev->ev, TEVENT_TRACE_BEFORE_WAIT);
pollrtn = poll(poll_ev->fds, poll_ev->num_fds, timeout);
+ tevent_trace_point_callback(poll_ev->ev, TEVENT_TRACE_AFTER_WAIT);
if (pollrtn == -1 && errno == EINTR && ev->signal_events) {
tevent_common_check_signal(ev);
diff --git a/lib/tevent/tevent_select.c b/lib/tevent/tevent_select.c
index 94faa86593..c11f0e8324 100644
--- a/lib/tevent/tevent_select.c
+++ b/lib/tevent/tevent_select.c
@@ -167,7 +167,9 @@ static int select_event_loop_select(struct select_event_context *select_ev, stru
return 0;
}
+ tevent_trace_point_callback(select_ev->ev, TEVENT_TRACE_BEFORE_WAIT);
selrtn = select(select_ev->maxfd+1, &r_fds, &w_fds, NULL, tvalp);
+ tevent_trace_point_callback(select_ev->ev, TEVENT_TRACE_AFTER_WAIT);
if (selrtn == -1 && errno == EINTR &&
select_ev->ev->signal_events) {
diff --git a/lib/tevent/tevent_standard.c b/lib/tevent/tevent_standard.c
index e2ca44f9c2..1e33720f70 100644
--- a/lib/tevent/tevent_standard.c
+++ b/lib/tevent/tevent_standard.c
@@ -278,7 +278,9 @@ static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tv
return 0;
}
+ tevent_trace_point_callback(std_ev->ev, TEVENT_TRACE_BEFORE_WAIT);
ret = epoll_wait(std_ev->epoll_fd, events, MAXEVENTS, timeout);
+ tevent_trace_point_callback(std_ev->ev, TEVENT_TRACE_AFTER_WAIT);
if (ret == -1 && errno == EINTR && std_ev->ev->signal_events) {
if (tevent_common_check_signal(std_ev->ev)) {
diff --git a/lib/tevent/wscript b/lib/tevent/wscript
index 2e6c2a6e6e..2e6c2a6e6e 100644..100755
--- a/lib/tevent/wscript
+++ b/lib/tevent/wscript