From fc9dd8ce9f0ae2a7ae972035e56c4c4f9028e261 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20B=C5=99ezina?= Date: Tue, 1 Jun 2021 13:57:45 +0200 Subject: tevent: add custom tag to events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a new API to set and get an uint64_t tag on fd, timer, signal and immediate events. This can be used to assign a unique and known id to the event to allow easy tracking of such event. Pair-Programmed-With: Stefan Metzmacher Signed-off-by: Pavel Březina Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider --- lib/tevent/ABI/tevent-0.10.2.sigs | 8 ++ lib/tevent/tests/test_tevent_tag.c | 212 +++++++++++++++++++++++++++++++++++++ lib/tevent/tevent.h | 64 +++++++++++ lib/tevent/tevent_fd.c | 18 ++++ lib/tevent/tevent_immediate.c | 20 ++++ lib/tevent/tevent_internal.h | 8 ++ lib/tevent/tevent_signal.c | 18 ++++ lib/tevent/tevent_timed.c | 17 +++ lib/tevent/wscript | 6 +- 9 files changed, 370 insertions(+), 1 deletion(-) create mode 100644 lib/tevent/tests/test_tevent_tag.c (limited to 'lib/tevent') diff --git a/lib/tevent/ABI/tevent-0.10.2.sigs b/lib/tevent/ABI/tevent-0.10.2.sigs index f6227db5c93..238b69f0bd4 100644 --- a/lib/tevent/ABI/tevent-0.10.2.sigs +++ b/lib/tevent/ABI/tevent-0.10.2.sigs @@ -54,10 +54,14 @@ 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_immediate_get_tag: uint64_t (const struct tevent_immediate *) +tevent_immediate_set_tag: void (struct tevent_immediate *, 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) @@ -108,10 +112,14 @@ tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_deb 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_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) diff --git a/lib/tevent/tests/test_tevent_tag.c b/lib/tevent/tests/test_tevent_tag.c new file mode 100644 index 00000000000..ce64d3c396e --- /dev/null +++ b/lib/tevent/tests/test_tevent_tag.c @@ -0,0 +1,212 @@ +/* + * Unix SMB/CIFS implementation. + * + * testing of some tevent_req aspects + * + * Copyright (C) Pavel Březina 2021 + * + * ** NOTE! The following LGPL license applies to the tevent + * ** library. This does NOT imply that all of Samba is released + * ** under the LGPL + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +static void fd_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, + void *private_data) +{ + /* Dummy handler. Just return. */ + return; +} + +static void timer_handler(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval current_time, + void *private_data) +{ + /* Dummy handler. Just return. */ + return; +} + +static void signal_handler(struct tevent_context *ev, + struct tevent_signal *se, + int signum, + int count, + void *siginfo, + void *private_data) +{ + /* Dummy handler. Just return. */ + return; +} + +static void immediate_handler(struct tevent_context *ctx, + struct tevent_immediate *im, + void *private_data) +{ + /* Dummy handler. Just return. */ + return; +} + +static int test_setup(void **state) +{ + struct tevent_context *ev; + + ev = tevent_context_init(NULL); + assert_non_null(ev); + + *state = ev; + return 0; +} + +static int test_teardown(void **state) +{ + struct tevent_context *ev = (struct tevent_context *)(*state); + talloc_free(ev); + return 0; +} + +static void test_fd_tag(void **state) +{ + struct tevent_context *ev = (struct tevent_context *)(*state); + struct tevent_fd *fde; + uint64_t tag; + + fde = tevent_add_fd(ev, ev, 0, TEVENT_FD_READ, fd_handler, NULL); + assert_non_null(fde); + + tag = tevent_fd_get_tag(fde); + assert_int_equal(0, tag); + + tevent_fd_set_tag(fde, 1); + tag = tevent_fd_get_tag(fde); + assert_int_equal(1, tag); + + tevent_re_initialise(ev); + + tag = tevent_fd_get_tag(fde); + assert_int_equal(1, tag); + + TALLOC_FREE(fde); +} + +static void test_timer_tag(void **state) +{ + struct tevent_context *ev = (struct tevent_context *)(*state); + struct tevent_timer *te; + struct timeval next; + uint64_t tag; + + next = tevent_timeval_current(); + te = tevent_add_timer(ev, ev, next, timer_handler, NULL); + assert_non_null(te); + + tag = tevent_timer_get_tag(te); + assert_int_equal(0, tag); + + tevent_timer_set_tag(te, 1); + tag = tevent_timer_get_tag(te); + assert_int_equal(1, tag); + + next = tevent_timeval_current(); + tevent_update_timer(te, next); + + tag = tevent_timer_get_tag(te); + assert_int_equal(1, tag); + + tevent_re_initialise(ev); + + tag = tevent_timer_get_tag(te); + assert_int_equal(1, tag); + + TALLOC_FREE(te); +} + +static void test_signal_tag(void **state) +{ + struct tevent_context *ev = (struct tevent_context *)(*state); + struct tevent_signal *se; + uint64_t tag; + + se = tevent_add_signal(ev, ev, SIGUSR1, 0, signal_handler, NULL); + assert_non_null(se); + + tag = tevent_signal_get_tag(se); + assert_int_equal(0, tag); + + tevent_signal_set_tag(se, 1); + tag = tevent_signal_get_tag(se); + assert_int_equal(1, tag); + + tevent_re_initialise(ev); + + tag = tevent_signal_get_tag(se); + assert_int_equal(1, tag); + + TALLOC_FREE(se); +} + +static void test_immediate_tag(void **state) +{ + struct tevent_context *ev = (struct tevent_context *)(*state); + struct tevent_immediate *im; + uint64_t tag; + + im = tevent_create_immediate(ev); + assert_non_null(im); + + tag = tevent_immediate_get_tag(im); + assert_int_equal(0, tag); + + tevent_immediate_set_tag(im, 1); + tag = tevent_immediate_get_tag(im); + assert_int_equal(1, tag); + + tevent_schedule_immediate(im, ev, immediate_handler, NULL); + + tag = tevent_immediate_get_tag(im); + assert_int_equal(1, tag); + + tevent_re_initialise(ev); + + tag = tevent_immediate_get_tag(im); + assert_int_equal(1, tag); + + TALLOC_FREE(im); +} + +int main(int argc, char **argv) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test_setup_teardown(test_fd_tag, test_setup, test_teardown), + cmocka_unit_test_setup_teardown(test_timer_tag, test_setup, test_teardown), + cmocka_unit_test_setup_teardown(test_signal_tag, test_setup, test_teardown), + cmocka_unit_test_setup_teardown(test_immediate_tag, test_setup, test_teardown), + }; + + cmocka_set_message_output(CM_OUTPUT_SUBUNIT); + + return cmocka_run_group_tests(tests, NULL, NULL); +} diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h index b8e46feec46..5cfd1a1e9fa 100644 --- a/lib/tevent/tevent.h +++ b/lib/tevent/tevent.h @@ -210,6 +210,22 @@ struct tevent_fd *_tevent_add_fd(struct tevent_context *ev, #handler, __location__) #endif +/** + * @brief Associate a custom tag with the event. + * + * This tag can be then retrieved with tevent_fd_get_tag() + * + * @param[in] fde The file descriptor event. + * + * @param[in] tag Custom tag. + */ +void tevent_fd_set_tag(struct tevent_fd *fde, uint64_t tag); + +/** + * @brief Get custom event tag. + */ +uint64_t tevent_fd_get_tag(const struct tevent_fd *fde); + #ifdef DOXYGEN /** * @brief Add a timed event @@ -268,6 +284,22 @@ struct tevent_timer *_tevent_add_timer(struct tevent_context *ev, */ void tevent_update_timer(struct tevent_timer *te, struct timeval next_event); +/** + * @brief Associate a custom tag with the event. + * + * This tag can be then retrieved with tevent_timer_get_tag() + * + * @param[in] te The timer event. + * + * @param[in] tag Custom tag. + */ +void tevent_timer_set_tag(struct tevent_timer *te, uint64_t tag); + +/** + * @brief Get custom event tag. + */ +uint64_t tevent_timer_get_tag(const struct tevent_timer *te); + #ifdef DOXYGEN /** * Initialize an immediate event object @@ -318,6 +350,22 @@ void _tevent_schedule_immediate(struct tevent_immediate *im, #handler, __location__); #endif +/** + * @brief Associate a custom tag with the event. + * + * This tag can be then retrieved with tevent_immediate_get_tag() + * + * @param[in] im The immediate event. + * + * @param[in] tag Custom tag. + */ +void tevent_immediate_set_tag(struct tevent_immediate *im, uint64_t tag); + +/** + * @brief Get custom event tag. + */ +uint64_t tevent_immediate_get_tag(const struct tevent_immediate *fde); + #ifdef DOXYGEN /** * @brief Add a tevent signal handler @@ -365,6 +413,22 @@ struct tevent_signal *_tevent_add_signal(struct tevent_context *ev, #handler, __location__) #endif +/** + * @brief Associate a custom tag with the event. + * + * This tag can be then retrieved with tevent_signal_get_tag() + * + * @param[in] fde The signal event. + * + * @param[in] tag Custom tag. + */ +void tevent_signal_set_tag(struct tevent_signal *se, uint64_t tag); + +/** + * @brief Get custom event tag. + */ +uint64_t tevent_signal_get_tag(const struct tevent_signal *se); + /** * @brief the number of supported signals * diff --git a/lib/tevent/tevent_fd.c b/lib/tevent/tevent_fd.c index a0557fedbec..cd8b9741281 100644 --- a/lib/tevent/tevent_fd.c +++ b/lib/tevent/tevent_fd.c @@ -159,3 +159,21 @@ int tevent_common_invoke_fd_handler(struct tevent_fd *fde, uint16_t flags, return 0; } + +void tevent_fd_set_tag(struct tevent_fd *fde, uint64_t tag) +{ + if (fde == NULL) { + return; + } + + fde->tag = tag; +} + +uint64_t tevent_fd_get_tag(const struct tevent_fd *fde) +{ + if (fde == NULL) { + return 0; + } + + return fde->tag; +} diff --git a/lib/tevent/tevent_immediate.c b/lib/tevent/tevent_immediate.c index d7f8dccc3de..cff0104e42d 100644 --- a/lib/tevent/tevent_immediate.c +++ b/lib/tevent/tevent_immediate.c @@ -101,6 +101,7 @@ void tevent_common_schedule_immediate(struct tevent_immediate *im, { const char *create_location = im->create_location; bool busy = im->busy; + uint64_t tag = im->tag; struct tevent_wrapper_glue *glue = im->wrapper; tevent_common_immediate_cancel(im); @@ -118,6 +119,7 @@ void tevent_common_schedule_immediate(struct tevent_immediate *im, .create_location = create_location, .schedule_location = location, .busy = busy, + .tag = tag, }; DLIST_ADD_END(ev->immediate_events, im); @@ -208,3 +210,21 @@ bool tevent_common_loop_immediate(struct tevent_context *ev) return true; } + +void tevent_immediate_set_tag(struct tevent_immediate *im, uint64_t tag) +{ + if (im == NULL) { + return; + } + + im->tag = tag; +} + +uint64_t tevent_immediate_get_tag(const struct tevent_immediate *im) +{ + if (im == NULL) { + return 0; + } + + return im->tag; +} diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h index 5365fce3533..78e86c7fa77 100644 --- a/lib/tevent/tevent_internal.h +++ b/lib/tevent/tevent_internal.h @@ -204,6 +204,8 @@ struct tevent_fd { /* this is private for the events_ops implementation */ uint64_t additional_flags; void *additional_data; + /* custom tag that can be set by caller */ + uint64_t tag; }; struct tevent_timer { @@ -221,6 +223,8 @@ struct tevent_timer { const char *location; /* this is private for the events_ops implementation */ void *additional_data; + /* custom tag that can be set by caller */ + uint64_t tag; }; struct tevent_immediate { @@ -239,6 +243,8 @@ struct tevent_immediate { /* this is private for the events_ops implementation */ void (*cancel_fn)(struct tevent_immediate *im); void *additional_data; + /* custom tag that can be set by caller */ + uint64_t tag; }; struct tevent_signal { @@ -257,6 +263,8 @@ struct tevent_signal { const char *location; /* this is private for the events_ops implementation */ void *additional_data; + /* custom tag that can be set by caller */ + uint64_t tag; }; struct tevent_threaded_context { diff --git a/lib/tevent/tevent_signal.c b/lib/tevent/tevent_signal.c index 7ebb13d6a39..b55940c788e 100644 --- a/lib/tevent/tevent_signal.c +++ b/lib/tevent/tevent_signal.c @@ -516,3 +516,21 @@ void tevent_cleanup_pending_signal_handlers(struct tevent_signal *se) talloc_set_destructor(se, NULL); return; } + +void tevent_signal_set_tag(struct tevent_signal *se, uint64_t tag) +{ + if (se == NULL) { + return; + } + + se->tag = tag; +} + +uint64_t tevent_signal_get_tag(const struct tevent_signal *se) +{ + if (se == NULL) { + return 0; + } + + return se->tag; +} diff --git a/lib/tevent/tevent_timed.c b/lib/tevent/tevent_timed.c index a78d286a187..b0458aaceaf 100644 --- a/lib/tevent/tevent_timed.c +++ b/lib/tevent/tevent_timed.c @@ -447,3 +447,20 @@ struct timeval tevent_common_loop_timer_delay(struct tevent_context *ev) return tevent_timeval_zero(); } +void tevent_timer_set_tag(struct tevent_timer *te, uint64_t tag) +{ + if (te == NULL) { + return; + } + + te->tag = tag; +} + +uint64_t tevent_timer_get_tag(const struct tevent_timer *te) +{ + if (te == NULL) { + return 0; + } + + return te->tag; +} diff --git a/lib/tevent/wscript b/lib/tevent/wscript index bc28f7cbb46..5c318972124 100644 --- a/lib/tevent/wscript +++ b/lib/tevent/wscript @@ -135,6 +135,10 @@ def build(bld): pattern='tevent.py', installdir='python') + bld.SAMBA_BINARY('test_tevent_tag', + source='tests/test_tevent_tag.c', + deps='cmocka tevent', + install=False) def test(ctx): '''test tevent''' @@ -147,7 +151,7 @@ def test(ctx): unit_test_ret = 0 unit_tests = [ - + 'test_tevent_tag', ] for unit_test in unit_tests: -- cgit v1.2.1