From: Pavel Filipenský Date: Mon, 14 Mar 2022 10:22:15 +0000 (+0100) Subject: tevent: Add tevent queue tracing support X-Git-Tag: tevent-0.12.0~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f681ef2ff48b5b48fd1f0a2075184689059cb9a1;p=thirdparty%2Fsamba.git tevent: Add tevent queue tracing support Signed-off-by: Pavel Filipenský Reviewed-by: Stefan Metzmacher Reviewed-by: Andreas Schneider --- diff --git a/lib/tevent/ABI/tevent-0.12.0.sigs b/lib/tevent/ABI/tevent-0.12.0.sigs new file mode 100644 index 00000000000..22a8ce33413 --- /dev/null +++ b/lib/tevent/ABI/tevent-0.12.0.sigs @@ -0,0 +1,151 @@ +_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +_tevent_context_pop_use: void (struct tevent_context *, const char *) +_tevent_context_push_use: bool (struct tevent_context *, const char *) +_tevent_context_wrapper_create: struct tevent_context *(struct tevent_context *, TALLOC_CTX *, const struct tevent_wrapper_ops *, void *, size_t, const char *, const char *) +_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *) +_tevent_loop_once: int (struct tevent_context *, const char *) +_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *) +_tevent_loop_wait: int (struct tevent_context *, const char *) +_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *) +_tevent_req_callback_data: void *(struct tevent_req *) +_tevent_req_cancel: bool (struct tevent_req *, const char *) +_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *) +_tevent_req_data: void *(struct tevent_req *) +_tevent_req_done: void (struct tevent_req *, const char *) +_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *) +_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *) +_tevent_req_notify_callback: void (struct tevent_req *, const char *) +_tevent_req_oom: void (struct tevent_req *, const char *) +_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +_tevent_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_abort: void (struct tevent_context *, const char *) +tevent_backend_list: const char **(TALLOC_CTX *) +tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *) +tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *) +tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *) +tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *) +tevent_common_check_double_free: void (TALLOC_CTX *, const char *) +tevent_common_check_signal: int (struct tevent_context *) +tevent_common_context_destructor: int (struct tevent_context *) +tevent_common_fd_destructor: int (struct tevent_fd *) +tevent_common_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_common_have_events: bool (struct tevent_context *) +tevent_common_invoke_fd_handler: int (struct tevent_fd *, uint16_t, bool *) +tevent_common_invoke_immediate_handler: int (struct tevent_immediate *, bool *) +tevent_common_invoke_signal_handler: int (struct tevent_signal *, int, int, void *, bool *) +tevent_common_invoke_timer_handler: int (struct tevent_timer *, struct timeval, bool *) +tevent_common_loop_immediate: bool (struct tevent_context *) +tevent_common_loop_timer_delay: struct timeval (struct tevent_context *) +tevent_common_loop_wait: int (struct tevent_context *, const char *) +tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *) +tevent_common_threaded_activate_immediate: void (struct tevent_context *) +tevent_common_wakeup: int (struct tevent_context *) +tevent_common_wakeup_fd: int (int) +tevent_common_wakeup_init: int (struct tevent_context *) +tevent_context_init: struct tevent_context *(TALLOC_CTX *) +tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *) +tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *) +tevent_context_is_wrapper: bool (struct tevent_context *) +tevent_context_same_loop: bool (struct tevent_context *, struct tevent_context *) +tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (struct tevent_fd *) +tevent_fd_get_tag: uint64_t (const struct tevent_fd *) +tevent_fd_set_auto_close: void (struct tevent_fd *) +tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t) +tevent_fd_set_flags: void (struct tevent_fd *, uint16_t) +tevent_fd_set_tag: void (struct tevent_fd *, uint64_t) +tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +tevent_get_trace_fd_callback: void (struct tevent_context *, tevent_trace_fd_callback_t *, void *) +tevent_get_trace_immediate_callback: void (struct tevent_context *, tevent_trace_immediate_callback_t *, void *) +tevent_get_trace_queue_callback: void (struct tevent_context *, tevent_trace_queue_callback_t *, void *) +tevent_get_trace_signal_callback: void (struct tevent_context *, tevent_trace_signal_callback_t *, void *) +tevent_get_trace_timer_callback: void (struct tevent_context *, tevent_trace_timer_callback_t *, void *) +tevent_immediate_get_tag: uint64_t (const struct tevent_immediate *) +tevent_immediate_set_tag: void (struct tevent_immediate *, uint64_t) +tevent_queue_entry_get_tag: uint64_t (const struct tevent_queue_entry *) +tevent_queue_entry_set_tag: void (struct tevent_queue_entry *, uint64_t) +tevent_loop_allow_nesting: void (struct tevent_context *) +tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *) +tevent_num_signals: size_t (void) +tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *) +tevent_queue_entry_untrigger: void (struct tevent_queue_entry *) +tevent_queue_length: size_t (struct tevent_queue *) +tevent_queue_running: bool (struct tevent_queue *) +tevent_queue_start: void (struct tevent_queue *) +tevent_queue_stop: void (struct tevent_queue *) +tevent_queue_wait_recv: bool (struct tevent_req *) +tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *) +tevent_re_initialise: int (struct tevent_context *) +tevent_register_backend: bool (const char *, const struct tevent_ops *) +tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *) +tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *) +tevent_req_get_profile: const struct tevent_req_profile *(struct tevent_req *) +tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +tevent_req_move_profile: struct tevent_req_profile *(struct tevent_req *, TALLOC_CTX *) +tevent_req_poll: bool (struct tevent_req *, struct tevent_context *) +tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *) +tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *) +tevent_req_profile_append_sub: void (struct tevent_req_profile *, struct tevent_req_profile **) +tevent_req_profile_create: struct tevent_req_profile *(TALLOC_CTX *) +tevent_req_profile_get_name: void (const struct tevent_req_profile *, const char **) +tevent_req_profile_get_start: void (const struct tevent_req_profile *, const char **, struct timeval *) +tevent_req_profile_get_status: void (const struct tevent_req_profile *, pid_t *, enum tevent_req_state *, uint64_t *) +tevent_req_profile_get_stop: void (const struct tevent_req_profile *, const char **, struct timeval *) +tevent_req_profile_get_subprofiles: const struct tevent_req_profile *(const struct tevent_req_profile *) +tevent_req_profile_next: const struct tevent_req_profile *(const struct tevent_req_profile *) +tevent_req_profile_set_name: bool (struct tevent_req_profile *, const char *) +tevent_req_profile_set_start: bool (struct tevent_req_profile *, const char *, struct timeval) +tevent_req_profile_set_status: void (struct tevent_req_profile *, pid_t, enum tevent_req_state, uint64_t) +tevent_req_profile_set_stop: bool (struct tevent_req_profile *, const char *, struct timeval) +tevent_req_received: void (struct tevent_req *) +tevent_req_reset_endtime: void (struct tevent_req *) +tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *) +tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn) +tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn) +tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) +tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) +tevent_req_set_profile: bool (struct tevent_req *) +tevent_sa_info_queue_count: size_t (void) +tevent_set_abort_fn: void (void (*)(const char *)) +tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *) +tevent_set_debug_stderr: int (struct tevent_context *) +tevent_set_default_backend: void (const char *) +tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *) +tevent_set_trace_fd_callback: void (struct tevent_context *, tevent_trace_fd_callback_t, void *) +tevent_set_trace_immediate_callback: void (struct tevent_context *, tevent_trace_immediate_callback_t, void *) +tevent_set_trace_queue_callback: void (struct tevent_context *, tevent_trace_queue_callback_t, void *) +tevent_set_trace_signal_callback: void (struct tevent_context *, tevent_trace_signal_callback_t, void *) +tevent_set_trace_timer_callback: void (struct tevent_context *, tevent_trace_timer_callback_t, void *) +tevent_signal_get_tag: uint64_t (const struct tevent_signal *) +tevent_signal_set_tag: void (struct tevent_signal *, uint64_t) +tevent_signal_support: bool (struct tevent_context *) +tevent_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) +tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) +tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, struct tevent_context *) +tevent_timer_get_tag: uint64_t (const struct tevent_timer *) +tevent_timer_set_tag: void (struct tevent_timer *, uint64_t) +tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t) +tevent_timeval_compare: int (const struct timeval *, const struct timeval *) +tevent_timeval_current: struct timeval (void) +tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t) +tevent_timeval_is_zero: bool (const struct timeval *) +tevent_timeval_set: struct timeval (uint32_t, uint32_t) +tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *) +tevent_timeval_zero: struct timeval (void) +tevent_trace_fd_callback: void (struct tevent_context *, struct tevent_fd *, enum tevent_event_trace_point) +tevent_trace_immediate_callback: void (struct tevent_context *, struct tevent_immediate *, enum tevent_event_trace_point) +tevent_trace_queue_callback: void (struct tevent_context *, struct tevent_queue_entry *, enum tevent_event_trace_point) +tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point) +tevent_trace_signal_callback: void (struct tevent_context *, struct tevent_signal *, enum tevent_event_trace_point) +tevent_trace_timer_callback: void (struct tevent_context *, struct tevent_timer *, enum tevent_event_trace_point) +tevent_update_timer: void (struct tevent_timer *, struct timeval) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h index 9edf7bc3488..1c337adbf74 100644 --- a/lib/tevent/tevent.h +++ b/lib/tevent/tevent.h @@ -1931,6 +1931,55 @@ struct timeval tevent_timeval_current_ofs(uint32_t secs, uint32_t usecs); struct tevent_queue; struct tevent_queue_entry; +/** + * @brief Associate a custom tag with the queue entry. + * + * This tag can be then retrieved with tevent_queue_entry_get_tag() + * + * @param[in] qe The queue entry. + * + * @param[in] tag Custom tag. + */ +void tevent_queue_entry_set_tag(struct tevent_queue_entry *qe, uint64_t tag); + +/** + * @brief Get custom queue entry tag. + */ +uint64_t tevent_queue_entry_get_tag(const struct tevent_queue_entry *qe); + +typedef void (*tevent_trace_queue_callback_t)(struct tevent_queue_entry *qe, + enum tevent_event_trace_point, + void *private_data); + +/** + * Register a callback to be called at certain trace points of queue. + * + * @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_event_trace_point. Call with NULL to reset. + */ +void tevent_set_trace_queue_callback(struct tevent_context *ev, + tevent_trace_queue_callback_t cb, + void *private_data); + +/** + * Retrieve the current trace callback of queue. + * + * @param[in] ev Event context + * @param[out] cb Registered trace callback + * @param[out] p_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_queue_callback(struct tevent_context *ev, + tevent_trace_queue_callback_t *cb, + void *p_private_data); + #ifdef DOXYGEN /** * @brief Create and start a tevent queue. diff --git a/lib/tevent/tevent_debug.c b/lib/tevent/tevent_debug.c index 44f76f789ca..6b8f2d5100b 100644 --- a/lib/tevent/tevent_debug.c +++ b/lib/tevent/tevent_debug.c @@ -260,3 +260,35 @@ void tevent_trace_immediate_callback(struct tevent_context *ev, ev->tracing.im.callback(im, tp, ev->tracing.im.private_data); } } + +void tevent_set_trace_queue_callback(struct tevent_context *ev, + tevent_trace_queue_callback_t cb, + void *private_data) +{ + if (ev->wrapper.glue != NULL) { + ev = tevent_wrapper_main_ev(ev); + tevent_abort(ev, "tevent_set_trace_queue_callback() " + "on wrapper"); + return; + } + + ev->tracing.qe.callback = cb; + ev->tracing.qe.private_data = private_data; +} + +void tevent_get_trace_queue_callback(struct tevent_context *ev, + tevent_trace_queue_callback_t *cb, + void *p_private_data) +{ + *cb = ev->tracing.qe.callback; + *(void**)p_private_data = ev->tracing.qe.private_data; +} + +void tevent_trace_queue_callback(struct tevent_context *ev, + struct tevent_queue_entry *qe, + enum tevent_event_trace_point tp) +{ + if (ev->tracing.qe.callback != NULL) { + ev->tracing.qe.callback(qe, tp, ev->tracing.qe.private_data); + } +} diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h index 7608a2d66be..3ca7fe1aa62 100644 --- a/lib/tevent/tevent_internal.h +++ b/lib/tevent/tevent_internal.h @@ -366,6 +366,11 @@ struct tevent_context { tevent_trace_immediate_callback_t callback; void *private_data; } im; + + struct { + tevent_trace_queue_callback_t callback; + void *private_data; + } qe; } tracing; struct { @@ -516,3 +521,7 @@ void tevent_trace_timer_callback(struct tevent_context *ev, void tevent_trace_immediate_callback(struct tevent_context *ev, struct tevent_immediate *im, enum tevent_event_trace_point); + +void tevent_trace_queue_callback(struct tevent_context *ev, + struct tevent_queue_entry *qe, + enum tevent_event_trace_point); diff --git a/lib/tevent/tevent_queue.c b/lib/tevent/tevent_queue.c index ad68643c69f..dffe30fdcfb 100644 --- a/lib/tevent/tevent_queue.c +++ b/lib/tevent/tevent_queue.c @@ -38,6 +38,7 @@ struct tevent_queue_entry { tevent_queue_trigger_fn_t trigger; void *private_data; + uint64_t tag; }; struct tevent_queue { @@ -63,6 +64,7 @@ static int tevent_queue_entry_destructor(struct tevent_queue_entry *e) return 0; } + tevent_trace_queue_callback(q->list->ev, e, TEVENT_EVENT_TRACE_DETACH); DLIST_REMOVE(q->list, e); q->length--; @@ -145,6 +147,8 @@ static void tevent_queue_immediate_trigger(struct tevent_context *ev, return; } + tevent_trace_queue_callback(ev, q->list, + TEVENT_EVENT_TRACE_BEFORE_HANDLER); q->list->triggered = true; q->list->trigger(q->list->req, q->list->private_data); } @@ -204,6 +208,7 @@ static struct tevent_queue_entry *tevent_queue_add_internal( DLIST_ADD_END(queue->list, e); queue->length++; talloc_set_destructor(e, tevent_queue_entry_destructor); + tevent_trace_queue_callback(ev, e, TEVENT_EVENT_TRACE_ATTACH); if (!queue->running) { return e; @@ -219,6 +224,9 @@ static struct tevent_queue_entry *tevent_queue_add_internal( * an immediate event. */ if (allow_direct) { + tevent_trace_queue_callback(ev, + queue->list, + TEVENT_EVENT_TRACE_BEFORE_HANDLER); queue->list->triggered = true; queue->list->trigger(queue->list->req, queue->list->private_data); @@ -374,3 +382,21 @@ bool tevent_queue_wait_recv(struct tevent_req *req) tevent_req_received(req); return true; } + +void tevent_queue_entry_set_tag(struct tevent_queue_entry *qe, uint64_t tag) +{ + if (qe == NULL) { + return; + } + + qe->tag = tag; +} + +uint64_t tevent_queue_entry_get_tag(const struct tevent_queue_entry *qe) +{ + if (qe == NULL) { + return 0; + } + + return qe->tag; +} diff --git a/lib/tevent/wscript b/lib/tevent/wscript index 3d0d71df140..308655e047f 100644 --- a/lib/tevent/wscript +++ b/lib/tevent/wscript @@ -1,7 +1,7 @@ #!/usr/bin/env python APPNAME = 'tevent' -VERSION = '0.11.0' +VERSION = '0.12.0' import sys, os