1 /* 2 Unix SMB/CIFS implementation. 3 4 generalised event loop handling 5 6 Copyright (C) Andrew Tridgell 2005 7 Copyright (C) Stefan Metzmacher 2005-2009 8 Copyright (C) Volker Lendecke 2008 9 10 ** NOTE! The following LGPL license applies to the tevent 11 ** library. This does NOT imply that all of Samba is released 12 ** under the LGPL 13 14 This library is free software; you can redistribute it and/or 15 modify it under the terms of the GNU Lesser General Public 16 License as published by the Free Software Foundation; either 17 version 3 of the License, or (at your option) any later version. 18 19 This library is distributed in the hope that it will be useful, 20 but WITHOUT ANY WARRANTY; without even the implied warranty of 21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 Lesser General Public License for more details. 23 24 You should have received a copy of the GNU Lesser General Public 25 License along with this library; if not, see <http://www.gnu.org/licenses/>. 26 */ 27 28 #ifndef __TEVENT_H__ 29 #define __TEVENT_H__ 30 31 #include <stdint.h> 32 #include <talloc.h> 33 #include <sys/time.h> 34 #include <stdbool.h> 35 36 struct tevent_context; 37 struct tevent_ops; 38 struct tevent_fd; 39 struct tevent_timer; 40 struct tevent_immediate; 41 struct tevent_signal; 42 struct tevent_thread_proxy; 43 struct tevent_threaded_context; 44 45 /** 46 * @defgroup tevent The tevent API 47 * 48 * The tevent low-level API 49 * 50 * This API provides the public interface to manage events in the tevent 51 * mainloop. Functions are provided for managing low-level events such 52 * as timer events, fd events and signal handling. 53 * 54 * @{ 55 */ 56 57 /* event handler types */ 58 /** 59 * Called when a file descriptor monitored by tevent has 60 * data to be read or written on it. 61 */ 62 typedef void (*tevent_fd_handler_t)(struct tevent_context *ev, 63 struct tevent_fd *fde, 64 uint16_t flags, 65 void *private_data); 66 67 /** 68 * Called when tevent is ceasing the monitoring of a file descriptor. 69 */ 70 typedef void (*tevent_fd_close_fn_t)(struct tevent_context *ev, 71 struct tevent_fd *fde, 72 int fd, 73 void *private_data); 74 75 /** 76 * Called when a tevent timer has fired. 77 */ 78 typedef void (*tevent_timer_handler_t)(struct tevent_context *ev, 79 struct tevent_timer *te, 80 struct timeval current_time, 81 void *private_data); 82 83 /** 84 * Called when a tevent immediate event is invoked. 85 */ 86 typedef void (*tevent_immediate_handler_t)(struct tevent_context *ctx, 87 struct tevent_immediate *im, 88 void *private_data); 89 90 /** 91 * Called after tevent detects the specified signal. 92 */ 93 typedef void (*tevent_signal_handler_t)(struct tevent_context *ev, 94 struct tevent_signal *se, 95 int signum, 96 int count, 97 void *siginfo, 98 void *private_data); 99 100 /** 101 * @brief Create a event_context structure. 102 * 103 * This must be the first events call, and all subsequent calls pass this 104 * event_context as the first element. Event handlers also receive this as 105 * their first argument. 106 * 107 * @param[in] mem_ctx The memory context to use. 108 * 109 * @return An allocated tevent context, NULL on error. 110 * 111 * @see tevent_context_init() 112 */ 113 struct tevent_context *tevent_context_init(TALLOC_CTX *mem_ctx); 114 115 /** 116 * @brief Create a event_context structure and select a specific backend. 117 * 118 * This must be the first events call, and all subsequent calls pass this 119 * event_context as the first element. Event handlers also receive this as 120 * their first argument. 121 * 122 * @param[in] mem_ctx The memory context to use. 123 * 124 * @param[in] name The name of the backend to use. 125 * 126 * @return An allocated tevent context, NULL on error. 127 */ 128 struct tevent_context *tevent_context_init_byname(TALLOC_CTX *mem_ctx, const char *name); 129 130 /** 131 * @brief Create a custom event context 132 * 133 * @param[in] mem_ctx The memory context to use. 134 * @param[in] ops The function pointer table of the backend. 135 * @param[in] additional_data The additional/private data to this instance 136 * 137 * @return An allocated tevent context, NULL on error. 138 * 139 */ 140 struct tevent_context *tevent_context_init_ops(TALLOC_CTX *mem_ctx, 141 const struct tevent_ops *ops, 142 void *additional_data); 143 144 /** 145 * @brief List available backends. 146 * 147 * @param[in] mem_ctx The memory context to use. 148 * 149 * @return A string vector with a terminating NULL element, NULL 150 * on error. 151 */ 152 const char **tevent_backend_list(TALLOC_CTX *mem_ctx); 153 154 /** 155 * @brief Set the default tevent backend. 156 * 157 * @param[in] backend The name of the backend to set. 158 */ 159 void tevent_set_default_backend(const char *backend); 160 161 #ifdef DOXYGEN 162 /** 163 * @brief Add a file descriptor based event. 164 * 165 * @param[in] ev The event context to work on. 166 * 167 * @param[in] mem_ctx The talloc memory context to use. 168 * 169 * @param[in] fd The file descriptor to base the event on. 170 * 171 * @param[in] flags #TEVENT_FD_READ or #TEVENT_FD_WRITE 172 * 173 * @param[in] handler The callback handler for the event. 174 * 175 * @param[in] private_data The private data passed to the callback handler. 176 * 177 * @return The file descriptor based event, NULL on error. 178 * 179 * @note To cancel the monitoring of a file descriptor, call talloc_free() 180 * on the object returned by this function. 181 * 182 * @note The caller should avoid closing the file descriptor before 183 * calling talloc_free()! Otherwise the behaviour is undefined which 184 * might result in crashes. See https://bugzilla.samba.org/show_bug.cgi?id=11141 185 * for an example. 186 */ 187 struct tevent_fd *tevent_add_fd(struct tevent_context *ev, 188 TALLOC_CTX *mem_ctx, 189 int fd, 190 uint16_t flags, 191 tevent_fd_handler_t handler, 192 void *private_data); 193 #else 194 struct tevent_fd *_tevent_add_fd(struct tevent_context *ev, 195 TALLOC_CTX *mem_ctx, 196 int fd, 197 uint16_t flags, 198 tevent_fd_handler_t handler, 199 void *private_data, 200 const char *handler_name, 201 const char *location); 202 #define tevent_add_fd(ev, mem_ctx, fd, flags, handler, private_data) \ 203 _tevent_add_fd(ev, mem_ctx, fd, flags, handler, private_data, \ 204 #handler, __location__) 205 #endif 206 207 #ifdef DOXYGEN 208 /** 209 * @brief Add a timed event 210 * 211 * @param[in] ev The event context to work on. 212 * 213 * @param[in] mem_ctx The talloc memory context to use. 214 * 215 * @param[in] next_event Timeval specifying the absolute time to fire this 216 * event. This is not an offset. 217 * 218 * @param[in] handler The callback handler for the event. 219 * 220 * @param[in] private_data The private data passed to the callback handler. 221 * 222 * @return The newly-created timer event, or NULL on error. 223 * 224 * @note To cancel a timer event before it fires, call talloc_free() on the 225 * event returned from this function. This event is automatically 226 * talloc_free()-ed after its event handler files, if it hasn't been freed yet. 227 * 228 * @note Unlike some mainloops, tevent timers are one-time events. To set up 229 * a recurring event, it is necessary to call tevent_add_timer() again during 230 * the handler processing. 231 * 232 * @note Due to the internal mainloop processing, a timer set to run 233 * immediately will do so after any other pending timers fire, but before 234 * any further file descriptor or signal handling events fire. Callers should 235 * not rely on this behavior! 236 */ 237 struct tevent_timer *tevent_add_timer(struct tevent_context *ev, 238 TALLOC_CTX *mem_ctx, 239 struct timeval next_event, 240 tevent_timer_handler_t handler, 241 void *private_data); 242 #else 243 struct tevent_timer *_tevent_add_timer(struct tevent_context *ev, 244 TALLOC_CTX *mem_ctx, 245 struct timeval next_event, 246 tevent_timer_handler_t handler, 247 void *private_data, 248 const char *handler_name, 249 const char *location); 250 #define tevent_add_timer(ev, mem_ctx, next_event, handler, private_data) \ 251 _tevent_add_timer(ev, mem_ctx, next_event, handler, private_data, \ 252 #handler, __location__) 253 #endif 254 255 /** 256 * @brief Set the time a tevent_timer fires 257 * 258 * @param[in] te The timer event to reset 259 * 260 * @param[in] next_event Timeval specifying the absolute time to fire this 261 * event. This is not an offset. 262 */ 263 void tevent_update_timer(struct tevent_timer *te, struct timeval next_event); 264 265 #ifdef DOXYGEN 266 /** 267 * Initialize an immediate event object 268 * 269 * This object can be used to trigger an event to occur immediately after 270 * returning from the current event (before any other event occurs) 271 * 272 * @param[in] mem_ctx The talloc memory context to use as the parent 273 * 274 * @return An empty tevent_immediate object. Use tevent_schedule_immediate 275 * to populate and use it. 276 * 277 * @note Available as of tevent 0.9.8 278 */ 279 struct tevent_immediate *tevent_create_immediate(TALLOC_CTX *mem_ctx); 280 #else 281 struct tevent_immediate *_tevent_create_immediate(TALLOC_CTX *mem_ctx, 282 const char *location); 283 #define tevent_create_immediate(mem_ctx) \ 284 _tevent_create_immediate(mem_ctx, __location__) 285 #endif 286 287 #ifdef DOXYGEN 288 289 /** 290 * Schedule an event for immediate execution. This event will occur 291 * immediately after returning from the current event (before any other 292 * event occurs) 293 * 294 * @param[in] im The tevent_immediate object to populate and use 295 * @param[in] ctx The tevent_context to run this event 296 * @param[in] handler The event handler to run when this event fires 297 * @param[in] private_data Data to pass to the event handler 298 */ 299 void tevent_schedule_immediate(struct tevent_immediate *im, 300 struct tevent_context *ctx, 301 tevent_immediate_handler_t handler, 302 void *private_data); 303 #else 304 void _tevent_schedule_immediate(struct tevent_immediate *im, 305 struct tevent_context *ctx, 306 tevent_immediate_handler_t handler, 307 void *private_data, 308 const char *handler_name, 309 const char *location); 310 #define tevent_schedule_immediate(im, ctx, handler, private_data) \ 311 _tevent_schedule_immediate(im, ctx, handler, private_data, \ 312 #handler, __location__); 313 #endif 314 315 #ifdef DOXYGEN 316 /** 317 * @brief Add a tevent signal handler 318 * 319 * tevent_add_signal() creates a new event for handling a signal the next 320 * time through the mainloop. It implements a very simple traditional signal 321 * handler whose only purpose is to add the handler event into the mainloop. 322 * 323 * @param[in] ev The event context to work on. 324 * 325 * @param[in] mem_ctx The talloc memory context to use. 326 * 327 * @param[in] signum The signal to trap 328 * 329 * @param[in] handler The callback handler for the signal. 330 * 331 * @param[in] sa_flags sigaction flags for this signal handler. 332 * 333 * @param[in] private_data The private data passed to the callback handler. 334 * 335 * @return The newly-created signal handler event, or NULL on error. 336 * 337 * @note To cancel a signal handler, call talloc_free() on the event returned 338 * from this function. 339 * 340 * @see tevent_num_signals, tevent_sa_info_queue_count 341 */ 342 struct tevent_signal *tevent_add_signal(struct tevent_context *ev, 343 TALLOC_CTX *mem_ctx, 344 int signum, 345 int sa_flags, 346 tevent_signal_handler_t handler, 347 void *private_data); 348 #else 349 struct tevent_signal *_tevent_add_signal(struct tevent_context *ev, 350 TALLOC_CTX *mem_ctx, 351 int signum, 352 int sa_flags, 353 tevent_signal_handler_t handler, 354 void *private_data, 355 const char *handler_name, 356 const char *location); 357 #define tevent_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data) \ 358 _tevent_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data, \ 359 #handler, __location__) 360 #endif 361 362 /** 363 * @brief the number of supported signals 364 * 365 * This returns value of the configure time TEVENT_NUM_SIGNALS constant. 366 * 367 * The 'signum' argument of tevent_add_signal() must be less than 368 * TEVENT_NUM_SIGNALS. 369 * 370 * @see tevent_add_signal 371 */ 372 size_t tevent_num_signals(void); 373 374 /** 375 * @brief the number of pending realtime signals 376 * 377 * This returns value of TEVENT_SA_INFO_QUEUE_COUNT. 378 * 379 * The tevent internals remember the last TEVENT_SA_INFO_QUEUE_COUNT 380 * siginfo_t structures for SA_SIGINFO signals. If the system generates 381 * more some signals get lost. 382 * 383 * @see tevent_add_signal 384 */ 385 size_t tevent_sa_info_queue_count(void); 386 387 #ifdef DOXYGEN 388 /** 389 * @brief Pass a single time through the mainloop 390 * 391 * This will process any appropriate signal, immediate, fd and timer events 392 * 393 * @param[in] ev The event context to process 394 * 395 * @return Zero on success, nonzero if an internal error occurred 396 */ 397 int tevent_loop_once(struct tevent_context *ev); 398 #else 399 int _tevent_loop_once(struct tevent_context *ev, const char *location); 400 #define tevent_loop_once(ev) \ 401 _tevent_loop_once(ev, __location__) 402 #endif 403 404 #ifdef DOXYGEN 405 /** 406 * @brief Run the mainloop 407 * 408 * The mainloop will run until there are no events remaining to be processed 409 * 410 * @param[in] ev The event context to process 411 * 412 * @return Zero if all events have been processed. Nonzero if an internal 413 * error occurred. 414 */ 415 int tevent_loop_wait(struct tevent_context *ev); 416 #else 417 int _tevent_loop_wait(struct tevent_context *ev, const char *location); 418 #define tevent_loop_wait(ev) \ 419 _tevent_loop_wait(ev, __location__) 420 #endif 421 422 423 /** 424 * Assign a function to run when a tevent_fd is freed 425 * 426 * This function is a destructor for the tevent_fd. It does not automatically 427 * close the file descriptor. If this is the desired behavior, then it must be 428 * performed by the close_fn. 429 * 430 * @param[in] fde File descriptor event on which to set the destructor 431 * @param[in] close_fn Destructor to execute when fde is freed 432 * 433 * @note That the close_fn() on tevent_fd is *NOT* wrapped on contexts 434 * created by tevent_context_wrapper_create()! 435 * 436 * @see tevent_fd_set_close_fn 437 * @see tevent_context_wrapper_create 438 */ 439 void tevent_fd_set_close_fn(struct tevent_fd *fde, 440 tevent_fd_close_fn_t close_fn); 441 442 /** 443 * Automatically close the file descriptor when the tevent_fd is freed 444 * 445 * This function calls close(fd) internally. 446 * 447 * @param[in] fde File descriptor event to auto-close 448 * 449 * @see tevent_fd_set_close_fn 450 */ 451 void tevent_fd_set_auto_close(struct tevent_fd *fde); 452 453 /** 454 * Return the flags set on this file descriptor event 455 * 456 * @param[in] fde File descriptor event to query 457 * 458 * @return The flags set on the event. See #TEVENT_FD_READ and 459 * #TEVENT_FD_WRITE 460 */ 461 uint16_t tevent_fd_get_flags(struct tevent_fd *fde); 462 463 /** 464 * Set flags on a file descriptor event 465 * 466 * @param[in] fde File descriptor event to set 467 * @param[in] flags Flags to set on the event. See #TEVENT_FD_READ and 468 * #TEVENT_FD_WRITE 469 */ 470 void tevent_fd_set_flags(struct tevent_fd *fde, uint16_t flags); 471 472 /** 473 * Query whether tevent supports signal handling 474 * 475 * @param[in] ev An initialized tevent context 476 * 477 * @return True if this platform and tevent context support signal handling 478 */ 479 bool tevent_signal_support(struct tevent_context *ev); 480 481 void tevent_set_abort_fn(void (*abort_fn)(const char *reason)); 482 483 /* bits for file descriptor event flags */ 484 485 /** 486 * Monitor a file descriptor for data to be read 487 */ 488 #define TEVENT_FD_READ 1 489 /** 490 * Monitor a file descriptor for writeability 491 */ 492 #define TEVENT_FD_WRITE 2 493 494 /** 495 * Convenience function for declaring a tevent_fd writable 496 */ 497 #define TEVENT_FD_WRITEABLE(fde) \ 498 tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) | TEVENT_FD_WRITE) 499 500 /** 501 * Convenience function for declaring a tevent_fd readable 502 */ 503 #define TEVENT_FD_READABLE(fde) \ 504 tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) | TEVENT_FD_READ) 505 506 /** 507 * Convenience function for declaring a tevent_fd non-writable 508 */ 509 #define TEVENT_FD_NOT_WRITEABLE(fde) \ 510 tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) & ~TEVENT_FD_WRITE) 511 512 /** 513 * Convenience function for declaring a tevent_fd non-readable 514 */ 515 #define TEVENT_FD_NOT_READABLE(fde) \ 516 tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) & ~TEVENT_FD_READ) 517 518 /** 519 * Debug level of tevent 520 */ 521 enum tevent_debug_level { 522 TEVENT_DEBUG_FATAL, 523 TEVENT_DEBUG_ERROR, 524 TEVENT_DEBUG_WARNING, 525 TEVENT_DEBUG_TRACE 526 }; 527 528 /** 529 * @brief The tevent debug callbac. 530 * 531 * @param[in] context The memory context to use. 532 * 533 * @param[in] level The debug level. 534 * 535 * @param[in] fmt The format string. 536 * 537 * @param[in] ap The arguments for the format string. 538 */ 539 typedef void (*tevent_debug_fn)(void *context, 540 enum tevent_debug_level level, 541 const char *fmt, 542 va_list ap) PRINTF_ATTRIBUTE(3,0); 543 544 /** 545 * Set destination for tevent debug messages 546 * 547 * @param[in] ev Event context to debug 548 * @param[in] debug Function to handle output printing 549 * @param[in] context The context to pass to the debug function. 550 * 551 * @return Always returns 0 as of version 0.9.8 552 * 553 * @note Default is to emit no debug messages 554 */ 555 int tevent_set_debug(struct tevent_context *ev, 556 tevent_debug_fn debug, 557 void *context); 558 559 /** 560 * Designate stderr for debug message output 561 * 562 * @param[in] ev Event context to debug 563 * 564 * @note This function will only output TEVENT_DEBUG_FATAL, TEVENT_DEBUG_ERROR 565 * and TEVENT_DEBUG_WARNING messages. For TEVENT_DEBUG_TRACE, please define a 566 * function for tevent_set_debug() 567 */ 568 int tevent_set_debug_stderr(struct tevent_context *ev); 569 570 enum tevent_trace_point { 571 /** 572 * Corresponds to a trace point just before waiting 573 */ 574 TEVENT_TRACE_BEFORE_WAIT, 575 /** 576 * Corresponds to a trace point just after waiting 577 */ 578 TEVENT_TRACE_AFTER_WAIT, 579 #define TEVENT_HAS_LOOP_ONCE_TRACE_POINTS 1 580 /** 581 * Corresponds to a trace point just before calling 582 * the loop_once() backend function. 583 */ 584 TEVENT_TRACE_BEFORE_LOOP_ONCE, 585 /** 586 * Corresponds to a trace point right after the 587 * loop_once() backend function has returned. 588 */ 589 TEVENT_TRACE_AFTER_LOOP_ONCE, 590 }; 591 592 typedef void (*tevent_trace_callback_t)(enum tevent_trace_point, 593 void *private_data); 594 595 /** 596 * Register a callback to be called at certain trace points 597 * 598 * @param[in] ev Event context 599 * @param[in] cb Trace callback 600 * @param[in] private_data Data to be passed to callback 601 * 602 * @note The callback will be called at trace points defined by 603 * tevent_trace_point. Call with NULL to reset. 604 */ 605 void tevent_set_trace_callback(struct tevent_context *ev, 606 tevent_trace_callback_t cb, 607 void *private_data); 608 609 /** 610 * Retrieve the current trace callback 611 * 612 * @param[in] ev Event context 613 * @param[out] cb Registered trace callback 614 * @param[out] private_data Registered data to be passed to callback 615 * 616 * @note This can be used to allow one component that wants to 617 * register a callback to respect the callback that another component 618 * has already registered. 619 */ 620 void tevent_get_trace_callback(struct tevent_context *ev, 621 tevent_trace_callback_t *cb, 622 void *private_data); 623 624 /** 625 * @} 626 */ 627 628 /** 629 * @defgroup tevent_request The tevent request functions. 630 * @ingroup tevent 631 * 632 * A tevent_req represents an asynchronous computation. 633 * 634 * The tevent_req group of API calls is the recommended way of 635 * programming async computations within tevent. In particular the 636 * file descriptor (tevent_add_fd) and timer (tevent_add_timed) events 637 * are considered too low-level to be used in larger computations. To 638 * read and write from and to sockets, Samba provides two calls on top 639 * of tevent_add_fd: tstream_read_packet_send/recv and tstream_writev_send/recv. 640 * These requests are much easier to compose than the low-level event 641 * handlers called from tevent_add_fd. 642 * 643 * A lot of the simplicity tevent_req has brought to the notoriously 644 * hairy async programming came via a set of conventions that every 645 * async computation programmed should follow. One central piece of 646 * these conventions is the naming of routines and variables. 647 * 648 * Every async computation needs a name (sensibly called "computation" 649 * down from here). From this name quite a few naming conventions are 650 * derived. 651 * 652 * Every computation that requires local state needs a 653 * @code 654 * struct computation_state { 655 * int local_var; 656 * }; 657 * @endcode 658 * Even if no local variables are required, such a state struct should 659 * be created containing a dummy variable. Quite a few helper 660 * functions and macros (for example tevent_req_create()) assume such 661 * a state struct. 662 * 663 * An async computation is started by a computation_send 664 * function. When it is finished, its result can be received by a 665 * computation_recv function. For an example how to set up an async 666 * computation, see the code example in the documentation for 667 * tevent_req_create() and tevent_req_post(). The prototypes for _send 668 * and _recv functions should follow some conventions: 669 * 670 * @code 671 * struct tevent_req *computation_send(TALLOC_CTX *mem_ctx, 672 * struct tevent_context *ev, 673 * ... further args); 674 * int computation_recv(struct tevent_req *req, ... further output args); 675 * @endcode 676 * 677 * The "int" result of computation_recv() depends on the result the 678 * sync version of the function would have, "int" is just an example 679 * here. 680 * 681 * Another important piece of the conventions is that the program flow 682 * is interrupted as little as possible. Because a blocking 683 * sub-computation requires that the flow needs to continue in a 684 * separate function that is the logical sequel of some computation, 685 * it should lexically follow sending off the blocking 686 * sub-computation. Setting the callback function via 687 * tevent_req_set_callback() requires referencing a function lexically 688 * below the call to tevent_req_set_callback(), forward declarations 689 * are required. A lot of the async computations thus begin with a 690 * sequence of declarations such as 691 * 692 * @code 693 * static void computation_step1_done(struct tevent_req *subreq); 694 * static void computation_step2_done(struct tevent_req *subreq); 695 * static void computation_step3_done(struct tevent_req *subreq); 696 * @endcode 697 * 698 * It really helps readability a lot to do these forward declarations, 699 * because the lexically sequential program flow makes the async 700 * computations almost as clear to read as a normal, sync program 701 * flow. 702 * 703 * It is up to the user of the async computation to talloc_free it 704 * after it has finished. If an async computation should be aborted, 705 * the tevent_req structure can be talloc_free'ed. After it has 706 * finished, it should talloc_free'ed by the API user. 707 * 708 * tevent_req variable naming conventions: 709 * 710 * The name of the variable pointing to the tevent_req structure 711 * returned by a _send() function SHOULD be named differently between 712 * implementation and caller. 713 * 714 * From the point of view of the implementation (of the _send() and 715 * _recv() functions) the variable returned by tevent_req_create() is 716 * always called @em req. 717 * 718 * While the caller of the _send() function should use @em subreq to 719 * hold the result. 720 * 721 * @see tevent_req_create() 722 * @see tevent_req_fn() 723 * 724 * @{ 725 */ 726 727 /** 728 * An async request moves from TEVENT_REQ_INIT to 729 * TEVENT_REQ_IN_PROGRESS. All other states are valid after a request 730 * has finished. 731 */ 732 enum tevent_req_state { 733 /** 734 * We are creating the request 735 */ 736 TEVENT_REQ_INIT, 737 /** 738 * We are waiting the request to complete 739 */ 740 TEVENT_REQ_IN_PROGRESS, 741 /** 742 * The request is finished successfully 743 */ 744 TEVENT_REQ_DONE, 745 /** 746 * A user error has occurred. The user error has been 747 * indicated by tevent_req_error(), it can be retrieved via 748 * tevent_req_is_error(). 749 */ 750 TEVENT_REQ_USER_ERROR, 751 /** 752 * Request timed out after the timeout set by tevent_req_set_endtime. 753 */ 754 TEVENT_REQ_TIMED_OUT, 755 /** 756 * An internal allocation has failed, or tevent_req_nomem has 757 * been given a NULL pointer as the first argument. 758 */ 759 TEVENT_REQ_NO_MEMORY, 760 /** 761 * The request has been received by the caller. No further 762 * action is valid. 763 */ 764 TEVENT_REQ_RECEIVED 765 }; 766 767 /** 768 * @brief An async request 769 */ 770 struct tevent_req; 771 772 /** 773 * @brief A tevent request callback function. 774 * 775 * @param[in] subreq The tevent async request which executed this callback. 776 */ 777 typedef void (*tevent_req_fn)(struct tevent_req *subreq); 778 779 /** 780 * @brief Set an async request callback. 781 * 782 * See the documentation of tevent_req_post() for an example how this 783 * is supposed to be used. 784 * 785 * @param[in] req The async request to set the callback. 786 * 787 * @param[in] fn The callback function to set. 788 * 789 * @param[in] pvt A pointer to private data to pass to the async request 790 * callback. 791 */ 792 void tevent_req_set_callback(struct tevent_req *req, tevent_req_fn fn, void *pvt); 793 794 #ifdef DOXYGEN 795 /** 796 * @brief Get the private data cast to the given type for a callback from 797 * a tevent request structure. 798 * 799 * @code 800 * static void computation_done(struct tevent_req *subreq) { 801 * struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); 802 * struct computation_state *state = tevent_req_data(req, struct computation_state); 803 * .... more things, eventually maybe call tevent_req_done(req); 804 * } 805 * @endcode 806 * 807 * @param[in] req The structure to get the callback data from. 808 * 809 * @param[in] type The type of the private callback data to get. 810 * 811 * @return The type casted private data set NULL if not set. 812 */ 813 void *tevent_req_callback_data(struct tevent_req *req, #type); 814 #else 815 void *_tevent_req_callback_data(struct tevent_req *req); 816 #define tevent_req_callback_data(_req, _type) \ 817 talloc_get_type_abort(_tevent_req_callback_data(_req), _type) 818 #endif 819 820 #ifdef DOXYGEN 821 /** 822 * @brief Get the private data for a callback from a tevent request structure. 823 * 824 * @param[in] req The structure to get the callback data from. 825 * 826 * @return The private data or NULL if not set. 827 */ 828 void *tevent_req_callback_data_void(struct tevent_req *req); 829 #else 830 #define tevent_req_callback_data_void(_req) \ 831 _tevent_req_callback_data(_req) 832 #endif 833 834 #ifdef DOXYGEN 835 /** 836 * @brief Get the private data from a tevent request structure. 837 * 838 * When the tevent_req has been created by tevent_req_create, the 839 * result of tevent_req_data() is the state variable created by 840 * tevent_req_create() as a child of the req. 841 * 842 * @param[in] req The structure to get the private data from. 843 * 844 * @param[in] type The type of the private data 845 * 846 * @return The private data or NULL if not set. 847 */ 848 void *tevent_req_data(struct tevent_req *req, #type); 849 #else 850 void *_tevent_req_data(struct tevent_req *req); 851 #define tevent_req_data(_req, _type) \ 852 talloc_get_type_abort(_tevent_req_data(_req), _type) 853 #endif 854 855 /** 856 * @brief The print function which can be set for a tevent async request. 857 * 858 * @param[in] req The tevent async request. 859 * 860 * @param[in] ctx A talloc memory context which can be uses to allocate 861 * memory. 862 * 863 * @return An allocated string buffer to print. 864 * 865 * Example: 866 * @code 867 * static char *my_print(struct tevent_req *req, TALLOC_CTX *mem_ctx) 868 * { 869 * struct my_data *data = tevent_req_data(req, struct my_data); 870 * char *result; 871 * 872 * result = tevent_req_default_print(mem_ctx, req); 873 * if (result == NULL) { 874 * return NULL; 875 * } 876 * 877 * return talloc_asprintf_append_buffer(result, "foo=%d, bar=%d", 878 * data->foo, data->bar); 879 * } 880 * @endcode 881 */ 882 typedef char *(*tevent_req_print_fn)(struct tevent_req *req, TALLOC_CTX *ctx); 883 884 /** 885 * @brief This function sets a print function for the given request. 886 * 887 * This function can be used to setup a print function for the given request. 888 * This will be triggered if the tevent_req_print() function was 889 * called on the given request. 890 * 891 * @param[in] req The request to use. 892 * 893 * @param[in] fn A pointer to the print function 894 * 895 * @note This function should only be used for debugging. 896 */ 897 void tevent_req_set_print_fn(struct tevent_req *req, tevent_req_print_fn fn); 898 899 /** 900 * @brief The default print function for creating debug messages. 901 * 902 * The function should not be used by users of the async API, 903 * but custom print function can use it and append custom text 904 * to the string. 905 * 906 * @param[in] req The request to be printed. 907 * 908 * @param[in] mem_ctx The memory context for the result. 909 * 910 * @return Text representation of request. 911 * 912 */ 913 char *tevent_req_default_print(struct tevent_req *req, TALLOC_CTX *mem_ctx); 914 915 /** 916 * @brief Print an tevent_req structure in debug messages. 917 * 918 * This function should be used by callers of the async API. 919 * 920 * @param[in] mem_ctx The memory context for the result. 921 * 922 * @param[in] req The request to be printed. 923 * 924 * @return Text representation of request. 925 */ 926 char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req); 927 928 /** 929 * @brief A typedef for a cancel function for a tevent request. 930 * 931 * @param[in] req The tevent request calling this function. 932 * 933 * @return True if the request could be canceled, false if not. 934 */ 935 typedef bool (*tevent_req_cancel_fn)(struct tevent_req *req); 936 937 /** 938 * @brief This function sets a cancel function for the given tevent request. 939 * 940 * This function can be used to setup a cancel function for the given request. 941 * This will be triggered if the tevent_req_cancel() function was 942 * called on the given request. 943 * 944 * @param[in] req The request to use. 945 * 946 * @param[in] fn A pointer to the cancel function. 947 */ 948 void tevent_req_set_cancel_fn(struct tevent_req *req, tevent_req_cancel_fn fn); 949 950 #ifdef DOXYGEN 951 /** 952 * @brief Try to cancel the given tevent request. 953 * 954 * This function can be used to cancel the given request. 955 * 956 * It is only possible to cancel a request when the implementation 957 * has registered a cancel function via the tevent_req_set_cancel_fn(). 958 * 959 * @param[in] req The request to use. 960 * 961 * @return This function returns true if the request is 962 * cancelable, otherwise false is returned. 963 * 964 * @note Even if the function returns true, the caller need to wait 965 * for the function to complete normally. 966 * Only the _recv() function of the given request indicates 967 * if the request was really canceled. 968 */ 969 bool tevent_req_cancel(struct tevent_req *req); 970 #else 971 bool _tevent_req_cancel(struct tevent_req *req, const char *location); 972 #define tevent_req_cancel(req) \ 973 _tevent_req_cancel(req, __location__) 974 #endif 975 976 /** 977 * @brief A typedef for a cleanup function for a tevent request. 978 * 979 * @param[in] req The tevent request calling this function. 980 * 981 * @param[in] req_state The current tevent_req_state. 982 * 983 */ 984 typedef void (*tevent_req_cleanup_fn)(struct tevent_req *req, 985 enum tevent_req_state req_state); 986 987 /** 988 * @brief This function sets a cleanup function for the given tevent request. 989 * 990 * This function can be used to setup a cleanup function for the given request. 991 * This will be triggered when the tevent_req_done() or tevent_req_error() 992 * function was called, before notifying the callers callback function, 993 * and also before scheduling the deferred trigger. 994 * 995 * This might be useful if more than one tevent_req belong together 996 * and need to finish both requests at the same time. 997 * 998 * The cleanup function is able to call tevent_req_done() or tevent_req_error() 999 * recursively, the cleanup function is only triggered the first time. 1000 * 1001 * The cleanup function is also called by tevent_req_received() 1002 * (possibly triggered from tevent_req_destructor()) before destroying 1003 * the private data of the tevent_req. 1004 * 1005 * @param[in] req The request to use. 1006 * 1007 * @param[in] fn A pointer to the cancel function. 1008 */ 1009 void tevent_req_set_cleanup_fn(struct tevent_req *req, tevent_req_cleanup_fn fn); 1010 1011 #ifdef DOXYGEN 1012 /** 1013 * @brief Create an async tevent request. 1014 * 1015 * The new async request will be initialized in state TEVENT_REQ_IN_PROGRESS. 1016 * 1017 * @code 1018 * struct tevent_req *req; 1019 * struct computation_state *state; 1020 * req = tevent_req_create(mem_ctx, &state, struct computation_state); 1021 * @endcode 1022 * 1023 * Tevent_req_create() allocates and zeros the state variable as a talloc 1024 * child of its result. The state variable should be used as the talloc 1025 * parent for all temporary variables that are allocated during the async 1026 * computation. This way, when the user of the async computation frees 1027 * the request, the state as a talloc child will be free'd along with 1028 * all the temporary variables hanging off the state. 1029 * 1030 * @param[in] mem_ctx The memory context for the result. 1031 * @param[in] pstate Pointer to the private request state. 1032 * @param[in] type The name of the request. 1033 * 1034 * @return A new async request. NULL on error. 1035 */ 1036 struct tevent_req *tevent_req_create(TALLOC_CTX *mem_ctx, 1037 void **pstate, #type); 1038 #else 1039 struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx, 1040 void *pstate, 1041 size_t state_size, 1042 const char *type, 1043 const char *location); 1044 1045 #define tevent_req_create(_mem_ctx, _pstate, _type) \ 1046 _tevent_req_create((_mem_ctx), (_pstate), sizeof(_type), \ 1047 #_type, __location__) 1048 #endif 1049 1050 /** 1051 * @brief Set a timeout for an async request. On failure, "req" is already 1052 * set to state TEVENT_REQ_NO_MEMORY. 1053 * 1054 * @param[in] req The request to set the timeout for. 1055 * 1056 * @param[in] ev The event context to use for the timer. 1057 * 1058 * @param[in] endtime The endtime of the request. 1059 * 1060 * @return True if succeeded, false if not. 1061 */ 1062 bool tevent_req_set_endtime(struct tevent_req *req, 1063 struct tevent_context *ev, 1064 struct timeval endtime); 1065 1066 /** 1067 * @brief Reset the timer set by tevent_req_set_endtime. 1068 * 1069 * @param[in] req The request to reset the timeout for 1070 */ 1071 void tevent_req_reset_endtime(struct tevent_req *req); 1072 1073 #ifdef DOXYGEN 1074 /** 1075 * @brief Call the notify callback of the given tevent request manually. 1076 * 1077 * @param[in] req The tevent request to call the notify function from. 1078 * 1079 * @see tevent_req_set_callback() 1080 */ 1081 void tevent_req_notify_callback(struct tevent_req *req); 1082 #else 1083 void _tevent_req_notify_callback(struct tevent_req *req, const char *location); 1084 #define tevent_req_notify_callback(req) \ 1085 _tevent_req_notify_callback(req, __location__) 1086 #endif 1087 1088 #ifdef DOXYGEN 1089 /** 1090 * @brief An async request has successfully finished. 1091 * 1092 * This function is to be used by implementors of async requests. When a 1093 * request is successfully finished, this function calls the user's completion 1094 * function. 1095 * 1096 * @param[in] req The finished request. 1097 */ 1098 void tevent_req_done(struct tevent_req *req); 1099 #else 1100 void _tevent_req_done(struct tevent_req *req, 1101 const char *location); 1102 #define tevent_req_done(req) \ 1103 _tevent_req_done(req, __location__) 1104 #endif 1105 1106 #ifdef DOXYGEN 1107 /** 1108 * @brief An async request has seen an error. 1109 * 1110 * This function is to be used by implementors of async requests. When a 1111 * request can not successfully completed, the implementation should call this 1112 * function with the appropriate status code. 1113 * 1114 * If error is 0 the function returns false and does nothing more. 1115 * 1116 * @param[in] req The request with an error. 1117 * 1118 * @param[in] error The error code. 1119 * 1120 * @return On success true is returned, false if error is 0. 1121 * 1122 * @code 1123 * int error = first_function(); 1124 * if (tevent_req_error(req, error)) { 1125 * return; 1126 * } 1127 * 1128 * error = second_function(); 1129 * if (tevent_req_error(req, error)) { 1130 * return; 1131 * } 1132 * 1133 * tevent_req_done(req); 1134 * return; 1135 * @endcode 1136 */ 1137 bool tevent_req_error(struct tevent_req *req, 1138 uint64_t error); 1139 #else 1140 bool _tevent_req_error(struct tevent_req *req, 1141 uint64_t error, 1142 const char *location); 1143 #define tevent_req_error(req, error) \ 1144 _tevent_req_error(req, error, __location__) 1145 #endif 1146 1147 #ifdef DOXYGEN 1148 /** 1149 * @brief Helper function for nomem check. 1150 * 1151 * Convenience helper to easily check alloc failure within a callback 1152 * implementing the next step of an async request. 1153 * 1154 * @param[in] p The pointer to be checked. 1155 * 1156 * @param[in] req The request being processed. 1157 * 1158 * @code 1159 * p = talloc(mem_ctx, bla); 1160 * if (tevent_req_nomem(p, req)) { 1161 * return; 1162 * } 1163 * @endcode 1164 */ 1165 bool tevent_req_nomem(const void *p, 1166 struct tevent_req *req); 1167 #else 1168 bool _tevent_req_nomem(const void *p, 1169 struct tevent_req *req, 1170 const char *location); 1171 #define tevent_req_nomem(p, req) \ 1172 _tevent_req_nomem(p, req, __location__) 1173 #endif 1174 1175 #ifdef DOXYGEN 1176 /** 1177 * @brief Indicate out of memory to a request 1178 * 1179 * @param[in] req The request being processed. 1180 */ 1181 void tevent_req_oom(struct tevent_req *req); 1182 #else 1183 void _tevent_req_oom(struct tevent_req *req, 1184 const char *location); 1185 #define tevent_req_oom(req) \ 1186 _tevent_req_oom(req, __location__) 1187 #endif 1188 1189 /** 1190 * @brief Finish a request before the caller had a chance to set the callback. 1191 * 1192 * An implementation of an async request might find that it can either finish 1193 * the request without waiting for an external event, or it can not even start 1194 * the engine. To present the illusion of a callback to the user of the API, 1195 * the implementation can call this helper function which triggers an 1196 * immediate event. This way the caller can use the same calling 1197 * conventions, independent of whether the request was actually deferred. 1198 * 1199 * @code 1200 * struct tevent_req *computation_send(TALLOC_CTX *mem_ctx, 1201 * struct tevent_context *ev) 1202 * { 1203 * struct tevent_req *req, *subreq; 1204 * struct computation_state *state; 1205 * req = tevent_req_create(mem_ctx, &state, struct computation_state); 1206 * if (req == NULL) { 1207 * return NULL; 1208 * } 1209 * subreq = subcomputation_send(state, ev); 1210 * if (tevent_req_nomem(subreq, req)) { 1211 * return tevent_req_post(req, ev); 1212 * } 1213 * tevent_req_set_callback(subreq, computation_done, req); 1214 * return req; 1215 * } 1216 * @endcode 1217 * 1218 * @param[in] req The finished request. 1219 * 1220 * @param[in] ev The tevent_context for the immediate event. 1221 * 1222 * @return The given request will be returned. 1223 */ 1224 struct tevent_req *tevent_req_post(struct tevent_req *req, 1225 struct tevent_context *ev); 1226 1227 /** 1228 * @brief Finish multiple requests within one function 1229 * 1230 * Normally tevent_req_notify_callback() and all wrappers 1231 * (e.g. tevent_req_done() and tevent_req_error()) 1232 * need to be the last thing an event handler should call. 1233 * This is because the callback is likely to destroy the 1234 * context of the current function. 1235 * 1236 * If a function wants to notify more than one caller, 1237 * it is dangerous if it just triggers multiple callbacks 1238 * in a row. With tevent_req_defer_callback() it is possible 1239 * to set an event context that will be used to defer the callback 1240 * via an immediate event (similar to tevent_req_post()). 1241 * 1242 * @code 1243 * struct complete_state { 1244 * struct tevent_context *ev; 1245 * 1246 * struct tevent_req **reqs; 1247 * }; 1248 * 1249 * void complete(struct complete_state *state) 1250 * { 1251 * size_t i, c = talloc_array_length(state->reqs); 1252 * 1253 * for (i=0; i < c; i++) { 1254 * tevent_req_defer_callback(state->reqs[i], state->ev); 1255 * tevent_req_done(state->reqs[i]); 1256 * } 1257 * } 1258 * @endcode 1259 * 1260 * @param[in] req The finished request. 1261 * 1262 * @param[in] ev The tevent_context for the immediate event. 1263 * 1264 * @return The given request will be returned. 1265 */ 1266 void tevent_req_defer_callback(struct tevent_req *req, 1267 struct tevent_context *ev); 1268 1269 /** 1270 * @brief Check if the given request is still in progress. 1271 * 1272 * It is typically used by sync wrapper functions. 1273 * 1274 * @param[in] req The request to poll. 1275 * 1276 * @return The boolean form of "is in progress". 1277 */ 1278 bool tevent_req_is_in_progress(struct tevent_req *req); 1279 1280 /** 1281 * @brief Actively poll for the given request to finish. 1282 * 1283 * This function is typically used by sync wrapper functions. 1284 * 1285 * @param[in] req The request to poll. 1286 * 1287 * @param[in] ev The tevent_context to be used. 1288 * 1289 * @return On success true is returned. If a critical error has 1290 * happened in the tevent loop layer false is returned. 1291 * This is not the return value of the given request! 1292 * 1293 * @note This should only be used if the given tevent context was created by the 1294 * caller, to avoid event loop nesting. 1295 * 1296 * @code 1297 * req = tstream_writev_queue_send(mem_ctx, 1298 * ev_ctx, 1299 * tstream, 1300 * send_queue, 1301 * iov, 2); 1302 * ok = tevent_req_poll(req, tctx->ev); 1303 * rc = tstream_writev_queue_recv(req, &sys_errno); 1304 * TALLOC_FREE(req); 1305 * @endcode 1306 */ 1307 bool tevent_req_poll(struct tevent_req *req, 1308 struct tevent_context *ev); 1309 1310 /** 1311 * @brief Get the tevent request state and the actual error set by 1312 * tevent_req_error. 1313 * 1314 * @code 1315 * int computation_recv(struct tevent_req *req, uint64_t *perr) 1316 * { 1317 * enum tevent_req_state state; 1318 * uint64_t err; 1319 * if (tevent_req_is_error(req, &state, &err)) { 1320 * *perr = err; 1321 * return -1; 1322 * } 1323 * return 0; 1324 * } 1325 * @endcode 1326 * 1327 * @param[in] req The tevent request to get the error from. 1328 * 1329 * @param[out] state A pointer to store the tevent request error state. 1330 * 1331 * @param[out] error A pointer to store the error set by tevent_req_error(). 1332 * 1333 * @return True if the function could set error and state, false 1334 * otherwise. 1335 * 1336 * @see tevent_req_error() 1337 */ 1338 bool tevent_req_is_error(struct tevent_req *req, 1339 enum tevent_req_state *state, 1340 uint64_t *error); 1341 1342 /** 1343 * @brief Use as the last action of a _recv() function. 1344 * 1345 * This function destroys the attached private data. 1346 * 1347 * @param[in] req The finished request. 1348 */ 1349 void tevent_req_received(struct tevent_req *req); 1350 1351 /** 1352 * @brief Mark a tevent_req for profiling 1353 * 1354 * This will turn on profiling for this tevent_req an all subreqs that 1355 * are directly started as helper requests off this 1356 * tevent_req. subreqs are chained by walking up the talloc_parent 1357 * hierarchy at a subreq's tevent_req_create. This means to get the 1358 * profiling chain right the subreq that needs to be profiled as part 1359 * of this tevent_req's profile must be a talloc child of the requests 1360 * state variable. 1361 * 1362 * @param[in] req The request to do tracing for 1363 * 1364 * @return False if the profile could not be activated 1365 */ 1366 bool tevent_req_set_profile(struct tevent_req *req); 1367 1368 struct tevent_req_profile; 1369 1370 /** 1371 * @brief Get the a request's profile for inspection 1372 * 1373 * @param[in] req The request to get the profile from 1374 * 1375 * @return The request's profile 1376 */ 1377 const struct tevent_req_profile *tevent_req_get_profile( 1378 struct tevent_req *req); 1379 1380 /** 1381 * @brief Move the profile out of a request 1382 * 1383 * This function detaches the request's profile from the request, so 1384 * that the profile can outlive the request in a _recv function. 1385 * 1386 * @param[in] req The request to move the profile out of 1387 * @param[in] mem_ctx The new talloc context for the profile 1388 * 1389 * @return The moved profile 1390 */ 1391 1392 struct tevent_req_profile *tevent_req_move_profile(struct tevent_req *req, 1393 TALLOC_CTX *mem_ctx); 1394 1395 /** 1396 * @brief Get a profile description 1397 * 1398 * @param[in] profile The profile to be queried 1399 * @param[in] req_name The name of the request (state's name) 1400 * 1401 * "req_name" after this call is still in talloc-posession of "profile" 1402 */ 1403 void tevent_req_profile_get_name(const struct tevent_req_profile *profile, 1404 const char **req_name); 1405 1406 /** 1407 * @brief Get a profile's start event data 1408 * 1409 * @param[in] profile The profile to be queried 1410 * @param[in] start_location The location where this event started 1411 * @param[in] start_time The time this event started 1412 * 1413 * "start_location" after this call is still in talloc-posession of "profile" 1414 */ 1415 void tevent_req_profile_get_start(const struct tevent_req_profile *profile, 1416 const char **start_location, 1417 struct timeval *start_time); 1418 1419 /** 1420 * @brief Get a profile's stop event data 1421 * 1422 * @param[in] profile The profile to be queried 1423 * @param[in] stop_location The location where this event stopped 1424 * @param[in] stop_time The time this event stopped 1425 * 1426 * "stop_location" after this call is still in talloc-posession of "profile" 1427 */ 1428 void tevent_req_profile_get_stop(const struct tevent_req_profile *profile, 1429 const char **stop_location, 1430 struct timeval *stop_time); 1431 1432 /** 1433 * @brief Get a profile's result data 1434 * 1435 * @param[in] pid The process where this profile was taken 1436 * @param[in] state The status the profile's tevent_req finished with 1437 * @param[in] user_error The user error of the profile's tevent_req 1438 */ 1439 void tevent_req_profile_get_status(const struct tevent_req_profile *profile, 1440 pid_t *pid, 1441 enum tevent_req_state *state, 1442 uint64_t *user_error); 1443 1444 /** 1445 * @brief Retrieve the first subreq's profile from a profile 1446 * 1447 * @param[in] profile The profile to query 1448 * 1449 * @return The first tevent subreq's profile 1450 */ 1451 const struct tevent_req_profile *tevent_req_profile_get_subprofiles( 1452 const struct tevent_req_profile *profile); 1453 1454 /** 1455 * @brief Walk the chain of subreqs 1456 * 1457 * @param[in] profile The subreq's profile to walk 1458 * 1459 * @return The next subprofile in the list 1460 */ 1461 const struct tevent_req_profile *tevent_req_profile_next( 1462 const struct tevent_req_profile *profile); 1463 1464 /** 1465 * @brief Create a fresh tevent_req_profile 1466 * 1467 * @param[in] mem_ctx The talloc context to hang the fresh struct off 1468 * 1469 * @return The fresh struct 1470 */ 1471 struct tevent_req_profile *tevent_req_profile_create(TALLOC_CTX *mem_ctx); 1472 1473 /** 1474 * @brief Set a profile's name 1475 * 1476 * @param[in] profile The profile to set the name for 1477 * @param[in] name The new name for the profile 1478 * 1479 * @return True if the internal talloc_strdup succeeded 1480 */ 1481 bool tevent_req_profile_set_name(struct tevent_req_profile *profile, 1482 const char *name); 1483 1484 /** 1485 * @brief Set a profile's start event 1486 * 1487 * @param[in] profile The profile to set the start data for 1488 * @param[in] start_location The new start location 1489 * @param[in] start_time The new start time 1490 * 1491 * @return True if the internal talloc_strdup succeeded 1492 */ 1493 bool tevent_req_profile_set_start(struct tevent_req_profile *profile, 1494 const char *start_location, 1495 struct timeval start_time); 1496 1497 /** 1498 * @brief Set a profile's stop event 1499 * 1500 * @param[in] profile The profile to set the stop data for 1501 * @param[in] stop_location The new stop location 1502 * @param[in] stop_time The new stop time 1503 * 1504 * @return True if the internal talloc_strdup succeeded 1505 */ 1506 bool tevent_req_profile_set_stop(struct tevent_req_profile *profile, 1507 const char *stop_location, 1508 struct timeval stop_time); 1509 1510 /** 1511 * @brief Set a profile's exit status 1512 * 1513 * @param[in] profile The profile to set the exit status for 1514 * @param[in] pid The process where this profile was taken 1515 * @param[in] state The status the profile's tevent_req finished with 1516 * @param[in] user_error The user error of the profile's tevent_req 1517 */ 1518 void tevent_req_profile_set_status(struct tevent_req_profile *profile, 1519 pid_t pid, 1520 enum tevent_req_state state, 1521 uint64_t user_error); 1522 1523 /** 1524 * @brief Add a subprofile to a profile 1525 * 1526 * @param[in] parent_profile The profile to be modified 1527 * @param[in] sub_profile The subreqs profile profile to be added 1528 * 1529 * "subreq" is talloc_move'ed into "parent_profile", so the talloc 1530 * ownership of "sub_profile" changes 1531 */ 1532 1533 void tevent_req_profile_append_sub(struct tevent_req_profile *parent_profile, 1534 struct tevent_req_profile **sub_profile); 1535 1536 /** 1537 * @brief Create a tevent subrequest at a given time. 1538 * 1539 * The idea is that always the same syntax for tevent requests. 1540 * 1541 * @param[in] mem_ctx The talloc memory context to use. 1542 * 1543 * @param[in] ev The event handle to setup the request. 1544 * 1545 * @param[in] wakeup_time The time to wakeup and execute the request. 1546 * 1547 * @return The new subrequest, NULL on error. 1548 * 1549 * Example: 1550 * @code 1551 * static void my_callback_wakeup_done(tevent_req *subreq) 1552 * { 1553 * struct tevent_req *req = tevent_req_callback_data(subreq, 1554 * struct tevent_req); 1555 * bool ok; 1556 * 1557 * ok = tevent_wakeup_recv(subreq); 1558 * TALLOC_FREE(subreq); 1559 * if (!ok) { 1560 * tevent_req_error(req, -1); 1561 * return; 1562 * } 1563 * ... 1564 * } 1565 * @endcode 1566 * 1567 * @code 1568 * subreq = tevent_wakeup_send(mem_ctx, ev, wakeup_time); 1569 * if (tevent_req_nomem(subreq, req)) { 1570 * return false; 1571 * } 1572 * tevent_set_callback(subreq, my_callback_wakeup_done, req); 1573 * @endcode 1574 * 1575 * @see tevent_wakeup_recv() 1576 */ 1577 struct tevent_req *tevent_wakeup_send(TALLOC_CTX *mem_ctx, 1578 struct tevent_context *ev, 1579 struct timeval wakeup_time); 1580 1581 /** 1582 * @brief Check if the wakeup has been correctly executed. 1583 * 1584 * This function needs to be called in the callback function set after calling 1585 * tevent_wakeup_send(). 1586 * 1587 * @param[in] req The tevent request to check. 1588 * 1589 * @return True on success, false otherwise. 1590 * 1591 * @see tevent_wakeup_recv() 1592 */ 1593 bool tevent_wakeup_recv(struct tevent_req *req); 1594 1595 /* @} */ 1596 1597 /** 1598 * @defgroup tevent_helpers The tevent helper functions 1599 * @ingroup tevent 1600 * 1601 * @todo description 1602 * 1603 * @{ 1604 */ 1605 1606 /** 1607 * @brief Compare two timeval values. 1608 * 1609 * @param[in] tv1 The first timeval value to compare. 1610 * 1611 * @param[in] tv2 The second timeval value to compare. 1612 * 1613 * @return 0 if they are equal. 1614 * 1 if the first time is greater than the second. 1615 * -1 if the first time is smaller than the second. 1616 */ 1617 int tevent_timeval_compare(const struct timeval *tv1, 1618 const struct timeval *tv2); 1619 1620 /** 1621 * @brief Get a zero timeval value. 1622 * 1623 * @return A zero timeval value. 1624 */ 1625 struct timeval tevent_timeval_zero(void); 1626 1627 /** 1628 * @brief Get a timeval value for the current time. 1629 * 1630 * @return A timeval value with the current time. 1631 */ 1632 struct timeval tevent_timeval_current(void); 1633 1634 /** 1635 * @brief Get a timeval structure with the given values. 1636 * 1637 * @param[in] secs The seconds to set. 1638 * 1639 * @param[in] usecs The microseconds to set. 1640 * 1641 * @return A timeval structure with the given values. 1642 */ 1643 struct timeval tevent_timeval_set(uint32_t secs, uint32_t usecs); 1644 1645 /** 1646 * @brief Get the difference between two timeval values. 1647 * 1648 * @param[in] tv1 The first timeval. 1649 * 1650 * @param[in] tv2 The second timeval. 1651 * 1652 * @return A timeval structure with the difference between the 1653 * first and the second value. 1654 */ 1655 struct timeval tevent_timeval_until(const struct timeval *tv1, 1656 const struct timeval *tv2); 1657 1658 /** 1659 * @brief Check if a given timeval structure is zero. 1660 * 1661 * @param[in] tv The timeval to check if it is zero. 1662 * 1663 * @return True if it is zero, false otherwise. 1664 */ 1665 bool tevent_timeval_is_zero(const struct timeval *tv); 1666 1667 /** 1668 * @brief Add the given amount of time to a timeval structure. 1669 * 1670 * @param[in] tv The timeval structure to add the time. 1671 * 1672 * @param[in] secs The seconds to add to the timeval. 1673 * 1674 * @param[in] usecs The microseconds to add to the timeval. 1675 * 1676 * @return The timeval structure with the new time. 1677 */ 1678 struct timeval tevent_timeval_add(const struct timeval *tv, uint32_t secs, 1679 uint32_t usecs); 1680 1681 /** 1682 * @brief Get a timeval in the future with a specified offset from now. 1683 * 1684 * @param[in] secs The seconds of the offset from now. 1685 * 1686 * @param[in] usecs The microseconds of the offset from now. 1687 * 1688 * @return A timeval with the given offset in the future. 1689 */ 1690 struct timeval tevent_timeval_current_ofs(uint32_t secs, uint32_t usecs); 1691 1692 /* @} */ 1693 1694 1695 /** 1696 * @defgroup tevent_queue The tevent queue functions 1697 * @ingroup tevent 1698 * 1699 * A tevent_queue is used to queue up async requests that must be 1700 * serialized. For example writing buffers into a socket must be 1701 * serialized. Writing a large lump of data into a socket can require 1702 * multiple write(2) or send(2) system calls. If more than one async 1703 * request is outstanding to write large buffers into a socket, every 1704 * request must individually be completed before the next one begins, 1705 * even if multiple syscalls are required. 1706 * 1707 * Take a look at @ref tevent_queue_tutorial for more details. 1708 * @{ 1709 */ 1710 1711 struct tevent_queue; 1712 struct tevent_queue_entry; 1713 1714 #ifdef DOXYGEN 1715 /** 1716 * @brief Create and start a tevent queue. 1717 * 1718 * @param[in] mem_ctx The talloc memory context to allocate the queue. 1719 * 1720 * @param[in] name The name to use to identify the queue. 1721 * 1722 * @return An allocated tevent queue on success, NULL on error. 1723 * 1724 * @see tevent_queue_start() 1725 * @see tevent_queue_stop() 1726 */ 1727 struct tevent_queue *tevent_queue_create(TALLOC_CTX *mem_ctx, 1728 const char *name); 1729 #else 1730 struct tevent_queue *_tevent_queue_create(TALLOC_CTX *mem_ctx, 1731 const char *name, 1732 const char *location); 1733 1734 #define tevent_queue_create(_mem_ctx, _name) \ 1735 _tevent_queue_create((_mem_ctx), (_name), __location__) 1736 #endif 1737 1738 /** 1739 * @brief A callback trigger function run by the queue. 1740 * 1741 * @param[in] req The tevent request the trigger function is executed on. 1742 * 1743 * @param[in] private_data The private data pointer specified by 1744 * tevent_queue_add(). 1745 * 1746 * @see tevent_queue_add() 1747 * @see tevent_queue_add_entry() 1748 * @see tevent_queue_add_optimize_empty() 1749 */ 1750 typedef void (*tevent_queue_trigger_fn_t)(struct tevent_req *req, 1751 void *private_data); 1752 1753 /** 1754 * @brief Add a tevent request to the queue. 1755 * 1756 * @param[in] queue The queue to add the request. 1757 * 1758 * @param[in] ev The event handle to use for the request. 1759 * 1760 * @param[in] req The tevent request to add to the queue. 1761 * 1762 * @param[in] trigger The function triggered by the queue when the request 1763 * is called. Since tevent 0.9.14 it's possible to 1764 * pass NULL, in order to just add a "blocker" to the 1765 * queue. 1766 * 1767 * @param[in] private_data The private data passed to the trigger function. 1768 * 1769 * @return True if the request has been successfully added, false 1770 * otherwise. 1771 */ 1772 bool tevent_queue_add(struct tevent_queue *queue, 1773 struct tevent_context *ev, 1774 struct tevent_req *req, 1775 tevent_queue_trigger_fn_t trigger, 1776 void *private_data); 1777 1778 /** 1779 * @brief Add a tevent request to the queue. 1780 * 1781 * The request can be removed from the queue by calling talloc_free() 1782 * (or a similar function) on the returned queue entry. This 1783 * is the only difference to tevent_queue_add(). 1784 * 1785 * @param[in] queue The queue to add the request. 1786 * 1787 * @param[in] ev The event handle to use for the request. 1788 * 1789 * @param[in] req The tevent request to add to the queue. 1790 * 1791 * @param[in] trigger The function triggered by the queue when the request 1792 * is called. Since tevent 0.9.14 it's possible to 1793 * pass NULL, in order to just add a "blocker" to the 1794 * queue. 1795 * 1796 * @param[in] private_data The private data passed to the trigger function. 1797 * 1798 * @return a pointer to the tevent_queue_entry if the request 1799 * has been successfully added, NULL otherwise. 1800 * 1801 * @see tevent_queue_add() 1802 * @see tevent_queue_add_optimize_empty() 1803 */ 1804 struct tevent_queue_entry *tevent_queue_add_entry( 1805 struct tevent_queue *queue, 1806 struct tevent_context *ev, 1807 struct tevent_req *req, 1808 tevent_queue_trigger_fn_t trigger, 1809 void *private_data); 1810 1811 /** 1812 * @brief Add a tevent request to the queue using a possible optimization. 1813 * 1814 * This tries to optimize for the empty queue case and may calls 1815 * the trigger function directly. This is the only difference compared 1816 * to tevent_queue_add_entry(). 1817 * 1818 * The caller needs to be prepared that the trigger function has 1819 * already called tevent_req_notify_callback(), tevent_req_error(), 1820 * tevent_req_done() or a similar function. 1821 * 1822 * The trigger function has no chance to see the returned 1823 * queue_entry in the optimized case. 1824 * 1825 * The request can be removed from the queue by calling talloc_free() 1826 * (or a similar function) on the returned queue entry. 1827 * 1828 * @param[in] queue The queue to add the request. 1829 * 1830 * @param[in] ev The event handle to use for the request. 1831 * 1832 * @param[in] req The tevent request to add to the queue. 1833 * 1834 * @param[in] trigger The function triggered by the queue when the request 1835 * is called. Since tevent 0.9.14 it's possible to 1836 * pass NULL, in order to just add a "blocker" to the 1837 * queue. 1838 * 1839 * @param[in] private_data The private data passed to the trigger function. 1840 * 1841 * @return a pointer to the tevent_queue_entry if the request 1842 * has been successfully added, NULL otherwise. 1843 * 1844 * @see tevent_queue_add() 1845 * @see tevent_queue_add_entry() 1846 */ 1847 struct tevent_queue_entry *tevent_queue_add_optimize_empty( 1848 struct tevent_queue *queue, 1849 struct tevent_context *ev, 1850 struct tevent_req *req, 1851 tevent_queue_trigger_fn_t trigger, 1852 void *private_data); 1853 1854 /** 1855 * @brief Untrigger an already triggered queue entry. 1856 * 1857 * If a trigger function detects that it needs to remain 1858 * in the queue, it needs to call tevent_queue_stop() 1859 * followed by tevent_queue_entry_untrigger(). 1860 * 1861 * @note In order to call tevent_queue_entry_untrigger() 1862 * the queue must be already stopped and the given queue_entry 1863 * must be the first one in the queue! Otherwise it calls abort(). 1864 * 1865 * @note You can't use this together with tevent_queue_add_optimize_empty() 1866 * because the trigger function don't have access to the quene entry 1867 * in the case of an empty queue. 1868 * 1869 * @param[in] queue_entry The queue entry to rearm. 1870 * 1871 * @see tevent_queue_add_entry() 1872 * @see tevent_queue_stop() 1873 */ 1874 void tevent_queue_entry_untrigger(struct tevent_queue_entry *entry); 1875 1876 /** 1877 * @brief Start a tevent queue. 1878 * 1879 * The queue is started by default. 1880 * 1881 * @param[in] queue The queue to start. 1882 */ 1883 void tevent_queue_start(struct tevent_queue *queue); 1884 1885 /** 1886 * @brief Stop a tevent queue. 1887 * 1888 * The queue is started by default. 1889 * 1890 * @param[in] queue The queue to stop. 1891 */ 1892 void tevent_queue_stop(struct tevent_queue *queue); 1893 1894 /** 1895 * @brief Get the length of the queue. 1896 * 1897 * @param[in] queue The queue to get the length from. 1898 * 1899 * @return The number of elements. 1900 */ 1901 size_t tevent_queue_length(struct tevent_queue *queue); 1902 1903 /** 1904 * @brief Is the tevent queue running. 1905 * 1906 * The queue is started by default. 1907 * 1908 * @param[in] queue The queue. 1909 * 1910 * @return Whether the queue is running or not.. 1911 */ 1912 bool tevent_queue_running(struct tevent_queue *queue); 1913 1914 /** 1915 * @brief Create a tevent subrequest that waits in a tevent_queue 1916 * 1917 * The idea is that always the same syntax for tevent requests. 1918 * 1919 * @param[in] mem_ctx The talloc memory context to use. 1920 * 1921 * @param[in] ev The event handle to setup the request. 1922 * 1923 * @param[in] queue The queue to wait in. 1924 * 1925 * @return The new subrequest, NULL on error. 1926 * 1927 * @see tevent_queue_wait_recv() 1928 */ 1929 struct tevent_req *tevent_queue_wait_send(TALLOC_CTX *mem_ctx, 1930 struct tevent_context *ev, 1931 struct tevent_queue *queue); 1932 1933 /** 1934 * @brief Check if we no longer need to wait in the queue. 1935 * 1936 * This function needs to be called in the callback function set after calling 1937 * tevent_queue_wait_send(). 1938 * 1939 * @param[in] req The tevent request to check. 1940 * 1941 * @return True on success, false otherwise. 1942 * 1943 * @see tevent_queue_wait_send() 1944 */ 1945 bool tevent_queue_wait_recv(struct tevent_req *req); 1946 1947 typedef int (*tevent_nesting_hook)(struct tevent_context *ev, 1948 void *private_data, 1949 uint32_t level, 1950 bool begin, 1951 void *stack_ptr, 1952 const char *location); 1953 1954 /** 1955 * @brief Create a tevent_thread_proxy for message passing between threads. 1956 * 1957 * The tevent_context must have been allocated on the NULL 1958 * talloc context, and talloc_disable_null_tracking() must 1959 * have been called. 1960 * 1961 * @param[in] dest_ev_ctx The tevent_context to receive events. 1962 * 1963 * @return An allocated tevent_thread_proxy, NULL on error. 1964 * If tevent was compiled without PTHREAD support 1965 * NULL is always returned and errno set to ENOSYS. 1966 * 1967 * @see tevent_thread_proxy_schedule() 1968 */ 1969 struct tevent_thread_proxy *tevent_thread_proxy_create( 1970 struct tevent_context *dest_ev_ctx); 1971 1972 /** 1973 * @brief Schedule an immediate event on an event context from another thread. 1974 * 1975 * Causes dest_ev_ctx, being run by another thread, to receive an 1976 * immediate event calling the handler with the *pp_private parameter. 1977 * 1978 * *pp_im must be a pointer to an immediate event talloced on a context owned 1979 * by the calling thread, or the NULL context. Ownership will 1980 * be transferred to the tevent_thread_proxy and *pp_im will be returned as NULL. 1981 * 1982 * *pp_private_data must be a talloced area of memory with no destructors. 1983 * Ownership of this memory will be transferred to the tevent library and 1984 * *pp_private_data will be set to NULL on successful completion of 1985 * the call. Set pp_private to NULL if no parameter transfer 1986 * needed (a pure callback). This is an asynchronous request, caller 1987 * does not wait for callback to be completed before returning. 1988 * 1989 * @param[in] tp The tevent_thread_proxy to use. 1990 * 1991 * @param[in] pp_im Pointer to immediate event pointer. 1992 * 1993 * @param[in] handler The function that will be called. 1994 * 1995 * @param[in] pp_private_data The talloced memory to transfer. 1996 * 1997 * @see tevent_thread_proxy_create() 1998 */ 1999 void tevent_thread_proxy_schedule(struct tevent_thread_proxy *tp, 2000 struct tevent_immediate **pp_im, 2001 tevent_immediate_handler_t handler, 2002 void *pp_private_data); 2003 2004 /* 2005 * @brief Create a context for threaded activation of immediates 2006 * 2007 * A tevent_treaded_context provides a link into an event 2008 * context. Using tevent_threaded_schedule_immediate, it is possible 2009 * to activate an immediate event from within a thread. 2010 * 2011 * It is the duty of the caller of tevent_threaded_context_create() to 2012 * keep the event context around longer than any 2013 * tevent_threaded_context. tevent will abort if ev is talloc_free'ed 2014 * with an active tevent_threaded_context. 2015 * 2016 * If tevent is build without pthread support, this always returns 2017 * NULL with errno=ENOSYS. 2018 * 2019 * @param[in] mem_ctx The talloc memory context to use. 2020 * @param[in] ev The event context to link this to. 2021 * @return The threaded context, or NULL with errno set. 2022 * 2023 * @see tevent_threaded_schedule_immediate() 2024 * 2025 * @note Available as of tevent 0.9.30 2026 */ 2027 struct tevent_threaded_context *tevent_threaded_context_create( 2028 TALLOC_CTX *mem_ctx, struct tevent_context *ev); 2029 2030 #ifdef DOXYGEN 2031 /* 2032 * @brief Activate an immediate from a thread 2033 * 2034 * Activate an immediate from within a thread. 2035 * 2036 * This routine does not watch out for talloc hierarchies. This means 2037 * that it is highly recommended to create the tevent_immediate in the 2038 * thread owning tctx, allocate a threaded job description for the 2039 * thread, hand over both pointers to a helper thread and not touch it 2040 * in the main thread at all anymore. 2041 * 2042 * tevent_threaded_schedule_immediate is intended as a job completion 2043 * indicator for simple threaded helpers. 2044 * 2045 * Please be aware that tevent_threaded_schedule_immediate is very 2046 * picky about its arguments: An immediate may not already be 2047 * activated and the handler must exist. With 2048 * tevent_threaded_schedule_immediate memory ownership is transferred 2049 * to the main thread holding the tevent context behind tctx, the 2050 * helper thread can't access it anymore. 2051 * 2052 * @param[in] tctx The threaded context to go through 2053 * @param[in] im The immediate event to activate 2054 * @param[in] handler The immediate handler to call in the main thread 2055 * @param[in] private_data Pointer for the immediate handler 2056 * 2057 * @see tevent_threaded_context_create() 2058 * 2059 * @note Available as of tevent 0.9.30 2060 */ 2061 void tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx, 2062 struct tevent_immediate *im, 2063 tevent_immediate_handler_t handler, 2064 void *private_data); 2065 #else 2066 void _tevent_threaded_schedule_immediate(struct tevent_threaded_context *tctx, 2067 struct tevent_immediate *im, 2068 tevent_immediate_handler_t handler, 2069 void *private_data, 2070 const char *handler_name, 2071 const char *location); 2072 #define tevent_threaded_schedule_immediate(tctx, im, handler, private_data) \ 2073 _tevent_threaded_schedule_immediate(tctx, im, handler, private_data, \ 2074 #handler, __location__); 2075 #endif 2076 2077 #ifdef TEVENT_DEPRECATED 2078 #ifndef _DEPRECATED_ 2079 #ifdef HAVE___ATTRIBUTE__ 2080 #define _DEPRECATED_ __attribute__ ((deprecated)) 2081 #else 2082 #define _DEPRECATED_ 2083 #endif 2084 #endif 2085 void tevent_loop_allow_nesting(struct tevent_context *ev) _DEPRECATED_; 2086 void tevent_loop_set_nesting_hook(struct tevent_context *ev, 2087 tevent_nesting_hook hook, 2088 void *private_data) _DEPRECATED_; 2089 int _tevent_loop_until(struct tevent_context *ev, 2090 bool (*finished)(void *private_data), 2091 void *private_data, 2092 const char *location) _DEPRECATED_; 2093 #define tevent_loop_until(ev, finished, private_data) \ 2094 _tevent_loop_until(ev, finished, private_data, __location__) 2095 #endif 2096 2097 int tevent_re_initialise(struct tevent_context *ev); 2098 2099 /* @} */ 2100 2101 /** 2102 * @defgroup tevent_ops The tevent operation functions 2103 * @ingroup tevent 2104 * 2105 * The following structure and registration functions are exclusively 2106 * needed for people writing and pluggin a different event engine. 2107 * There is nothing useful for normal tevent user in here. 2108 * @{ 2109 */ 2110 2111 struct tevent_ops { 2112 /* context init */ 2113 int (*context_init)(struct tevent_context *ev); 2114 2115 /* fd_event functions */ 2116 struct tevent_fd *(*add_fd)(struct tevent_context *ev, 2117 TALLOC_CTX *mem_ctx, 2118 int fd, uint16_t flags, 2119 tevent_fd_handler_t handler, 2120 void *private_data, 2121 const char *handler_name, 2122 const char *location); 2123 void (*set_fd_close_fn)(struct tevent_fd *fde, 2124 tevent_fd_close_fn_t close_fn); 2125 uint16_t (*get_fd_flags)(struct tevent_fd *fde); 2126 void (*set_fd_flags)(struct tevent_fd *fde, uint16_t flags); 2127 2128 /* timed_event functions */ 2129 struct tevent_timer *(*add_timer)(struct tevent_context *ev, 2130 TALLOC_CTX *mem_ctx, 2131 struct timeval next_event, 2132 tevent_timer_handler_t handler, 2133 void *private_data, 2134 const char *handler_name, 2135 const char *location); 2136 2137 /* immediate event functions */ 2138 void (*schedule_immediate)(struct tevent_immediate *im, 2139 struct tevent_context *ev, 2140 tevent_immediate_handler_t handler, 2141 void *private_data, 2142 const char *handler_name, 2143 const char *location); 2144 2145 /* signal functions */ 2146 struct tevent_signal *(*add_signal)(struct tevent_context *ev, 2147 TALLOC_CTX *mem_ctx, 2148 int signum, int sa_flags, 2149 tevent_signal_handler_t handler, 2150 void *private_data, 2151 const char *handler_name, 2152 const char *location); 2153 2154 /* loop functions */ 2155 int (*loop_once)(struct tevent_context *ev, const char *location); 2156 int (*loop_wait)(struct tevent_context *ev, const char *location); 2157 }; 2158 2159 bool tevent_register_backend(const char *name, const struct tevent_ops *ops); 2160 2161 /* @} */ 2162 2163 #ifdef TEVENT_DEPRECATED 2164 /** 2165 * @defgroup tevent_wrapper_ops The tevent wrapper operation functions 2166 * @ingroup tevent 2167 * 2168 * The following structure and registration functions are exclusively 2169 * needed for people writing wrapper functions for event handlers 2170 * e.g. wrappers can be used for debugging/profiling or impersonation. 2171 * 2172 * There is nothing useful for normal tevent user in here. 2173 * 2174 * @note That the close_fn() on tevent_fd is *NOT* wrapped! 2175 * 2176 * @see tevent_context_wrapper_create 2177 * @see tevent_fd_set_auto_close 2178 * @{ 2179 */ 2180 2181 struct tevent_wrapper_ops { 2182 const char *name; 2183 2184 bool (*before_use)(struct tevent_context *wrap_ev, 2185 void *private_state, 2186 struct tevent_context *main_ev, 2187 const char *location); 2188 void (*after_use)(struct tevent_context *wrap_ev, 2189 void *private_state, 2190 struct tevent_context *main_ev, 2191 const char *location); 2192 2193 void (*before_fd_handler)(struct tevent_context *wrap_ev, 2194 void *private_state, 2195 struct tevent_context *main_ev, 2196 struct tevent_fd *fde, 2197 uint16_t flags, 2198 const char *handler_name, 2199 const char *location); 2200 void (*after_fd_handler)(struct tevent_context *wrap_ev, 2201 void *private_state, 2202 struct tevent_context *main_ev, 2203 struct tevent_fd *fde, 2204 uint16_t flags, 2205 const char *handler_name, 2206 const char *location); 2207 2208 void (*before_timer_handler)(struct tevent_context *wrap_ev, 2209 void *private_state, 2210 struct tevent_context *main_ev, 2211 struct tevent_timer *te, 2212 struct timeval requested_time, 2213 struct timeval trigger_time, 2214 const char *handler_name, 2215 const char *location); 2216 void (*after_timer_handler)(struct tevent_context *wrap_ev, 2217 void *private_state, 2218 struct tevent_context *main_ev, 2219 struct tevent_timer *te, 2220 struct timeval requested_time, 2221 struct timeval trigger_time, 2222 const char *handler_name, 2223 const char *location); 2224 2225 void (*before_immediate_handler)(struct tevent_context *wrap_ev, 2226 void *private_state, 2227 struct tevent_context *main_ev, 2228 struct tevent_immediate *im, 2229 const char *handler_name, 2230 const char *location); 2231 void (*after_immediate_handler)(struct tevent_context *wrap_ev, 2232 void *private_state, 2233 struct tevent_context *main_ev, 2234 struct tevent_immediate *im, 2235 const char *handler_name, 2236 const char *location); 2237 2238 void (*before_signal_handler)(struct tevent_context *wrap_ev, 2239 void *private_state, 2240 struct tevent_context *main_ev, 2241 struct tevent_signal *se, 2242 int signum, 2243 int count, 2244 void *siginfo, 2245 const char *handler_name, 2246 const char *location); 2247 void (*after_signal_handler)(struct tevent_context *wrap_ev, 2248 void *private_state, 2249 struct tevent_context *main_ev, 2250 struct tevent_signal *se, 2251 int signum, 2252 int count, 2253 void *siginfo, 2254 const char *handler_name, 2255 const char *location); 2256 }; 2257 2258 #ifdef DOXYGEN 2259 /** 2260 * @brief Create a wrapper tevent_context. 2261 * 2262 * @param[in] main_ev The main event context to work on. 2263 * 2264 * @param[in] mem_ctx The talloc memory context to use. 2265 * 2266 * @param[in] ops The tevent_wrapper_ops function table. 2267 * 2268 * @param[out] private_state The private state use by the wrapper functions. 2269 * 2270 * @param[in] private_type The talloc type of the private_state. 2271 * 2272 * @return The wrapper event context, NULL on error. 2273 * 2274 * @note Available as of tevent 0.9.37 2275 * @note Deprecated as of tevent 0.9.38 2276 */ 2277 struct tevent_context *tevent_context_wrapper_create(struct tevent_context *main_ev, 2278 TALLOC_CTX *mem_ctx, 2279 const struct tevent_wrapper_ops *ops, 2280 void **private_state, 2281 const char *private_type); 2282 #else 2283 struct tevent_context *_tevent_context_wrapper_create(struct tevent_context *main_ev, 2284 TALLOC_CTX *mem_ctx, 2285 const struct tevent_wrapper_ops *ops, 2286 void *pstate, 2287 size_t psize, 2288 const char *type, 2289 const char *location) _DEPRECATED_; 2290 #define tevent_context_wrapper_create(main_ev, mem_ctx, ops, state, type) \ 2291 _tevent_context_wrapper_create(main_ev, mem_ctx, ops, \ 2292 state, sizeof(type), #type, __location__) 2293 #endif 2294 2295 /** 2296 * @brief Check if the event context is a wrapper event context. 2297 * 2298 * @param[in] ev The event context to work on. 2299 * 2300 * @return Is a wrapper (true), otherwise (false). 2301 * 2302 * @see tevent_context_wrapper_create() 2303 * 2304 * @note Available as of tevent 0.9.37 2305 * @note Deprecated as of tevent 0.9.38 2306 */ 2307 bool tevent_context_is_wrapper(struct tevent_context *ev) _DEPRECATED_; 2308 2309 #ifdef DOXYGEN 2310 /** 2311 * @brief Prepare the environment of a (wrapper) event context. 2312 * 2313 * A caller might call this before passing a wrapper event context 2314 * to a tevent_req based *_send() function. 2315 * 2316 * The wrapper event context might do something like impersonation. 2317 * 2318 * tevent_context_push_use() must always be used in combination 2319 * with tevent_context_pop_use(). 2320 * 2321 * There is a global stack of currently active/busy wrapper event contexts. 2322 * Each wrapper can only appear once on that global stack! 2323 * The stack size is limited to 32 elements, which should be enough 2324 * for all useful scenarios. 2325 * 2326 * In addition to an explicit tevent_context_push_use() also 2327 * the invocation of an immediate, timer or fd handler implicitly 2328 * pushes the wrapper on the stack. 2329 * 2330 * Therefore there are some strict constraints for the usage of 2331 * tevent_context_push_use(): 2332 * - It must not be called from within an event handler 2333 * that already acts on the wrapper. 2334 * - tevent_context_pop_use() must be called before 2335 * leaving the code block that called tevent_context_push_use(). 2336 * - The caller is responsible ensure the correct stack ordering 2337 * - Any violation of these constraints results in calling 2338 * the abort handler of the given tevent context. 2339 * 2340 * Calling tevent_context_push_use() on a raw event context 2341 * still consumes an element on the stack, but it's otherwise 2342 * a no-op. 2343 * 2344 * If tevent_context_push_use() returns false, it means 2345 * that the wrapper's before_use() hook returned this failure, 2346 * in that case you must not call tevent_context_pop_use() as 2347 * the wrapper is not pushed onto the stack. 2348 * 2349 * @param[in] ev The event context to work on. 2350 * 2351 * @return Success (true) or failure (false). 2352 * 2353 * @note This is only needed if wrapper event contexts are in use. 2354 * 2355 * @see tevent_context_pop_use 2356 * 2357 * @note Available as of tevent 0.9.37 2358 * @note Deprecated as of tevent 0.9.38 2359 */ 2360 bool tevent_context_push_use(struct tevent_context *ev); 2361 #else 2362 bool _tevent_context_push_use(struct tevent_context *ev, 2363 const char *location) _DEPRECATED_; 2364 #define tevent_context_push_use(ev) \ 2365 _tevent_context_push_use(ev, __location__) 2366 #endif 2367 2368 #ifdef DOXYGEN 2369 /** 2370 * @brief Release the environment of a (wrapper) event context. 2371 * 2372 * The wrapper event context might undo something like impersonation. 2373 * 2374 * This must be called after a succesful tevent_context_push_use(). 2375 * Any ordering violation results in calling 2376 * the abort handler of the given tevent context. 2377 * 2378 * This basically calls the wrapper's after_use() hook. 2379 * 2380 * @param[in] ev The event context to work on. 2381 * 2382 * @note This is only needed if wrapper event contexts are in use. 2383 * 2384 * @see tevent_context_push_use 2385 * 2386 * @note Available as of tevent 0.9.37 2387 * @note Deprecated as of tevent 0.9.38 2388 */ 2389 void tevent_context_pop_use(struct tevent_context *ev); 2390 #else 2391 void _tevent_context_pop_use(struct tevent_context *ev, 2392 const char *location) _DEPRECATED_; 2393 #define tevent_context_pop_use(ev) \ 2394 _tevent_context_pop_use(ev, __location__) 2395 #endif 2396 2397 /** 2398 * @brief Check is the two context pointers belong to the same low level loop 2399 * 2400 * With the introduction of wrapper contexts it's not trivial 2401 * to check if two context pointers belong to the same low level 2402 * event loop. Some code may need to know this in order 2403 * to make some caching decisions. 2404 * 2405 * @param[in] ev1 The first event context. 2406 * @param[in] ev2 The second event context. 2407 * 2408 * @return true if both contexts belong to the same (still existing) context 2409 * loop, false otherwise. 2410 * 2411 * @see tevent_context_wrapper_create 2412 * 2413 * @note Available as of tevent 0.9.37 2414 * @note Deprecated as of tevent 0.9.38 2415 */ 2416 bool tevent_context_same_loop(struct tevent_context *ev1, 2417 struct tevent_context *ev2) _DEPRECATED_; 2418 2419 /* @} */ 2420 #endif /* TEVENT_DEPRECATED */ 2421 2422 /** 2423 * @defgroup tevent_compat The tevent compatibility functions 2424 * @ingroup tevent 2425 * 2426 * The following definitions are usueful only for compatibility with the 2427 * implementation originally developed within the samba4 code and will be 2428 * soon removed. Please NEVER use in new code. 2429 * 2430 * @todo Ignore it? 2431 * 2432 * @{ 2433 */ 2434 2435 #ifdef TEVENT_COMPAT_DEFINES 2436 2437 #define event_context tevent_context 2438 #define event_ops tevent_ops 2439 #define fd_event tevent_fd 2440 #define timed_event tevent_timer 2441 #define signal_event tevent_signal 2442 2443 #define event_fd_handler_t tevent_fd_handler_t 2444 #define event_timed_handler_t tevent_timer_handler_t 2445 #define event_signal_handler_t tevent_signal_handler_t 2446 2447 #define event_context_init(mem_ctx) \ 2448 tevent_context_init(mem_ctx) 2449 2450 #define event_context_init_byname(mem_ctx, name) \ 2451 tevent_context_init_byname(mem_ctx, name) 2452 2453 #define event_backend_list(mem_ctx) \ 2454 tevent_backend_list(mem_ctx) 2455 2456 #define event_set_default_backend(backend) \ 2457 tevent_set_default_backend(backend) 2458 2459 #define event_add_fd(ev, mem_ctx, fd, flags, handler, private_data) \ 2460 tevent_add_fd(ev, mem_ctx, fd, flags, handler, private_data) 2461 2462 #define event_add_timed(ev, mem_ctx, next_event, handler, private_data) \ 2463 tevent_add_timer(ev, mem_ctx, next_event, handler, private_data) 2464 2465 #define event_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data) \ 2466 tevent_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data) 2467 2468 #define event_loop_once(ev) \ 2469 tevent_loop_once(ev) 2470 2471 #define event_loop_wait(ev) \ 2472 tevent_loop_wait(ev) 2473 2474 #define event_get_fd_flags(fde) \ 2475 tevent_fd_get_flags(fde) 2476 2477 #define event_set_fd_flags(fde, flags) \ 2478 tevent_fd_set_flags(fde, flags) 2479 2480 #define EVENT_FD_READ TEVENT_FD_READ 2481 #define EVENT_FD_WRITE TEVENT_FD_WRITE 2482 2483 #define EVENT_FD_WRITEABLE(fde) \ 2484 TEVENT_FD_WRITEABLE(fde) 2485 2486 #define EVENT_FD_READABLE(fde) \ 2487 TEVENT_FD_READABLE(fde) 2488 2489 #define EVENT_FD_NOT_WRITEABLE(fde) \ 2490 TEVENT_FD_NOT_WRITEABLE(fde) 2491 2492 #define EVENT_FD_NOT_READABLE(fde) \ 2493 TEVENT_FD_NOT_READABLE(fde) 2494 2495 #define ev_debug_level tevent_debug_level 2496 2497 #define EV_DEBUG_FATAL TEVENT_DEBUG_FATAL 2498 #define EV_DEBUG_ERROR TEVENT_DEBUG_ERROR 2499 #define EV_DEBUG_WARNING TEVENT_DEBUG_WARNING 2500 #define EV_DEBUG_TRACE TEVENT_DEBUG_TRACE 2501 2502 #define ev_set_debug(ev, debug, context) \ 2503 tevent_set_debug(ev, debug, context) 2504 2505 #define ev_set_debug_stderr(_ev) tevent_set_debug_stderr(ev) 2506 2507 #endif /* TEVENT_COMPAT_DEFINES */ 2508 2509 /* @} */ 2510 2511 #endif /* __TEVENT_H__ */ 2512