1 /* 2 Unix SMB/CIFS implementation. 3 4 generalised event loop handling 5 6 INTERNAL STRUCTS. THERE ARE NO API GUARANTEES. 7 External users should only ever have to include this header when 8 implementing new tevent backends. 9 10 Copyright (C) Stefan Metzmacher 2005-2009 11 12 ** NOTE! The following LGPL license applies to the tevent 13 ** library. This does NOT imply that all of Samba is released 14 ** under the LGPL 15 16 This library is free software; you can redistribute it and/or 17 modify it under the terms of the GNU Lesser General Public 18 License as published by the Free Software Foundation; either 19 version 3 of the License, or (at your option) any later version. 20 21 This library is distributed in the hope that it will be useful, 22 but WITHOUT ANY WARRANTY; without even the implied warranty of 23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24 Lesser General Public License for more details. 25 26 You should have received a copy of the GNU Lesser General Public 27 License along with this library; if not, see <http://www.gnu.org/licenses/>. 28 */ 29 30 struct tevent_req { 31 /** 32 * @brief What to do on completion 33 * 34 * This is used for the user of an async request, fn is called when 35 * the request completes, either successfully or with an error. 36 */ 37 struct { 38 /** 39 * @brief Completion function 40 * Completion function, to be filled by the API user 41 */ 42 tevent_req_fn fn; 43 /** 44 * @brief Private data for the completion function 45 */ 46 void *private_data; 47 } async; 48 49 /** 50 * @brief Private state pointer for the actual implementation 51 * 52 * The implementation doing the work for the async request needs to 53 * keep around current data like for example a fd event. The user of 54 * an async request should not touch this. 55 */ 56 void *data; 57 58 /** 59 * @brief A function to overwrite the default print function 60 * 61 * The implementation doing the work may want to implement a 62 * custom function to print the text representation of the async 63 * request. 64 */ 65 tevent_req_print_fn private_print; 66 67 /** 68 * @brief A function to cancel the request 69 * 70 * The implementation might want to set a function 71 * that is called when the tevent_req_cancel() function 72 * was called. 73 */ 74 tevent_req_cancel_fn private_cancel; 75 76 /** 77 * @brief A function to cleanup the request 78 * 79 * The implementation might want to set a function 80 * that is called before the tevent_req_done() and tevent_req_error() 81 * trigger the callers callback function. 82 */ 83 struct { 84 tevent_req_cleanup_fn fn; 85 enum tevent_req_state state; 86 } private_cleanup; 87 88 /** 89 * @brief Internal state of the request 90 * 91 * Callers should only access this via functions and never directly. 92 */ 93 struct { 94 /** 95 * @brief The talloc type of the data pointer 96 * 97 * This is filled by the tevent_req_create() macro. 98 * 99 * This for debugging only. 100 */ 101 const char *private_type; 102 103 /** 104 * @brief The location where the request was created 105 * 106 * This uses the __location__ macro via the tevent_req_create() 107 * macro. 108 * 109 * This for debugging only. 110 */ 111 const char *create_location; 112 113 /** 114 * @brief The location where the request was finished 115 * 116 * This uses the __location__ macro via the tevent_req_done(), 117 * tevent_req_error() or tevent_req_nomem() macro. 118 * 119 * This for debugging only. 120 */ 121 const char *finish_location; 122 123 /** 124 * @brief The location where the request was canceled 125 * 126 * This uses the __location__ macro via the 127 * tevent_req_cancel() macro. 128 * 129 * This for debugging only. 130 */ 131 const char *cancel_location; 132 133 /** 134 * @brief The external state - will be queried by the caller 135 * 136 * While the async request is being processed, state will remain in 137 * TEVENT_REQ_IN_PROGRESS. A request is finished if 138 * req->state>=TEVENT_REQ_DONE. 139 */ 140 enum tevent_req_state state; 141 142 /** 143 * @brief status code when finished 144 * 145 * This status can be queried in the async completion function. It 146 * will be set to 0 when everything went fine. 147 */ 148 uint64_t error; 149 150 /** 151 * @brief the immediate event used by tevent_req_post 152 * 153 */ 154 struct tevent_immediate *trigger; 155 156 /** 157 * @brief An event context which will be used to 158 * defer the _tevent_req_notify_callback(). 159 */ 160 struct tevent_context *defer_callback_ev; 161 162 /** 163 * @brief the timer event if tevent_req_set_endtime was used 164 * 165 */ 166 struct tevent_timer *timer; 167 168 /** 169 * @brief The place where profiling data is kept 170 */ 171 struct tevent_req_profile *profile; 172 } internal; 173 }; 174 175 struct tevent_req_profile { 176 struct tevent_req_profile *prev, *next; 177 struct tevent_req_profile *parent; 178 const char *req_name; 179 pid_t pid; 180 const char *start_location; 181 struct timeval start_time; 182 const char *stop_location; 183 struct timeval stop_time; 184 enum tevent_req_state state; 185 uint64_t user_error; 186 struct tevent_req_profile *subprofiles; 187 }; 188 189 struct tevent_fd { 190 struct tevent_fd *prev, *next; 191 struct tevent_context *event_ctx; 192 struct tevent_wrapper_glue *wrapper; 193 bool busy; 194 bool destroyed; 195 int fd; 196 uint16_t flags; /* see TEVENT_FD_* flags */ 197 tevent_fd_handler_t handler; 198 tevent_fd_close_fn_t close_fn; 199 /* this is private for the specific handler */ 200 void *private_data; 201 /* this is for debugging only! */ 202 const char *handler_name; 203 const char *location; 204 /* this is private for the events_ops implementation */ 205 uint64_t additional_flags; 206 void *additional_data; 207 }; 208 209 struct tevent_timer { 210 struct tevent_timer *prev, *next; 211 struct tevent_context *event_ctx; 212 struct tevent_wrapper_glue *wrapper; 213 bool busy; 214 bool destroyed; 215 struct timeval next_event; 216 tevent_timer_handler_t handler; 217 /* this is private for the specific handler */ 218 void *private_data; 219 /* this is for debugging only! */ 220 const char *handler_name; 221 const char *location; 222 /* this is private for the events_ops implementation */ 223 void *additional_data; 224 }; 225 226 struct tevent_immediate { 227 struct tevent_immediate *prev, *next; 228 struct tevent_context *event_ctx; 229 struct tevent_wrapper_glue *wrapper; 230 bool busy; 231 bool destroyed; 232 tevent_immediate_handler_t handler; 233 /* this is private for the specific handler */ 234 void *private_data; 235 /* this is for debugging only! */ 236 const char *handler_name; 237 const char *create_location; 238 const char *schedule_location; 239 /* this is private for the events_ops implementation */ 240 void (*cancel_fn)(struct tevent_immediate *im); 241 void *additional_data; 242 }; 243 244 struct tevent_signal { 245 struct tevent_signal *prev, *next; 246 struct tevent_context *event_ctx; 247 struct tevent_wrapper_glue *wrapper; 248 bool busy; 249 bool destroyed; 250 int signum; 251 int sa_flags; 252 tevent_signal_handler_t handler; 253 /* this is private for the specific handler */ 254 void *private_data; 255 /* this is for debugging only! */ 256 const char *handler_name; 257 const char *location; 258 /* this is private for the events_ops implementation */ 259 void *additional_data; 260 }; 261 262 struct tevent_threaded_context { 263 struct tevent_threaded_context *next, *prev; 264 265 #ifdef HAVE_PTHREAD 266 pthread_mutex_t event_ctx_mutex; 267 #endif 268 struct tevent_context *event_ctx; 269 }; 270 271 struct tevent_debug_ops { 272 void (*debug)(void *context, enum tevent_debug_level level, 273 const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); 274 void *context; 275 }; 276 277 void tevent_debug(struct tevent_context *ev, enum tevent_debug_level level, 278 const char *fmt, ...) PRINTF_ATTRIBUTE(3,4); 279 280 void tevent_abort(struct tevent_context *ev, const char *reason); 281 282 void tevent_common_check_double_free(TALLOC_CTX *ptr, const char *reason); 283 284 struct tevent_context { 285 /* the specific events implementation */ 286 const struct tevent_ops *ops; 287 288 /* 289 * The following three pointers are queried on every loop_once 290 * in the order in which they appear here. Not measured, but 291 * hopefully putting them at the top together with "ops" 292 * should make tevent a *bit* more cache-friendly than before. 293 */ 294 295 /* list of signal events - used by common code */ 296 struct tevent_signal *signal_events; 297 298 /* List of threaded job indicators */ 299 struct tevent_threaded_context *threaded_contexts; 300 301 /* list of immediate events - used by common code */ 302 struct tevent_immediate *immediate_events; 303 304 /* list of fd events - used by common code */ 305 struct tevent_fd *fd_events; 306 307 /* list of timed events - used by common code */ 308 struct tevent_timer *timer_events; 309 310 /* List of scheduled immediates */ 311 pthread_mutex_t scheduled_mutex; 312 struct tevent_immediate *scheduled_immediates; 313 314 /* this is private for the events_ops implementation */ 315 void *additional_data; 316 317 /* pipe hack used with signal handlers */ 318 struct tevent_fd *wakeup_fde; 319 int wakeup_fd; /* fd to write into */ 320 #ifndef HAVE_EVENT_FD 321 int wakeup_read_fd; 322 #endif 323 324 /* debugging operations */ 325 struct tevent_debug_ops debug_ops; 326 327 /* info about the nesting status */ 328 struct { 329 bool allowed; 330 uint32_t level; 331 tevent_nesting_hook hook_fn; 332 void *hook_private; 333 } nesting; 334 335 struct { 336 tevent_trace_callback_t callback; 337 void *private_data; 338 } tracing; 339 340 struct { 341 /* 342 * This is used on the main event context 343 */ 344 struct tevent_wrapper_glue *list; 345 346 /* 347 * This is used on the wrapper event context 348 */ 349 struct tevent_wrapper_glue *glue; 350 } wrapper; 351 352 /* 353 * an optimization pointer into timer_events 354 * used by used by common code via 355 * tevent_common_add_timer_v2() 356 */ 357 struct tevent_timer *last_zero_timer; 358 359 #ifdef HAVE_PTHREAD 360 struct tevent_context *prev, *next; 361 #endif 362 }; 363 364 const struct tevent_ops *tevent_find_ops_byname(const char *name); 365 366 int tevent_common_context_destructor(struct tevent_context *ev); 367 int tevent_common_loop_wait(struct tevent_context *ev, 368 const char *location); 369 370 int tevent_common_fd_destructor(struct tevent_fd *fde); 371 struct tevent_fd *tevent_common_add_fd(struct tevent_context *ev, 372 TALLOC_CTX *mem_ctx, 373 int fd, 374 uint16_t flags, 375 tevent_fd_handler_t handler, 376 void *private_data, 377 const char *handler_name, 378 const char *location); 379 void tevent_common_fd_set_close_fn(struct tevent_fd *fde, 380 tevent_fd_close_fn_t close_fn); 381 uint16_t tevent_common_fd_get_flags(struct tevent_fd *fde); 382 void tevent_common_fd_set_flags(struct tevent_fd *fde, uint16_t flags); 383 int tevent_common_invoke_fd_handler(struct tevent_fd *fde, uint16_t flags, 384 bool *removed); 385 386 struct tevent_timer *tevent_common_add_timer(struct tevent_context *ev, 387 TALLOC_CTX *mem_ctx, 388 struct timeval next_event, 389 tevent_timer_handler_t handler, 390 void *private_data, 391 const char *handler_name, 392 const char *location); 393 struct tevent_timer *tevent_common_add_timer_v2(struct tevent_context *ev, 394 TALLOC_CTX *mem_ctx, 395 struct timeval next_event, 396 tevent_timer_handler_t handler, 397 void *private_data, 398 const char *handler_name, 399 const char *location); 400 struct timeval tevent_common_loop_timer_delay(struct tevent_context *); 401 int tevent_common_invoke_timer_handler(struct tevent_timer *te, 402 struct timeval current_time, 403 bool *removed); 404 405 void tevent_common_schedule_immediate(struct tevent_immediate *im, 406 struct tevent_context *ev, 407 tevent_immediate_handler_t handler, 408 void *private_data, 409 const char *handler_name, 410 const char *location); 411 int tevent_common_invoke_immediate_handler(struct tevent_immediate *im, 412 bool *removed); 413 bool tevent_common_loop_immediate(struct tevent_context *ev); 414 void tevent_common_threaded_activate_immediate(struct tevent_context *ev); 415 416 bool tevent_common_have_events(struct tevent_context *ev); 417 int tevent_common_wakeup_init(struct tevent_context *ev); 418 int tevent_common_wakeup_fd(int fd); 419 int tevent_common_wakeup(struct tevent_context *ev); 420 421 struct tevent_signal *tevent_common_add_signal(struct tevent_context *ev, 422 TALLOC_CTX *mem_ctx, 423 int signum, 424 int sa_flags, 425 tevent_signal_handler_t handler, 426 void *private_data, 427 const char *handler_name, 428 const char *location); 429 int tevent_common_check_signal(struct tevent_context *ev); 430 void tevent_cleanup_pending_signal_handlers(struct tevent_signal *se); 431 int tevent_common_invoke_signal_handler(struct tevent_signal *se, 432 int signum, int count, void *siginfo, 433 bool *removed); 434 435 struct tevent_context *tevent_wrapper_main_ev(struct tevent_context *ev); 436 437 struct tevent_wrapper_ops; 438 439 struct tevent_wrapper_glue { 440 struct tevent_wrapper_glue *prev, *next; 441 struct tevent_context *wrap_ev; 442 struct tevent_context *main_ev; 443 bool busy; 444 bool destroyed; 445 const struct tevent_wrapper_ops *ops; 446 void *private_state; 447 }; 448 449 void tevent_wrapper_push_use_internal(struct tevent_context *ev, 450 struct tevent_wrapper_glue *wrapper); 451 void tevent_wrapper_pop_use_internal(const struct tevent_context *__ev_ptr, 452 struct tevent_wrapper_glue *wrapper); 453 454 bool tevent_standard_init(void); 455 bool tevent_poll_init(void); 456 bool tevent_poll_event_add_fd_internal(struct tevent_context *ev, 457 struct tevent_fd *fde); 458 bool tevent_poll_mt_init(void); 459 #ifdef HAVE_EPOLL 460 bool tevent_epoll_init(void); 461 void tevent_epoll_set_panic_fallback(struct tevent_context *ev, 462 bool (*panic_fallback)(struct tevent_context *ev, 463 bool replay)); 464 #endif 465 #ifdef HAVE_SOLARIS_PORTS 466 bool tevent_port_init(void); 467 #endif 468 469 470 void tevent_trace_point_callback(struct tevent_context *ev, 471 enum tevent_trace_point); 472