]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
tevent: add custom tag to events
authorPavel Březina <pbrezina@redhat.com>
Tue, 1 Jun 2021 11:57:45 +0000 (13:57 +0200)
committerAndreas Schneider <asn@cryptomilk.org>
Wed, 7 Jul 2021 05:07:30 +0000 (05:07 +0000)
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 <metze@samba.org>

Signed-off-by: Pavel Březina <pbrezina@redhat.com>
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
lib/tevent/ABI/tevent-0.10.2.sigs
lib/tevent/tests/test_tevent_tag.c [new file with mode: 0644]
lib/tevent/tevent.h
lib/tevent/tevent_fd.c
lib/tevent/tevent_immediate.c
lib/tevent/tevent_internal.h
lib/tevent/tevent_signal.c
lib/tevent/tevent_timed.c
lib/tevent/wscript

index f6227db5c938e41eaf2a3a80b29e2f5fa4fa3e01..238b69f0bd44ac4d588effa3c6504ce848d834d4 100644 (file)
@@ -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 (file)
index 0000000..ce64d3c
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * testing of some tevent_req aspects
+ *
+ * Copyright (C) Pavel Březina <pbrezina@redhat.com> 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <errno.h>
+#include <setjmp.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <signal.h>
+
+#include <talloc.h>
+#include <tevent.h>
+#include <cmocka.h>
+
+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);
+}
index b8e46feec466a9d2830193629c1377fd265fdbe6..5cfd1a1e9fa4a2e5933140948af0961e4871ecb6 100644 (file)
@@ -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
  *
index a0557fedbecd6f699330e201b6388190b3efa058..cd8b9741281d932639294cbf7a7563216b967185 100644 (file)
@@ -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;
+}
index d7f8dccc3de92b3eefdaf68e913a94b651d8e528..cff0104e42d5ae23a00c3aca5f05b95c02953f78 100644 (file)
@@ -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;
+}
index 5365fce35336ab51683056c4a084607375d9d3d1..78e86c7fa777d41fd55ad33f5d924d7bd361a411 100644 (file)
@@ -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 {
index 7ebb13d6a39c3f2cd4d6af535784db537fa34b31..b55940c788e4b1d7d39529d8c7490cf888f24614 100644 (file)
@@ -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;
+}
index a78d286a18714444f4327437d28c462441a2e392..b0458aaceafebe79f62d690e769bdd98a3b0bcde 100644 (file)
@@ -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;
+}
index bc28f7cbb46d1ef0a1756a7cde71171bb1feb149..5c3189721243ca12feb3e8195fce7259e4987b08 100644 (file)
@@ -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: