2022-03-14 13:16:58 +03:00
/*
2005-02-15 13:36:59 +03:00
Unix SMB / CIFS implementation .
generalised event loop handling
2009-05-16 06:14:21 +04:00
INTERNAL STRUCTS . THERE ARE NO API GUARANTEES .
2022-03-14 13:16:58 +03:00
External users should only ever have to include this header when
2009-05-16 06:14:21 +04:00
implementing new tevent backends .
2005-02-15 13:36:59 +03:00
2009-02-16 10:52:06 +03:00
Copyright ( C ) Stefan Metzmacher 2005 - 2009
* * 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 ,
2005-02-15 13:36:59 +03:00
but WITHOUT ANY WARRANTY ; without even the implied warranty of
2009-02-16 10:52:06 +03:00
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/>.
2005-02-15 13:36:59 +03:00
*/
2009-02-28 23:44:30 +03:00
struct tevent_req {
/**
* @ brief What to do on completion
*
* This is used for the user of an async request , fn is called when
* the request completes , either successfully or with an error .
*/
struct {
/**
* @ brief Completion function
* Completion function , to be filled by the API user
*/
tevent_req_fn fn ;
/**
* @ brief Private data for the completion function
*/
void * private_data ;
2023-04-24 16:04:06 +03:00
/**
* @ brief The completion function name , for flow tracing .
*/
const char * fn_name ;
2009-02-28 23:44:30 +03:00
} async ;
/**
* @ brief Private state pointer for the actual implementation
*
* The implementation doing the work for the async request needs to
* keep around current data like for example a fd event . The user of
* an async request should not touch this .
*/
void * data ;
/**
* @ brief A function to overwrite the default print function
*
2009-03-10 15:54:57 +03:00
* The implementation doing the work may want to implement a
2009-02-28 23:44:30 +03:00
* custom function to print the text representation of the async
* request .
*/
tevent_req_print_fn private_print ;
2009-08-15 11:46:23 +04:00
/**
* @ brief A function to cancel the request
*
* The implementation might want to set a function
* that is called when the tevent_req_cancel ( ) function
* was called .
*/
tevent_req_cancel_fn private_cancel ;
2013-09-27 04:29:57 +04:00
/**
* @ brief A function to cleanup the request
*
* The implementation might want to set a function
* that is called before the tevent_req_done ( ) and tevent_req_error ( )
* trigger the callers callback function .
*/
struct {
tevent_req_cleanup_fn fn ;
enum tevent_req_state state ;
} private_cleanup ;
2009-02-28 23:44:30 +03:00
/**
* @ brief Internal state of the request
*
* Callers should only access this via functions and never directly .
*/
struct {
/**
* @ brief The talloc type of the data pointer
*
* This is filled by the tevent_req_create ( ) macro .
*
* This for debugging only .
*/
const char * private_type ;
/**
* @ brief The location where the request was created
*
* This uses the __location__ macro via the tevent_req_create ( )
* macro .
*
* This for debugging only .
*/
2009-03-17 22:13:34 +03:00
const char * create_location ;
/**
* @ brief The location where the request was finished
*
* This uses the __location__ macro via the tevent_req_done ( ) ,
* tevent_req_error ( ) or tevent_req_nomem ( ) macro .
*
* This for debugging only .
*/
const char * finish_location ;
2009-02-28 23:44:30 +03:00
2009-08-15 11:46:23 +04:00
/**
* @ brief The location where the request was canceled
*
* This uses the __location__ macro via the
* tevent_req_cancel ( ) macro .
*
* This for debugging only .
*/
const char * cancel_location ;
2009-02-28 23:44:30 +03:00
/**
* @ brief The external state - will be queried by the caller
*
* While the async request is being processed , state will remain in
* TEVENT_REQ_IN_PROGRESS . A request is finished if
* req - > state > = TEVENT_REQ_DONE .
*/
enum tevent_req_state state ;
/**
* @ brief status code when finished
*
* This status can be queried in the async completion function . It
* will be set to 0 when everything went fine .
*/
uint64_t error ;
/**
2009-03-17 12:18:34 +03:00
* @ brief the immediate event used by tevent_req_post
2009-02-28 23:44:30 +03:00
*
*/
2009-03-17 12:18:34 +03:00
struct tevent_immediate * trigger ;
2009-02-28 23:44:30 +03:00
2011-07-08 17:54:51 +04:00
/**
* @ brief An event context which will be used to
* defer the _tevent_req_notify_callback ( ) .
*/
struct tevent_context * defer_callback_ev ;
2009-02-28 23:44:30 +03:00
/**
2009-11-26 19:18:00 +03:00
* @ brief the timer event if tevent_req_set_endtime was used
2009-02-28 23:44:30 +03:00
*
*/
struct tevent_timer * timer ;
2018-05-02 15:01:56 +03:00
/**
* @ brief The place where profiling data is kept
*/
struct tevent_req_profile * profile ;
2022-06-16 17:23:22 +03:00
size_t call_depth ;
2009-02-28 23:44:30 +03:00
} internal ;
} ;
2018-05-02 15:01:56 +03:00
struct tevent_req_profile {
struct tevent_req_profile * prev , * next ;
struct tevent_req_profile * parent ;
const char * req_name ;
pid_t pid ;
const char * start_location ;
struct timeval start_time ;
const char * stop_location ;
struct timeval stop_time ;
enum tevent_req_state state ;
uint64_t user_error ;
struct tevent_req_profile * subprofiles ;
} ;
2008-12-24 15:52:57 +03:00
struct tevent_fd {
struct tevent_fd * prev , * next ;
struct tevent_context * event_ctx ;
2014-07-22 18:51:38 +04:00
struct tevent_wrapper_glue * wrapper ;
2014-07-22 16:45:33 +04:00
bool busy ;
bool destroyed ;
2005-02-15 13:36:59 +03:00
int fd ;
2009-01-03 13:27:00 +03:00
uint16_t flags ; /* see TEVENT_FD_* flags */
2008-12-24 15:52:57 +03:00
tevent_fd_handler_t handler ;
2009-01-03 13:27:00 +03:00
tevent_fd_close_fn_t close_fn ;
2005-02-15 13:36:59 +03:00
/* this is private for the specific handler */
void * private_data ;
2009-01-02 15:26:32 +03:00
/* this is for debugging only! */
const char * handler_name ;
const char * location ;
2005-02-15 13:36:59 +03:00
/* this is private for the events_ops implementation */
2011-03-02 17:20:46 +03:00
uint64_t additional_flags ;
2005-02-15 13:36:59 +03:00
void * additional_data ;
2021-06-01 14:57:45 +03:00
/* custom tag that can be set by caller */
uint64_t tag ;
2005-02-15 13:36:59 +03:00
} ;
2008-12-24 15:52:57 +03:00
struct tevent_timer {
struct tevent_timer * prev , * next ;
struct tevent_context * event_ctx ;
2014-07-22 18:51:38 +04:00
struct tevent_wrapper_glue * wrapper ;
2014-07-22 15:08:42 +04:00
bool busy ;
bool destroyed ;
2005-02-15 13:36:59 +03:00
struct timeval next_event ;
2008-12-24 15:52:57 +03:00
tevent_timer_handler_t handler ;
2005-02-15 13:36:59 +03:00
/* this is private for the specific handler */
void * private_data ;
2009-01-02 15:26:32 +03:00
/* this is for debugging only! */
const char * handler_name ;
const char * location ;
2005-02-15 13:36:59 +03:00
/* this is private for the events_ops implementation */
void * additional_data ;
2021-06-01 14:57:45 +03:00
/* custom tag that can be set by caller */
uint64_t tag ;
2005-02-15 13:36:59 +03:00
} ;
2009-03-13 17:47:33 +03:00
struct tevent_immediate {
struct tevent_immediate * prev , * next ;
struct tevent_context * event_ctx ;
2014-07-22 18:51:38 +04:00
struct tevent_wrapper_glue * wrapper ;
2014-07-22 15:08:42 +04:00
bool busy ;
bool destroyed ;
2021-06-01 15:10:05 +03:00
struct tevent_context * detach_ev_ctx ;
2009-03-13 17:47:33 +03:00
tevent_immediate_handler_t handler ;
/* this is private for the specific handler */
void * private_data ;
/* this is for debugging only! */
const char * handler_name ;
const char * create_location ;
const char * schedule_location ;
/* this is private for the events_ops implementation */
void ( * cancel_fn ) ( struct tevent_immediate * im ) ;
void * additional_data ;
2021-06-01 14:57:45 +03:00
/* custom tag that can be set by caller */
uint64_t tag ;
2009-03-13 17:47:33 +03:00
} ;
2008-12-24 15:52:57 +03:00
struct tevent_signal {
struct tevent_signal * prev , * next ;
struct tevent_context * event_ctx ;
2014-07-22 18:51:38 +04:00
struct tevent_wrapper_glue * wrapper ;
2014-07-22 15:01:01 +04:00
bool busy ;
bool destroyed ;
2007-01-21 11:23:14 +03:00
int signum ;
2007-01-21 13:32:39 +03:00
int sa_flags ;
2009-01-02 15:26:32 +03:00
tevent_signal_handler_t handler ;
/* this is private for the specific handler */
void * private_data ;
/* this is for debugging only! */
const char * handler_name ;
const char * location ;
/* this is private for the events_ops implementation */
void * additional_data ;
2021-06-01 14:57:45 +03:00
/* custom tag that can be set by caller */
uint64_t tag ;
2007-01-21 11:23:14 +03:00
} ;
2016-08-08 12:26:37 +03:00
struct tevent_threaded_context {
struct tevent_threaded_context * next , * prev ;
2016-09-07 21:25:36 +03:00
# ifdef HAVE_PTHREAD
pthread_mutex_t event_ctx_mutex ;
# endif
2016-08-08 12:26:37 +03:00
struct tevent_context * event_ctx ;
} ;
2009-01-02 15:39:56 +03:00
struct tevent_debug_ops {
void ( * debug ) ( void * context , enum tevent_debug_level level ,
2008-06-14 19:23:31 +04:00
const char * fmt , va_list ap ) PRINTF_ATTRIBUTE ( 3 , 0 ) ;
void * context ;
} ;
2009-01-02 15:39:56 +03:00
void tevent_debug ( struct tevent_context * ev , enum tevent_debug_level level ,
const char * fmt , . . . ) PRINTF_ATTRIBUTE ( 3 , 4 ) ;
2008-06-14 19:23:31 +04:00
2014-07-22 17:10:00 +04:00
void tevent_abort ( struct tevent_context * ev , const char * reason ) ;
2018-04-17 17:33:47 +03:00
void tevent_common_check_double_free ( TALLOC_CTX * ptr , const char * reason ) ;
2008-12-24 15:52:57 +03:00
struct tevent_context {
2005-02-15 13:36:59 +03:00
/* the specific events implementation */
2008-12-24 15:52:57 +03:00
const struct tevent_ops * ops ;
2007-01-05 12:35:49 +03:00
2016-08-08 09:56:23 +03:00
/*
* 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 ;
2009-01-05 19:36:50 +03:00
/* list of fd events - used by common code */
struct tevent_fd * fd_events ;
2007-01-05 12:35:49 +03:00
/* list of timed events - used by common code */
2008-12-24 15:52:57 +03:00
struct tevent_timer * timer_events ;
2007-01-05 12:35:49 +03:00
2016-08-08 12:26:37 +03:00
/* List of scheduled immediates */
pthread_mutex_t scheduled_mutex ;
struct tevent_immediate * scheduled_immediates ;
2005-02-15 13:36:59 +03:00
/* this is private for the events_ops implementation */
void * additional_data ;
2007-01-21 11:23:14 +03:00
/* pipe hack used with signal handlers */
2016-08-12 17:32:33 +03:00
struct tevent_fd * wakeup_fde ;
2016-09-07 20:17:21 +03:00
int wakeup_fd ; /* fd to write into */
2016-08-12 17:32:33 +03:00
# ifndef HAVE_EVENT_FD
2016-09-07 20:17:21 +03:00
int wakeup_read_fd ;
2016-08-12 17:32:33 +03:00
# endif
2008-06-14 19:23:31 +04:00
/* debugging operations */
2009-01-02 15:39:56 +03:00
struct tevent_debug_ops debug_ops ;
2009-03-12 11:51:33 +03:00
/* info about the nesting status */
struct {
bool allowed ;
uint32_t level ;
2009-03-12 12:23:30 +03:00
tevent_nesting_hook hook_fn ;
void * hook_private ;
2009-03-12 11:51:33 +03:00
} nesting ;
2012-06-05 10:00:07 +04:00
struct {
2021-06-01 15:10:05 +03:00
struct {
tevent_trace_callback_t callback ;
void * private_data ;
} point ;
struct {
tevent_trace_fd_callback_t callback ;
void * private_data ;
} fde ;
struct {
tevent_trace_signal_callback_t callback ;
void * private_data ;
} se ;
struct {
tevent_trace_timer_callback_t callback ;
void * private_data ;
} te ;
struct {
tevent_trace_immediate_callback_t callback ;
void * private_data ;
} im ;
2022-03-14 13:22:15 +03:00
struct {
tevent_trace_queue_callback_t callback ;
void * private_data ;
} qe ;
2012-06-05 10:00:07 +04:00
} tracing ;
2013-02-22 15:45:39 +04:00
2014-07-22 18:51:38 +04:00
struct {
/*
* This is used on the main event context
*/
struct tevent_wrapper_glue * list ;
/*
* This is used on the wrapper event context
*/
struct tevent_wrapper_glue * glue ;
} wrapper ;
2013-02-22 15:45:39 +04:00
/*
* an optimization pointer into timer_events
* used by used by common code via
* tevent_common_add_timer_v2 ( )
*/
struct tevent_timer * last_zero_timer ;
2016-08-08 12:26:37 +03:00
# ifdef HAVE_PTHREAD
struct tevent_context * prev , * next ;
# endif
2005-02-15 13:36:59 +03:00
} ;
2009-01-05 21:23:23 +03:00
int tevent_common_context_destructor ( struct tevent_context * ev ) ;
2009-03-16 16:15:07 +03:00
int tevent_common_loop_wait ( struct tevent_context * ev ,
const char * location ) ;
2009-01-05 21:23:23 +03:00
2009-01-05 19:36:50 +03:00
int tevent_common_fd_destructor ( struct tevent_fd * fde ) ;
struct tevent_fd * tevent_common_add_fd ( struct tevent_context * ev ,
TALLOC_CTX * mem_ctx ,
int fd ,
uint16_t flags ,
tevent_fd_handler_t handler ,
void * private_data ,
const char * handler_name ,
const char * location ) ;
2009-01-03 13:27:00 +03:00
void tevent_common_fd_set_close_fn ( struct tevent_fd * fde ,
tevent_fd_close_fn_t close_fn ) ;
2009-01-03 13:18:14 +03:00
uint16_t tevent_common_fd_get_flags ( struct tevent_fd * fde ) ;
void tevent_common_fd_set_flags ( struct tevent_fd * fde , uint16_t flags ) ;
2014-07-22 16:45:33 +04:00
int tevent_common_invoke_fd_handler ( struct tevent_fd * fde , uint16_t flags ,
bool * removed ) ;
2009-01-03 13:18:14 +03:00
2009-01-02 15:26:32 +03:00
struct tevent_timer * tevent_common_add_timer ( 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 ) ;
2013-02-22 15:45:39 +04:00
struct tevent_timer * tevent_common_add_timer_v2 ( 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 ) ;
2009-01-02 15:26:32 +03:00
struct timeval tevent_common_loop_timer_delay ( struct tevent_context * ) ;
2014-07-22 15:08:42 +04:00
int tevent_common_invoke_timer_handler ( struct tevent_timer * te ,
struct timeval current_time ,
bool * removed ) ;
2009-01-02 15:26:32 +03:00
2009-03-13 17:47:33 +03:00
void tevent_common_schedule_immediate ( struct tevent_immediate * im ,
struct tevent_context * ev ,
tevent_immediate_handler_t handler ,
void * private_data ,
const char * handler_name ,
const char * location ) ;
2014-07-22 15:08:42 +04:00
int tevent_common_invoke_immediate_handler ( struct tevent_immediate * im ,
bool * removed ) ;
2009-03-13 17:47:33 +03:00
bool tevent_common_loop_immediate ( struct tevent_context * ev ) ;
2016-08-08 12:26:37 +03:00
void tevent_common_threaded_activate_immediate ( struct tevent_context * ev ) ;
2016-07-29 09:53:59 +03:00
bool tevent_common_have_events ( struct tevent_context * ev ) ;
int tevent_common_wakeup_init ( struct tevent_context * ev ) ;
2016-09-07 20:47:55 +03:00
int tevent_common_wakeup_fd ( int fd ) ;
2016-07-29 09:53:59 +03:00
int tevent_common_wakeup ( struct tevent_context * ev ) ;
2009-03-13 17:47:33 +03:00
2009-01-02 15:26:32 +03:00
struct tevent_signal * tevent_common_add_signal ( struct tevent_context * ev ,
TALLOC_CTX * mem_ctx ,
int signum ,
int sa_flags ,
tevent_signal_handler_t handler ,
void * private_data ,
const char * handler_name ,
const char * location ) ;
int tevent_common_check_signal ( struct tevent_context * ev ) ;
2010-02-09 12:02:20 +03:00
void tevent_cleanup_pending_signal_handlers ( struct tevent_signal * se ) ;
2014-07-22 15:01:01 +04:00
int tevent_common_invoke_signal_handler ( struct tevent_signal * se ,
int signum , int count , void * siginfo ,
bool * removed ) ;
2008-06-14 19:23:31 +04:00
2014-07-22 18:51:38 +04:00
struct tevent_context * tevent_wrapper_main_ev ( struct tevent_context * ev ) ;
struct tevent_wrapper_ops ;
struct tevent_wrapper_glue {
struct tevent_wrapper_glue * prev , * next ;
struct tevent_context * wrap_ev ;
struct tevent_context * main_ev ;
bool busy ;
bool destroyed ;
const struct tevent_wrapper_ops * ops ;
void * private_state ;
} ;
void tevent_wrapper_push_use_internal ( struct tevent_context * ev ,
struct tevent_wrapper_glue * wrapper ) ;
void tevent_wrapper_pop_use_internal ( const struct tevent_context * __ev_ptr ,
struct tevent_wrapper_glue * wrapper ) ;
2009-01-02 15:35:32 +03:00
bool tevent_standard_init ( void ) ;
2011-02-09 17:28:10 +03:00
bool tevent_poll_init ( void ) ;
2018-06-18 20:49:52 +03:00
bool tevent_poll_event_add_fd_internal ( struct tevent_context * ev ,
2013-02-11 23:20:28 +04:00
struct tevent_fd * fde ) ;
2012-08-13 18:06:01 +04:00
bool tevent_poll_mt_init ( void ) ;
2009-01-02 15:39:26 +03:00
# ifdef HAVE_EPOLL
2009-01-02 15:35:32 +03:00
bool tevent_epoll_init ( void ) ;
2013-12-11 21:58:41 +04:00
void tevent_epoll_set_panic_fallback ( struct tevent_context * ev ,
2013-02-11 22:43:39 +04:00
bool ( * panic_fallback ) ( struct tevent_context * ev ,
bool replay ) ) ;
2008-06-14 19:23:31 +04:00
# endif
2012-06-05 10:00:07 +04:00
2022-06-16 17:23:22 +03:00
void tevent_thread_call_depth_set ( size_t depth ) ;
2013-02-11 23:20:28 +04:00
2012-06-05 10:00:07 +04:00
void tevent_trace_point_callback ( struct tevent_context * ev ,
enum tevent_trace_point ) ;
2021-06-01 15:10:05 +03:00
void tevent_trace_fd_callback ( struct tevent_context * ev ,
struct tevent_fd * fde ,
enum tevent_event_trace_point ) ;
void tevent_trace_signal_callback ( struct tevent_context * ev ,
struct tevent_signal * se ,
enum tevent_event_trace_point ) ;
void tevent_trace_timer_callback ( struct tevent_context * ev ,
struct tevent_timer * te ,
enum tevent_event_trace_point ) ;
void tevent_trace_immediate_callback ( struct tevent_context * ev ,
struct tevent_immediate * im ,
enum tevent_event_trace_point ) ;
2022-03-14 13:22:15 +03:00
void tevent_trace_queue_callback ( struct tevent_context * ev ,
struct tevent_queue_entry * qe ,
enum tevent_event_trace_point ) ;