Hello community, here is the log from the commit of package tevent for openSUSE:Factory checked in at 2017-02-10 09:46:26 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/tevent (Old) and /work/SRC/openSUSE:Factory/.tevent.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "tevent" Changes: -------- --- /work/SRC/openSUSE:Factory/tevent/tevent-man.changes 2016-11-03 11:11:10.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.tevent.new/tevent-man.changes 2017-02-10 09:46:27.983570968 +0100 @@ -1,0 +2,15 @@ +Thu Feb 2 14:57:25 UTC 2017 - [email protected] + + - Use https urls. + +------------------------------------------------------------------- +Tue Jan 24 17:21:20 UTC 2017 - [email protected] + +- Update to version 0.9.31. + + Add tevent_req_reset_endtime + + Make talloc_free safe when threaded_contexts exist + + Add tevent_update_timer + + Factor out tevent_common_insert_timer + + Add threaded immediate activation + +------------------------------------------------------------------- --- /work/SRC/openSUSE:Factory/tevent/tevent.changes 2016-11-03 11:11:10.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.tevent.new/tevent.changes 2017-02-10 09:46:28.047561903 +0100 @@ -1,0 +2,21 @@ +Mon Feb 6 15:00:05 UTC 2017 - [email protected] + +- Drop redundant PreReq for ldconfig; this is autodetected. + Set RPM group right. + +------------------------------------------------------------------- +Thu Feb 2 14:57:25 UTC 2017 - [email protected] + + - Use https urls. + +------------------------------------------------------------------- +Tue Jan 24 17:21:20 UTC 2017 - [email protected] + +- Update to version 0.9.31. + + Add tevent_req_reset_endtime + + Make talloc_free safe when threaded_contexts exist + + Add tevent_update_timer + + Factor out tevent_common_insert_timer + + Add threaded immediate activation + +------------------------------------------------------------------- Old: ---- tevent-0.9.29.tar.asc tevent-0.9.29.tar.gz New: ---- tevent-0.9.31.tar.asc tevent-0.9.31.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ tevent-man.spec ++++++ --- /var/tmp/diff_new_pack.oksg9q/_old 2017-02-10 09:46:28.931436696 +0100 +++ /var/tmp/diff_new_pack.oksg9q/_new 2017-02-10 09:46:28.935436130 +0100 @@ -1,7 +1,7 @@ # # spec file for package tevent-man # -# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -50,13 +50,13 @@ %define build_make_smp_mflags %{?jobs:-j%jobs} %endif Url: http://tevent.samba.org/ -Version: 0.9.29 +Version: 0.9.31 Release: 0 Summary: An event system based on the talloc memory management library License: GPL-3.0+ -Group: System/Libraries -Source: http://download.samba.org/pub/tevent/tevent-%{version}.tar.gz -Source1: http://download.samba.org/pub/tevent/tevent-%{version}.tar.asc +Group: Development/Libraries/C and C++ +Source: https://download.samba.org/pub/tevent/tevent-%{version}.tar.gz +Source1: https://download.samba.org/pub/tevent/tevent-%{version}.tar.asc Source2: tevent.keyring Source4: baselibs.conf BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -79,7 +79,6 @@ %define libtevent_name libtevent %endif %package -n %{libtevent_name} -PreReq: /sbin/ldconfig Summary: Samba tevent Library Group: System/Libraries @@ -125,7 +124,6 @@ Summary: Python bindings for the Tevent library Group: Development/Libraries/Python Requires: %{libtevent_name} = %{version} -PreReq: /sbin/ldconfig %description -n python-tevent This package contains the python bindings for the Tevent library. @@ -136,7 +134,6 @@ Summary: Python3 bindings for the Tevent library Group: Development/Libraries/Python Requires: %{libtevent_name} = %{version} -PreReq: /sbin/ldconfig %description -n python3-tevent This package contains the python bindings for the Tevent library. ++++++ tevent.spec ++++++ --- /var/tmp/diff_new_pack.oksg9q/_old 2017-02-10 09:46:28.955433297 +0100 +++ /var/tmp/diff_new_pack.oksg9q/_new 2017-02-10 09:46:28.955433297 +0100 @@ -1,7 +1,7 @@ # # spec file for package tevent-man # -# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -49,14 +49,14 @@ %else %define build_make_smp_mflags %{?jobs:-j%jobs} %endif -Url: http://tevent.samba.org/ -Version: 0.9.29 +Url: https://tevent.samba.org/ +Version: 0.9.31 Release: 0 Summary: An event system based on the talloc memory management library License: GPL-3.0+ -Group: System/Libraries -Source: http://download.samba.org/pub/tevent/tevent-%{version}.tar.gz -Source1: http://download.samba.org/pub/tevent/tevent-%{version}.tar.asc +Group: Development/Libraries/C and C++ +Source: https://download.samba.org/pub/tevent/tevent-%{version}.tar.gz +Source1: https://download.samba.org/pub/tevent/tevent-%{version}.tar.asc Source2: tevent.keyring Source4: baselibs.conf BuildRoot: %{_tmppath}/%{name}-%{version}-build ++++++ tevent-0.9.29.tar.gz -> tevent-0.9.31.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tevent-0.9.29/ABI/tevent-0.9.30.sigs new/tevent-0.9.31/ABI/tevent-0.9.30.sigs --- old/tevent-0.9.29/ABI/tevent-0.9.30.sigs 1970-01-01 01:00:00.000000000 +0100 +++ new/tevent-0.9.31/ABI/tevent-0.9.30.sigs 2016-08-24 10:42:51.000000000 +0200 @@ -0,0 +1,96 @@ +_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_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_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_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_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_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_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (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_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +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_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_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +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_received: 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_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_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_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_point_callback: void (struct tevent_context *, enum tevent_trace_point) +tevent_wakeup_recv: bool (struct tevent_req *) +tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tevent-0.9.29/ABI/tevent-0.9.31.sigs new/tevent-0.9.31/ABI/tevent-0.9.31.sigs --- old/tevent-0.9.29/ABI/tevent-0.9.31.sigs 1970-01-01 01:00:00.000000000 +0100 +++ new/tevent-0.9.31/ABI/tevent-0.9.31.sigs 2016-10-07 06:45:35.000000000 +0200 @@ -0,0 +1,99 @@ +_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_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_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_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_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_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...) +tevent_fd_get_flags: uint16_t (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_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *) +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_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_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *) +tevent_req_is_in_progress: bool (struct tevent_req *) +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_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_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_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_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_point_callback: void (struct tevent_context *, enum tevent_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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tevent-0.9.29/buildtools/wafsamba/samba_autoconf.py new/tevent-0.9.31/buildtools/wafsamba/samba_autoconf.py --- old/tevent-0.9.29/buildtools/wafsamba/samba_autoconf.py 2016-07-28 09:17:50.000000000 +0200 +++ new/tevent-0.9.31/buildtools/wafsamba/samba_autoconf.py 2016-10-07 06:45:35.000000000 +0200 @@ -708,6 +708,7 @@ testflags=True) conf.ADD_CFLAGS('-Wformat=2 -Wno-format-y2k', testflags=True) + conf.ADD_CFLAGS('-Werror=format-security -Wformat-security', testflags=True) # This check is because for ldb_search(), a NULL format string # is not an error, but some compilers complain about that. if CHECK_CFLAGS(conf, ["-Werror=format", "-Wformat=2"], ''' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tevent-0.9.29/doc/tevent_context.dox new/tevent-0.9.31/doc/tevent_context.dox --- old/tevent-0.9.29/doc/tevent_context.dox 2014-09-16 20:04:31.000000000 +0200 +++ new/tevent-0.9.31/doc/tevent_context.dox 2016-10-07 06:45:35.000000000 +0200 @@ -67,7 +67,7 @@ <li>int tevent_loop_once()</li> </ul> -Both of functions accept just one parametr (tevent context) and the only +Both of functions accept just one parameter (tevent context) and the only difference lies in the fact that the first loop can theoretically last for ever but the second one will wait just for a single one event to catch and then the loop breaks and the program continue. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tevent-0.9.29/doc/tevent_queue.dox new/tevent-0.9.31/doc/tevent_queue.dox --- old/tevent-0.9.29/doc/tevent_queue.dox 2014-09-16 20:04:31.000000000 +0200 +++ new/tevent-0.9.31/doc/tevent_queue.dox 2016-10-07 06:45:35.000000000 +0200 @@ -11,7 +11,8 @@ similar, but the queue is not automatically set for any event. The queue has to be created on purpose, and events which should follow the order of the FIFO queue have to be explicitly pinpointed. Creating such a queue is crucial in -situations when sequential processing is absolutely essential for the succesful +situations when sequential processing is absolutely essential for the +successful completion of a task, e.g. for a large quantity of data that are about to be written from a buffer into a socket. The tevent library has its own queue structure that is ready to use after it has been initialized and started up @@ -20,7 +21,7 @@ @subsection cr_queue Creation of Queues The first and most important step is the creation of the tevent queue -(represented by struct tevent queue), which will then be in running mode. +(represented by struct tevent_queue), which will then be in running mode. @code struct tevent_queue* tevent_queue_create (TALLOC_CTX *mem_ctx, const char *name) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tevent-0.9.29/doc/tevent_thread.dox new/tevent-0.9.31/doc/tevent_thread.dox --- old/tevent-0.9.29/doc/tevent_thread.dox 2015-11-06 14:29:43.000000000 +0100 +++ new/tevent-0.9.31/doc/tevent_thread.dox 2016-10-07 06:45:35.000000000 +0200 @@ -1,7 +1,7 @@ /** -@page tevent_context Chapter 6: Tevent with threads +@page tevent_thread Chapter 6: Tevent with threads -@section context Tevent with threads +@section threads Tevent with threads In order to use tevent with threads, you must first understand how to use the talloc library in threaded programs. For more diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tevent-0.9.29/lib/replace/wscript new/tevent-0.9.31/lib/replace/wscript --- old/tevent-0.9.29/lib/replace/wscript 2016-07-28 09:17:50.000000000 +0200 +++ new/tevent-0.9.31/lib/replace/wscript 2016-08-24 10:42:51.000000000 +0200 @@ -483,6 +483,9 @@ if conf.CONFIG_SET('HAVE_PORT_CREATE') and conf.CONFIG_SET('HAVE_PORT_H'): conf.DEFINE('HAVE_SOLARIS_PORTS', 1) + if conf.CHECK_FUNCS('eventfd', headers='sys/eventfd.h'): + conf.DEFINE('HAVE_EVENTFD', 1) + conf.CHECK_HEADERS('poll.h') conf.CHECK_FUNCS('poll') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tevent-0.9.29/lib/talloc/talloc.c new/tevent-0.9.31/lib/talloc/talloc.c --- old/tevent-0.9.29/lib/talloc/talloc.c 2016-07-28 09:17:50.000000000 +0200 +++ new/tevent-0.9.31/lib/talloc/talloc.c 2016-08-30 08:06:06.000000000 +0200 @@ -2476,8 +2476,12 @@ #endif static struct talloc_chunk *_vasprintf_tc(const void *t, - const char *fmt, - va_list ap) + const char *fmt, + va_list ap) PRINTF_ATTRIBUTE(2,0); + +static struct talloc_chunk *_vasprintf_tc(const void *t, + const char *fmt, + va_list ap) { int len; char *ret; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tevent-0.9.29/testsuite.c new/tevent-0.9.31/testsuite.c --- old/tevent-0.9.29/testsuite.c 2016-07-28 09:17:50.000000000 +0200 +++ new/tevent-0.9.31/testsuite.c 2016-08-24 10:42:51.000000000 +0200 @@ -1148,6 +1148,101 @@ talloc_free(master_ev); return true; } + +struct threaded_test_2 { + struct tevent_threaded_context *tctx; + struct tevent_immediate *im; + pthread_t thread_id; +}; + +static void master_callback_2(struct tevent_context *ev, + struct tevent_immediate *im, + void *private_data); + +static void *thread_fn_2(void *private_data) +{ + struct threaded_test_2 *state = private_data; + + state->thread_id = pthread_self(); + + usleep(random() % 7000); + + tevent_threaded_schedule_immediate( + state->tctx, state->im, master_callback_2, state); + + return NULL; +} + +static void master_callback_2(struct tevent_context *ev, + struct tevent_immediate *im, + void *private_data) +{ + struct threaded_test_2 *state = private_data; + int i; + + for (i = 0; i < NUM_TEVENT_THREADS; i++) { + if (pthread_equal(state->thread_id, thread_map[i])) { + break; + } + } + torture_comment(thread_test_ctx, + "Callback_2 %u from thread %u\n", + thread_counter, + i); + thread_counter++; +} + +static bool test_multi_tevent_threaded_2(struct torture_context *test, + const void *test_data) +{ + unsigned i; + + struct tevent_context *ev; + struct tevent_threaded_context *tctx; + int ret; + + thread_test_ctx = test; + thread_counter = 0; + + ev = tevent_context_init(test); + torture_assert(test, ev != NULL, "tevent_context_init failed"); + + tctx = tevent_threaded_context_create(ev, ev); + torture_assert(test, tctx != NULL, + "tevent_threaded_context_create failed"); + + for (i=0; i<NUM_TEVENT_THREADS; i++) { + struct threaded_test_2 *state; + + state = talloc(ev, struct threaded_test_2); + torture_assert(test, state != NULL, "talloc failed"); + + state->tctx = tctx; + state->im = tevent_create_immediate(state); + torture_assert(test, state->im != NULL, + "tevent_create_immediate failed"); + + ret = pthread_create(&thread_map[i], NULL, thread_fn_2, state); + torture_assert(test, ret == 0, "pthread_create failed"); + } + + while (thread_counter < NUM_TEVENT_THREADS) { + ret = tevent_loop_once(ev); + torture_assert(test, ret == 0, "tevent_loop_once failed"); + } + + /* Wait for all the threads to finish - join 'em. */ + for (i = 0; i < NUM_TEVENT_THREADS; i++) { + void *retval; + ret = pthread_join(thread_map[i], &retval); + torture_assert(test, ret == 0, "pthread_join failed"); + /* Free the child thread event context. */ + } + + talloc_free(tctx); + talloc_free(ev); + return true; +} #endif struct torture_suite *torture_local_event(TALLOC_CTX *mem_ctx) @@ -1190,6 +1285,10 @@ test_multi_tevent_threaded_1, NULL); + torture_suite_add_simple_tcase_const(suite, "multi_tevent_threaded_2", + test_multi_tevent_threaded_2, + NULL); + #endif return suite; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tevent-0.9.29/tevent.c new/tevent-0.9.31/tevent.c --- old/tevent-0.9.29/tevent.c 2015-02-27 09:40:16.000000000 +0100 +++ new/tevent-0.9.31/tevent.c 2016-10-07 06:45:35.000000000 +0200 @@ -59,10 +59,18 @@ */ #include "replace.h" #include "system/filesys.h" +#ifdef HAVE_PTHREAD +#include "system/threads.h" +#endif #define TEVENT_DEPRECATED 1 #include "tevent.h" #include "tevent_internal.h" #include "tevent_util.h" +#ifdef HAVE_EVENTFD +#include <sys/eventfd.h> +#endif + +static void tevent_abort(struct tevent_context *ev, const char *reason); struct tevent_ops_list { struct tevent_ops_list *next, *prev; @@ -173,6 +181,120 @@ return list; } +static void tevent_common_wakeup_fini(struct tevent_context *ev); + +#ifdef HAVE_PTHREAD + +static pthread_mutex_t tevent_contexts_mutex = PTHREAD_MUTEX_INITIALIZER; +static struct tevent_context *tevent_contexts = NULL; +static pthread_once_t tevent_atfork_initialized = PTHREAD_ONCE_INIT; + +static void tevent_atfork_prepare(void) +{ + struct tevent_context *ev; + int ret; + + ret = pthread_mutex_lock(&tevent_contexts_mutex); + if (ret != 0) { + abort(); + } + + for (ev = tevent_contexts; ev != NULL; ev = ev->next) { + struct tevent_threaded_context *tctx; + + for (tctx = ev->threaded_contexts; tctx != NULL; + tctx = tctx->next) { + ret = pthread_mutex_lock(&tctx->event_ctx_mutex); + if (ret != 0) { + tevent_abort(ev, "pthread_mutex_lock failed"); + } + } + + ret = pthread_mutex_lock(&ev->scheduled_mutex); + if (ret != 0) { + tevent_abort(ev, "pthread_mutex_lock failed"); + } + } +} + +static void tevent_atfork_parent(void) +{ + struct tevent_context *ev; + int ret; + + for (ev = DLIST_TAIL(tevent_contexts); ev != NULL; + ev = DLIST_PREV(ev)) { + struct tevent_threaded_context *tctx; + + ret = pthread_mutex_unlock(&ev->scheduled_mutex); + if (ret != 0) { + tevent_abort(ev, "pthread_mutex_unlock failed"); + } + + for (tctx = DLIST_TAIL(ev->threaded_contexts); tctx != NULL; + tctx = DLIST_PREV(tctx)) { + ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); + if (ret != 0) { + tevent_abort( + ev, "pthread_mutex_unlock failed"); + } + } + } + + ret = pthread_mutex_unlock(&tevent_contexts_mutex); + if (ret != 0) { + abort(); + } +} + +static void tevent_atfork_child(void) +{ + struct tevent_context *ev; + int ret; + + for (ev = DLIST_TAIL(tevent_contexts); ev != NULL; + ev = DLIST_PREV(ev)) { + struct tevent_threaded_context *tctx; + + for (tctx = DLIST_TAIL(ev->threaded_contexts); tctx != NULL; + tctx = DLIST_PREV(tctx)) { + tctx->event_ctx = NULL; + + ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); + if (ret != 0) { + tevent_abort( + ev, "pthread_mutex_unlock failed"); + } + } + + ev->threaded_contexts = NULL; + + ret = pthread_mutex_unlock(&ev->scheduled_mutex); + if (ret != 0) { + tevent_abort(ev, "pthread_mutex_unlock failed"); + } + } + + ret = pthread_mutex_unlock(&tevent_contexts_mutex); + if (ret != 0) { + abort(); + } +} + +static void tevent_prep_atfork(void) +{ + int ret; + + ret = pthread_atfork(tevent_atfork_prepare, + tevent_atfork_parent, + tevent_atfork_child); + if (ret != 0) { + abort(); + } +} + +#endif + int tevent_common_context_destructor(struct tevent_context *ev) { struct tevent_fd *fd, *fn; @@ -180,13 +302,49 @@ struct tevent_immediate *ie, *in; struct tevent_signal *se, *sn; - if (ev->pipe_fde) { - talloc_free(ev->pipe_fde); - close(ev->pipe_fds[0]); - close(ev->pipe_fds[1]); - ev->pipe_fde = NULL; +#ifdef HAVE_PTHREAD + int ret; + + ret = pthread_mutex_lock(&tevent_contexts_mutex); + if (ret != 0) { + abort(); + } + + DLIST_REMOVE(tevent_contexts, ev); + + ret = pthread_mutex_unlock(&tevent_contexts_mutex); + if (ret != 0) { + abort(); } + while (ev->threaded_contexts != NULL) { + struct tevent_threaded_context *tctx = ev->threaded_contexts; + + ret = pthread_mutex_lock(&tctx->event_ctx_mutex); + if (ret != 0) { + abort(); + } + + /* + * Indicate to the thread that the tevent_context is + * gone. The counterpart of this is in + * _tevent_threaded_schedule_immediate, there we read + * this under the threaded_context's mutex. + */ + + tctx->event_ctx = NULL; + + ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); + if (ret != 0) { + abort(); + } + + DLIST_REMOVE(ev->threaded_contexts, tctx); + } +#endif + + tevent_common_wakeup_fini(ev); + for (fd = ev->fd_events; fd; fd = fn) { fn = fd->next; fd->event_ctx = NULL; @@ -255,6 +413,36 @@ ev = talloc_zero(mem_ctx, struct tevent_context); if (!ev) return NULL; +#ifdef HAVE_PTHREAD + + ret = pthread_once(&tevent_atfork_initialized, tevent_prep_atfork); + if (ret != 0) { + talloc_free(ev); + return NULL; + } + + ret = pthread_mutex_init(&ev->scheduled_mutex, NULL); + if (ret != 0) { + talloc_free(ev); + return NULL; + } + + ret = pthread_mutex_lock(&tevent_contexts_mutex); + if (ret != 0) { + pthread_mutex_destroy(&ev->scheduled_mutex); + talloc_free(ev); + return NULL; + } + + DLIST_ADD(tevent_contexts, ev); + + ret = pthread_mutex_unlock(&tevent_contexts_mutex); + if (ret != 0) { + abort(); + } + +#endif + talloc_set_destructor(ev, tevent_common_context_destructor); ev->ops = ops; @@ -620,6 +808,28 @@ return ret; } +bool tevent_common_have_events(struct tevent_context *ev) +{ + if (ev->fd_events != NULL) { + if (ev->fd_events != ev->wakeup_fde) { + return true; + } + if (ev->fd_events->next != NULL) { + return true; + } + + /* + * At this point we just have the wakeup pipe event as + * the only fd_event. That one does not count as a + * regular event, so look at the other event types. + */ + } + + return ((ev->timer_events != NULL) || + (ev->immediate_events != NULL) || + (ev->signal_events != NULL)); +} + /* return on failure or (with 0) if all fd events are removed */ @@ -629,10 +839,7 @@ /* * loop as long as we have events pending */ - while (ev->fd_events || - ev->timer_events || - ev->immediate_events || - ev->signal_events) { + while (tevent_common_have_events(ev)) { int ret; ret = _tevent_loop_once(ev, location); if (ret != 0) { @@ -670,3 +877,108 @@ return ev->ops->context_init(ev); } + +static void wakeup_pipe_handler(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, void *_private) +{ + ssize_t ret; + + do { + /* + * This is the boilerplate for eventfd, but it works + * for pipes too. And as we don't care about the data + * we read, we're fine. + */ + uint64_t val; + ret = read(fde->fd, &val, sizeof(val)); + } while (ret == -1 && errno == EINTR); +} + +/* + * Initialize the wakeup pipe and pipe fde + */ + +int tevent_common_wakeup_init(struct tevent_context *ev) +{ + int ret, read_fd; + + if (ev->wakeup_fde != NULL) { + return 0; + } + +#ifdef HAVE_EVENTFD + ret = eventfd(0, EFD_NONBLOCK); + if (ret == -1) { + return errno; + } + read_fd = ev->wakeup_fd = ret; +#else + { + int pipe_fds[2]; + ret = pipe(pipe_fds); + if (ret == -1) { + return errno; + } + ev->wakeup_fd = pipe_fds[1]; + ev->wakeup_read_fd = pipe_fds[0]; + + ev_set_blocking(ev->wakeup_fd, false); + ev_set_blocking(ev->wakeup_read_fd, false); + + read_fd = ev->wakeup_read_fd; + } +#endif + + ev->wakeup_fde = tevent_add_fd(ev, ev, read_fd, TEVENT_FD_READ, + wakeup_pipe_handler, NULL); + if (ev->wakeup_fde == NULL) { + close(ev->wakeup_fd); +#ifndef HAVE_EVENTFD + close(ev->wakeup_read_fd); +#endif + return ENOMEM; + } + + return 0; +} + +int tevent_common_wakeup_fd(int fd) +{ + ssize_t ret; + + do { +#ifdef HAVE_EVENTFD + uint64_t val = 1; + ret = write(fd, &val, sizeof(val)); +#else + char c = '\0'; + ret = write(fd, &c, 1); +#endif + } while ((ret == -1) && (errno == EINTR)); + + return 0; +} + +int tevent_common_wakeup(struct tevent_context *ev) +{ + if (ev->wakeup_fde == NULL) { + return ENOTCONN; + } + + return tevent_common_wakeup_fd(ev->wakeup_fd); +} + +static void tevent_common_wakeup_fini(struct tevent_context *ev) +{ + if (ev->wakeup_fde == NULL) { + return; + } + + TALLOC_FREE(ev->wakeup_fde); + + close(ev->wakeup_fd); +#ifndef HAVE_EVENTFD + close(ev->wakeup_read_fd); +#endif +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tevent-0.9.29/tevent.h new/tevent-0.9.31/tevent.h --- old/tevent-0.9.29/tevent.h 2016-07-28 09:17:50.000000000 +0200 +++ new/tevent-0.9.31/tevent.h 2016-10-07 06:45:35.000000000 +0200 @@ -40,6 +40,7 @@ struct tevent_immediate; struct tevent_signal; struct tevent_thread_proxy; +struct tevent_threaded_context; /** * @defgroup tevent The tevent API @@ -251,6 +252,16 @@ #handler, __location__) #endif +/** + * @brief Set the time a tevent_timer fires + * + * @param[in] te The timer event to reset + * + * @param[in] next_event Timeval specifying the absolute time to fire this + * event. This is not an offset. + */ +void tevent_update_timer(struct tevent_timer *te, struct timeval next_event); + #ifdef DOXYGEN /** * Initialize an immediate event object @@ -464,11 +475,11 @@ /* bits for file descriptor event flags */ /** - * Monitor a file descriptor for write availability + * Monitor a file descriptor for data to be read */ #define TEVENT_FD_READ 1 /** - * Monitor a file descriptor for data to be read + * Monitor a file descriptor for writeability */ #define TEVENT_FD_WRITE 2 @@ -1029,6 +1040,13 @@ struct tevent_context *ev, struct timeval endtime); +/** + * @brief Reset the timer set by tevent_req_set_endtime. + * + * @param[in] req The request to reset the timeout for + */ +void tevent_req_reset_endtime(struct tevent_req *req); + #ifdef DOXYGEN /** * @brief Call the notify callback of the given tevent request manually. @@ -1392,16 +1410,16 @@ const struct timeval *tv2); /** - * @brief Get a zero timval value. + * @brief Get a zero timeval value. * - * @return A zero timval value. + * @return A zero timeval value. */ struct timeval tevent_timeval_zero(void); /** * @brief Get a timeval value for the current time. * - * @return A timval value with the current time. + * @return A timeval value with the current time. */ struct timeval tevent_timeval_current(void); @@ -1750,6 +1768,79 @@ tevent_immediate_handler_t handler, void *pp_private_data); +/* + * @brief Create a context for threaded activation of immediates + * + * A tevent_treaded_context provides a link into an event + * context. Using tevent_threaded_schedule_immediate, it is possible + * to activate an immediate event from within a thread. + * + * It is the duty of the caller of tevent_threaded_context_create() to + * keep the event context around longer than any + * tevent_threaded_context. tevent will abort if ev is talllc_free'ed + * with an active tevent_threaded_context. + * + * If tevent is build without pthread support, this always returns + * NULL with errno=ENOSYS. + * + * @param[in] mem_ctx The talloc memory context to use. + * @param[in] ev The event context to link this to. + * @return The threaded context, or NULL with errno set. + * + * @see tevent_threaded_schedule_immediate() + * + * @note Available as of tevent 0.9.30 + */ +struct tevent_threaded_context *tevent_threaded_context_create( + TALLOC_CTX *mem_ctx, struct tevent_context *ev); + +#ifdef DOXYGEN +/* + * @brief Activate an immediate from a thread + * + * Activate an immediate from within a thread. + * + * This routine does not watch out for talloc hierarchies. This means + * that it is highly recommended to create the tevent_immediate in the + * thread owning tctx, allocate a threaded job description for the + * thread, hand over both pointers to a helper thread and not touch it + * in the main thread at all anymore. + * + * tevent_threaded_schedule_immediate is intended as a job completion + * indicator for simple threaded helpers. + * + * Please be aware that tevent_threaded_schedule_immediate is very + * picky about its arguments: An immediate may not already be + * activated and the handler must exist. With + * tevent_threaded_schedule_immediate memory ownership is transferred + * to the main thread holding the tevent context behind tctx, the + * helper thread can't access it anymore. + * + * @param[in] tctx The threaded context to go through + * @param[in] im The immediate event to activate + * @param[in] handler The immediate handler to call in the main thread + * @param[in] private_data Pointer for the immediate handler + * + * @see tevent_threaded_context_create() + * + * @note Available as of tevent 0.9.30 + */ +void tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx, + struct tevent_immediate *im, + tevent_immediate_handler_t handler, + void *private_data); +#else +void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx, + struct tevent_immediate *im, + tevent_immediate_handler_t handler, + void *private_data, + const char *handler_name, + const char *location); +#define tevent_threaded_schedule_immediate(tctx, im, handler, private_data) \ + _tevent_threaded_schedule_immediate(tctx, im, handler, private_data, \ + #handler, __location__); +#endif + #ifdef TEVENT_DEPRECATED #ifndef _DEPRECATED_ #ifdef HAVE___ATTRIBUTE__ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tevent-0.9.29/tevent_epoll.c new/tevent-0.9.31/tevent_epoll.c --- old/tevent-0.9.29/tevent_epoll.c 2015-12-10 12:01:40.000000000 +0100 +++ new/tevent-0.9.31/tevent_epoll.c 2016-08-24 10:42:51.000000000 +0200 @@ -903,6 +903,10 @@ return 0; } + if (ev->threaded_contexts != NULL) { + tevent_common_threaded_activate_immediate(ev); + } + if (ev->immediate_events && tevent_common_loop_immediate(ev)) { return 0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tevent-0.9.29/tevent_internal.h new/tevent-0.9.31/tevent_internal.h --- old/tevent-0.9.29/tevent_internal.h 2015-02-27 09:40:16.000000000 +0100 +++ new/tevent-0.9.31/tevent_internal.h 2016-10-07 06:45:35.000000000 +0200 @@ -228,6 +228,16 @@ void *additional_data; }; +struct tevent_threaded_context { + struct tevent_threaded_context *next, *prev; + +#ifdef HAVE_PTHREAD + pthread_mutex_t event_ctx_mutex; +#endif + struct tevent_context *event_ctx; + int wakeup_fd; +}; + struct tevent_debug_ops { void (*debug)(void *context, enum tevent_debug_level level, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); @@ -241,24 +251,41 @@ /* the specific events implementation */ const struct tevent_ops *ops; + /* + * The following three pointers are queried on every loop_once + * in the order in which they appear here. Not measured, but + * hopefully putting them at the top together with "ops" + * should make tevent a *bit* more cache-friendly than before. + */ + + /* list of signal events - used by common code */ + struct tevent_signal *signal_events; + + /* List of threaded job indicators */ + struct tevent_threaded_context *threaded_contexts; + + /* list of immediate events - used by common code */ + struct tevent_immediate *immediate_events; + /* list of fd events - used by common code */ struct tevent_fd *fd_events; /* list of timed events - used by common code */ struct tevent_timer *timer_events; - /* list of immediate events - used by common code */ - struct tevent_immediate *immediate_events; - - /* list of signal events - used by common code */ - struct tevent_signal *signal_events; + /* List of scheduled immediates */ + pthread_mutex_t scheduled_mutex; + struct tevent_immediate *scheduled_immediates; /* this is private for the events_ops implementation */ void *additional_data; /* pipe hack used with signal handlers */ - struct tevent_fd *pipe_fde; - int pipe_fds[2]; + struct tevent_fd *wakeup_fde; + int wakeup_fd; /* fd to write into */ +#ifndef HAVE_EVENT_FD + int wakeup_read_fd; +#endif /* debugging operations */ struct tevent_debug_ops debug_ops; @@ -282,6 +309,10 @@ * tevent_common_add_timer_v2() */ struct tevent_timer *last_zero_timer; + +#ifdef HAVE_PTHREAD + struct tevent_context *prev, *next; +#endif }; const struct tevent_ops *tevent_find_ops_byname(const char *name); @@ -327,6 +358,12 @@ const char *handler_name, const char *location); bool tevent_common_loop_immediate(struct tevent_context *ev); +void tevent_common_threaded_activate_immediate(struct tevent_context *ev); + +bool tevent_common_have_events(struct tevent_context *ev); +int tevent_common_wakeup_init(struct tevent_context *ev); +int tevent_common_wakeup_fd(int fd); +int tevent_common_wakeup(struct tevent_context *ev); struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev, TALLOC_CTX *mem_ctx, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tevent-0.9.29/tevent_poll.c new/tevent-0.9.31/tevent_poll.c --- old/tevent-0.9.29/tevent_poll.c 2016-02-19 22:02:02.000000000 +0100 +++ new/tevent-0.9.31/tevent_poll.c 2016-08-24 10:42:51.000000000 +0200 @@ -645,6 +645,10 @@ return 0; } + if (ev->threaded_contexts != NULL) { + tevent_common_threaded_activate_immediate(ev); + } + if (ev->immediate_events && tevent_common_loop_immediate(ev)) { return 0; @@ -667,10 +671,7 @@ /* * loop as long as we have events pending */ - while (ev->fd_events || - ev->timer_events || - ev->immediate_events || - ev->signal_events || + while (tevent_common_have_events(ev) || poll_ev->fresh || poll_ev->disabled) { int ret; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tevent-0.9.29/tevent_port.c new/tevent-0.9.31/tevent_port.c --- old/tevent-0.9.29/tevent_port.c 2016-02-19 22:02:02.000000000 +0100 +++ new/tevent-0.9.31/tevent_port.c 2016-08-24 10:42:51.000000000 +0200 @@ -760,6 +760,10 @@ return 0; } + if (ev->threaded_contexts != NULL) { + tevent_common_threaded_activate_immediate(ev); + } + if (ev->immediate_events && tevent_common_loop_immediate(ev)) { return 0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tevent-0.9.29/tevent_queue.c new/tevent-0.9.31/tevent_queue.c --- old/tevent-0.9.29/tevent_queue.c 2016-02-19 22:02:02.000000000 +0100 +++ new/tevent-0.9.31/tevent_queue.c 2016-08-24 10:42:51.000000000 +0200 @@ -187,7 +187,7 @@ if (req->async.fn != NULL) { /* - * If the callers wants to optimize for the + * If the caller wants to optimize for the * empty queue case, call the trigger only * if there is no callback defined for the * request yet. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tevent-0.9.29/tevent_req.c new/tevent-0.9.31/tevent_req.c --- old/tevent-0.9.29/tevent_req.c 2016-07-28 09:17:50.000000000 +0200 +++ new/tevent-0.9.31/tevent_req.c 2016-10-07 06:45:35.000000000 +0200 @@ -313,6 +313,11 @@ return true; } +void tevent_req_reset_endtime(struct tevent_req *req) +{ + TALLOC_FREE(req->internal.timer); +} + void tevent_req_set_callback(struct tevent_req *req, tevent_req_fn fn, void *pvt) { req->async.fn = fn; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tevent-0.9.29/tevent_select.c new/tevent-0.9.31/tevent_select.c --- old/tevent-0.9.29/tevent_select.c 2016-02-19 22:02:02.000000000 +0100 +++ new/tevent-0.9.31/tevent_select.c 2016-08-24 10:42:51.000000000 +0200 @@ -244,6 +244,10 @@ return 0; } + if (ev->threaded_contexts != NULL) { + tevent_common_threaded_activate_immediate(ev); + } + if (ev->immediate_events && tevent_common_loop_immediate(ev)) { return 0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tevent-0.9.29/tevent_signal.c new/tevent-0.9.31/tevent_signal.c --- old/tevent-0.9.29/tevent_signal.c 2016-07-28 09:17:50.000000000 +0200 +++ new/tevent-0.9.31/tevent_signal.c 2016-08-24 10:42:51.000000000 +0200 @@ -95,7 +95,6 @@ */ static void tevent_common_signal_handler(int signum) { - char c = 0; struct tevent_common_signal_list *sl; struct tevent_context *ev = NULL; int saved_errno = errno; @@ -106,13 +105,8 @@ /* Write to each unique event context. */ for (sl = sig_state->sig_handlers[signum]; sl; sl = sl->next) { if (sl->se->event_ctx && sl->se->event_ctx != ev) { - ssize_t ret; - ev = sl->se->event_ctx; - /* doesn't matter if this pipe overflows */ - do { - ret = write(ev->pipe_fds[1], &c, 1); - } while (ret == -1 && errno == EINTR); + tevent_common_wakeup(ev); } } @@ -198,16 +192,6 @@ struct tevent_context *ev = se->event_ctx; DLIST_REMOVE(ev->signal_events, se); - - if (ev->signal_events == NULL && ev->pipe_fde != NULL) { - /* - * This was the last signal. Destroy the pipe. - */ - TALLOC_FREE(ev->pipe_fde); - - close(ev->pipe_fds[0]); - close(ev->pipe_fds[1]); - } } talloc_free(sl); @@ -233,21 +217,6 @@ } /* - this is part of the pipe hack needed to avoid the signal race condition -*/ -static void signal_pipe_handler(struct tevent_context *ev, struct tevent_fd *fde, - uint16_t flags, void *_private) -{ - ssize_t ret; - - char c[16]; - /* its non-blocking, doesn't matter if we read too much */ - do { - ret = read(fde->fd, c, sizeof(c)); - } while (ret == -1 && errno == EINTR); -} - -/* add a signal event return NULL on failure (memory allocation error) */ @@ -263,6 +232,13 @@ struct tevent_signal *se; struct tevent_common_signal_list *sl; sigset_t set, oldset; + int ret; + + ret = tevent_common_wakeup_init(ev); + if (ret != 0) { + errno = ret; + return NULL; + } if (signum >= TEVENT_NUM_SIGNALS) { errno = EINVAL; @@ -304,26 +280,6 @@ return NULL; } - /* we need to setup the pipe hack handler if not already - setup */ - if (ev->pipe_fde == NULL) { - if (pipe(ev->pipe_fds) == -1) { - talloc_free(se); - return NULL; - } - ev_set_blocking(ev->pipe_fds[0], false); - ev_set_blocking(ev->pipe_fds[1], false); - ev->pipe_fde = tevent_add_fd(ev, ev, ev->pipe_fds[0], - TEVENT_FD_READ, - signal_pipe_handler, NULL); - if (!ev->pipe_fde) { - close(ev->pipe_fds[0]); - close(ev->pipe_fds[1]); - talloc_free(se); - return NULL; - } - } - /* only install a signal handler if not already installed */ if (sig_state->sig_handlers[signum] == NULL) { struct sigaction act; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tevent-0.9.29/tevent_threads.c new/tevent-0.9.31/tevent_threads.c --- old/tevent-0.9.29/tevent_threads.c 2016-07-28 09:17:50.000000000 +0200 +++ new/tevent-0.9.31/tevent_threads.c 2016-10-07 06:45:35.000000000 +0200 @@ -108,7 +108,7 @@ if (tp->tofree_im_list != NULL) { /* * Once the current immediate events - * are processed, we need to reshedule + * are processed, we need to reschedule * ourselves to free them. This works * as tevent_schedule_immediate() * always adds events to the *END* of @@ -371,3 +371,156 @@ ; } #endif + +static int tevent_threaded_context_destructor( + struct tevent_threaded_context *tctx) +{ + int ret; + + if (tctx->event_ctx != NULL) { + DLIST_REMOVE(tctx->event_ctx->threaded_contexts, tctx); + } + + ret = pthread_mutex_destroy(&tctx->event_ctx_mutex); + if (ret != 0) { + abort(); + } + + return 0; +} + +struct tevent_threaded_context *tevent_threaded_context_create( + TALLOC_CTX *mem_ctx, struct tevent_context *ev) +{ +#ifdef HAVE_PTHREAD + struct tevent_threaded_context *tctx; + int ret; + + ret = tevent_common_wakeup_init(ev); + if (ret != 0) { + errno = ret; + return NULL; + } + + tctx = talloc(mem_ctx, struct tevent_threaded_context); + if (tctx == NULL) { + return NULL; + } + tctx->event_ctx = ev; + tctx->wakeup_fd = ev->wakeup_fd; + + ret = pthread_mutex_init(&tctx->event_ctx_mutex, NULL); + if (ret != 0) { + TALLOC_FREE(tctx); + return NULL; + } + + DLIST_ADD(ev->threaded_contexts, tctx); + talloc_set_destructor(tctx, tevent_threaded_context_destructor); + + return tctx; +#else + errno = ENOSYS; + return NULL; +#endif +} + +void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx, + struct tevent_immediate *im, + tevent_immediate_handler_t handler, + void *private_data, + const char *handler_name, + const char *location) +{ +#ifdef HAVE_PTHREAD + struct tevent_context *ev; + int ret; + + ret = pthread_mutex_lock(&tctx->event_ctx_mutex); + if (ret != 0) { + abort(); + } + + ev = tctx->event_ctx; + + ret = pthread_mutex_unlock(&tctx->event_ctx_mutex); + if (ret != 0) { + abort(); + } + + if (ev == NULL) { + /* + * Our event context is already gone. + */ + return; + } + + if ((im->event_ctx != NULL) || (handler == NULL)) { + abort(); + } + + im->event_ctx = ev; + im->handler = handler; + im->private_data = private_data; + im->handler_name = handler_name; + im->schedule_location = location; + im->cancel_fn = NULL; + im->additional_data = NULL; + + ret = pthread_mutex_lock(&ev->scheduled_mutex); + if (ret != 0) { + abort(); + } + + DLIST_ADD_END(ev->scheduled_immediates, im); + + ret = pthread_mutex_unlock(&ev->scheduled_mutex); + if (ret != 0) { + abort(); + } + + /* + * We might want to wake up the main thread under the lock. We + * had a slightly similar situation in pthreadpool, changed + * with 1c4284c7395f23. This is not exactly the same, as the + * wakeup is only a last-resort thing in case the main thread + * is sleeping. Doing the wakeup under the lock can easily + * lead to a contended mutex, which is much more expensive + * than a noncontended one. So I'd opt for the lower footprint + * initially. Maybe we have to change that later. + */ + tevent_common_wakeup_fd(tctx->wakeup_fd); +#else + /* + * tevent_threaded_context_create() returned NULL with ENOSYS... + */ + abort(); +#endif +} + +void tevent_common_threaded_activate_immediate(struct tevent_context *ev) +{ +#ifdef HAVE_PTHREAD + int ret; + ret = pthread_mutex_lock(&ev->scheduled_mutex); + if (ret != 0) { + abort(); + } + + while (ev->scheduled_immediates != NULL) { + struct tevent_immediate *im = ev->scheduled_immediates; + DLIST_REMOVE(ev->scheduled_immediates, im); + DLIST_ADD_END(ev->immediate_events, im); + } + + ret = pthread_mutex_unlock(&ev->scheduled_mutex); + if (ret != 0) { + abort(); + } +#else + /* + * tevent_threaded_context_create() returned NULL with ENOSYS... + */ + abort(); +#endif +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tevent-0.9.29/tevent_timed.c new/tevent-0.9.31/tevent_timed.c --- old/tevent-0.9.29/tevent_timed.c 2014-09-16 20:04:31.000000000 +0200 +++ new/tevent-0.9.31/tevent_timed.c 2016-10-07 06:45:35.000000000 +0200 @@ -154,39 +154,13 @@ return -1; } -/* - add a timed event - return NULL on failure (memory allocation error) -*/ -static struct tevent_timer *tevent_common_add_timer_internal( - struct tevent_context *ev, - TALLOC_CTX *mem_ctx, - struct timeval next_event, - tevent_timer_handler_t handler, - void *private_data, - const char *handler_name, - const char *location, - bool optimize_zero) +static void tevent_common_insert_timer(struct tevent_context *ev, + struct tevent_timer *te, + bool optimize_zero) { - struct tevent_timer *te, *prev_te, *cur_te; - - te = talloc(mem_ctx?mem_ctx:ev, struct tevent_timer); - if (te == NULL) return NULL; - - te->event_ctx = ev; - te->next_event = next_event; - te->handler = handler; - te->private_data = private_data; - te->handler_name = handler_name; - te->location = location; - te->additional_data = NULL; - - if (ev->timer_events == NULL) { - ev->last_zero_timer = NULL; - } + struct tevent_timer *prev_te = NULL; /* keep the list ordered */ - prev_te = NULL; if (optimize_zero && tevent_timeval_is_zero(&te->next_event)) { /* * Some callers use zero tevent_timer @@ -199,6 +173,8 @@ prev_te = ev->last_zero_timer; ev->last_zero_timer = te; } else { + struct tevent_timer *cur_te; + /* * we traverse the list from the tail * because it's much more likely that @@ -227,6 +203,40 @@ } DLIST_ADD_AFTER(ev->timer_events, te, prev_te); +} + +/* + add a timed event + return NULL on failure (memory allocation error) +*/ +static struct tevent_timer *tevent_common_add_timer_internal( + struct tevent_context *ev, + TALLOC_CTX *mem_ctx, + struct timeval next_event, + tevent_timer_handler_t handler, + void *private_data, + const char *handler_name, + const char *location, + bool optimize_zero) +{ + struct tevent_timer *te; + + te = talloc(mem_ctx?mem_ctx:ev, struct tevent_timer); + if (te == NULL) return NULL; + + te->event_ctx = ev; + te->next_event = next_event; + te->handler = handler; + te->private_data = private_data; + te->handler_name = handler_name; + te->location = location; + te->additional_data = NULL; + + if (ev->timer_events == NULL) { + ev->last_zero_timer = NULL; + } + + tevent_common_insert_timer(ev, te, optimize_zero); talloc_set_destructor(te, tevent_common_timed_destructor); @@ -274,6 +284,24 @@ true); } +void tevent_update_timer(struct tevent_timer *te, struct timeval next_event) +{ + struct tevent_context *ev = te->event_ctx; + + if (ev->last_zero_timer == te) { + te->event_ctx->last_zero_timer = DLIST_PREV(te); + } + DLIST_REMOVE(ev->timer_events, te); + + te->next_event = next_event; + + /* + * Not doing the zero_timer optimization. This is for new code + * that should know about immediates. + */ + tevent_common_insert_timer(ev, te, false); +} + /* do a single event loop using the events defined in ev diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tevent-0.9.29/wscript new/tevent-0.9.31/wscript --- old/tevent-0.9.29/wscript 2016-07-28 09:19:54.000000000 +0200 +++ new/tevent-0.9.31/wscript 2016-10-07 06:45:35.000000000 +0200 @@ -1,7 +1,7 @@ #!/usr/bin/env python APPNAME = 'tevent' -VERSION = '0.9.29' +VERSION = '0.9.31' blddir = 'bin' @@ -99,9 +99,13 @@ private_library = True if not bld.CONFIG_SET('USING_SYSTEM_TEVENT'): + tevent_deps = 'replace talloc' + if bld.CONFIG_SET('HAVE_PTHREAD'): + tevent_deps += ' pthread' + bld.SAMBA_LIBRARY('tevent', SRC, - deps='replace talloc', + deps=tevent_deps, enabled= not bld.CONFIG_SET('USING_SYSTEM_TEVENT'), includes='.', abi_directory='ABI',
