mirror of
https://github.com/samba-team/samba.git
synced 2025-02-02 09:47:23 +03:00
tevent: add custom tag to events
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>
This commit is contained in:
parent
5203e70ada
commit
fc9dd8ce9f
@ -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)
|
||||
|
212
lib/tevent/tests/test_tevent_tag.c
Normal file
212
lib/tevent/tests/test_tevent_tag.c
Normal file
@ -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);
|
||||
}
|
@ -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
|
||||
*
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user