Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
14 deleted
16 edited
14 copied

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/lib/tevent/libtevent.m4

    r414 r745  
    3131TEVENT_OBJ="$TEVENT_OBJ tevent_req.o tevent_wakeup.o tevent_queue.o"
    3232TEVENT_OBJ="$TEVENT_OBJ tevent_standard.o tevent_select.o"
     33TEVENT_OBJ="$TEVENT_OBJ tevent_poll.o"
    3334
    3435AC_CHECK_HEADERS(sys/epoll.h)
  • trunk/server/lib/tevent/testsuite.c

    r620 r745  
    149149struct torture_suite *torture_local_event(TALLOC_CTX *mem_ctx)
    150150{
    151         struct torture_suite *suite = torture_suite_create(mem_ctx, "EVENT");
     151        struct torture_suite *suite = torture_suite_create(mem_ctx, "event");
    152152        const char **list = event_backend_list(suite);
    153153        int i;
  • trunk/server/lib/tevent/tevent.c

    r429 r745  
    8989        }
    9090
    91         e = talloc(talloc_autofree_context(), struct tevent_ops_list);
     91        e = talloc(NULL, struct tevent_ops_list);
    9292        if (e == NULL) return false;
    9393
     
    105105{
    106106        talloc_free(tevent_default_backend);
    107         tevent_default_backend = talloc_strdup(talloc_autofree_context(),
    108                                                backend);
     107        tevent_default_backend = talloc_strdup(NULL, backend);
    109108}
    110109
     
    115114{
    116115        tevent_select_init();
     116        tevent_poll_init();
    117117        tevent_standard_init();
    118118#ifdef HAVE_EPOLL
     
    263263  add a fd based event
    264264  return NULL on failure (memory allocation error)
    265 
    266   if flags contains TEVENT_FD_AUTOCLOSE then the fd will be closed when
    267   the returned fd_event context is freed
    268265*/
    269266struct tevent_fd *_tevent_add_fd(struct tevent_context *ev,
     
    617614        return ev->ops->loop_wait(ev, location);
    618615}
     616
     617
     618/*
     619  re-initialise a tevent context. This leaves you with the same
     620  event context, but all events are wiped and the structure is
     621  re-initialised. This is most useful after a fork() 
     622
     623  zero is returned on success, non-zero on failure
     624*/
     625int tevent_re_initialise(struct tevent_context *ev)
     626{
     627        tevent_common_context_destructor(ev);
     628
     629        return ev->ops->context_init(ev);
     630}
  • trunk/server/lib/tevent/tevent.h

    r414 r745  
    4141struct tevent_signal;
    4242
     43/**
     44 * @defgroup tevent The tevent API
     45 *
     46 * The tevent low-level API
     47 *
     48 * This API provides the public interface to manage events in the tevent
     49 * mainloop. Functions are provided for managing low-level events such
     50 * as timer events, fd events and signal handling.
     51 *
     52 * @{
     53 */
     54
    4355/* event handler types */
     56/**
     57 * Called when a file descriptor monitored by tevent has
     58 * data to be read or written on it.
     59 */
    4460typedef void (*tevent_fd_handler_t)(struct tevent_context *ev,
    4561                                    struct tevent_fd *fde,
    4662                                    uint16_t flags,
    4763                                    void *private_data);
     64
     65/**
     66 * Called when tevent is ceasing the monitoring of a file descriptor.
     67 */
    4868typedef void (*tevent_fd_close_fn_t)(struct tevent_context *ev,
    4969                                     struct tevent_fd *fde,
    5070                                     int fd,
    5171                                     void *private_data);
     72
     73/**
     74 * Called when a tevent timer has fired.
     75 */
    5276typedef void (*tevent_timer_handler_t)(struct tevent_context *ev,
    5377                                       struct tevent_timer *te,
    5478                                       struct timeval current_time,
    5579                                       void *private_data);
     80
     81/**
     82 * Called when a tevent immediate event is invoked.
     83 */
    5684typedef void (*tevent_immediate_handler_t)(struct tevent_context *ctx,
    5785                                           struct tevent_immediate *im,
    5886                                           void *private_data);
     87
     88/**
     89 * Called after tevent detects the specified signal.
     90 */
    5991typedef void (*tevent_signal_handler_t)(struct tevent_context *ev,
    6092                                        struct tevent_signal *se,
     
    6496                                        void *private_data);
    6597
     98/**
     99 * @brief Create a event_context structure.
     100 *
     101 * This must be the first events call, and all subsequent calls pass this
     102 * event_context as the first element. Event handlers also receive this as
     103 * their first argument.
     104 *
     105 * @param[in]  mem_ctx  The memory context to use.
     106 *
     107 * @return              An allocated tevent context, NULL on error.
     108 *
     109 * @see tevent_context_init()
     110 */
    66111struct tevent_context *tevent_context_init(TALLOC_CTX *mem_ctx);
     112
     113/**
     114 * @brief Create a event_context structure and name it.
     115 *
     116 * This must be the first events call, and all subsequent calls pass this
     117 * event_context as the first element. Event handlers also receive this as
     118 * their first argument.
     119 *
     120 * @param[in]  mem_ctx  The memory context to use.
     121 *
     122 * @param[in]  name     The name for the tevent context.
     123 *
     124 * @return              An allocated tevent context, NULL on error.
     125 */
    67126struct tevent_context *tevent_context_init_byname(TALLOC_CTX *mem_ctx, const char *name);
     127
     128/**
     129 * @brief List available backends.
     130 *
     131 * @param[in]  mem_ctx  The memory context to use.
     132 *
     133 * @return              A string vector with a terminating NULL element, NULL
     134 *                      on error.
     135 */
    68136const char **tevent_backend_list(TALLOC_CTX *mem_ctx);
     137
     138/**
     139 * @brief Set the default tevent backent.
     140 *
     141 * @param[in]  backend  The name of the backend to set.
     142 */
    69143void tevent_set_default_backend(const char *backend);
    70144
     145#ifdef DOXYGEN
     146/**
     147 * @brief Add a file descriptor based event.
     148 *
     149 * @param[in]  ev       The event context to work on.
     150 *
     151 * @param[in]  mem_ctx  The talloc memory context to use.
     152 *
     153 * @param[in]  fd       The file descriptor to base the event on.
     154 *
     155 * @param[in]  flags    #TEVENT_FD_READ or #TEVENT_FD_WRITE
     156 *
     157 * @param[in]  handler  The callback handler for the event.
     158 *
     159 * @param[in]  private_data  The private data passed to the callback handler.
     160 *
     161 * @return              The file descriptor based event, NULL on error.
     162 *
     163 * @note To cancel the monitoring of a file descriptor, call talloc_free()
     164 * on the object returned by this function.
     165 */
     166struct tevent_fd *tevent_add_fd(struct tevent_context *ev,
     167                                TALLOC_CTX *mem_ctx,
     168                                int fd,
     169                                uint16_t flags,
     170                                tevent_fd_handler_t handler,
     171                                void *private_data);
     172#else
    71173struct tevent_fd *_tevent_add_fd(struct tevent_context *ev,
    72174                                 TALLOC_CTX *mem_ctx,
     
    80182        _tevent_add_fd(ev, mem_ctx, fd, flags, handler, private_data, \
    81183                       #handler, __location__)
    82 
     184#endif
     185
     186#ifdef DOXYGEN
     187/**
     188 * @brief Add a timed event
     189 *
     190 * @param[in]  ev       The event context to work on.
     191 *
     192 * @param[in]  mem_ctx  The talloc memory context to use.
     193 *
     194 * @param[in]  next_event  Timeval specifying the absolute time to fire this
     195 * event. This is not an offset.
     196 *
     197 * @param[in]  handler  The callback handler for the event.
     198 *
     199 * @param[in]  private_data  The private data passed to the callback handler.
     200 *
     201 * @return The newly-created timer event, or NULL on error.
     202 *
     203 * @note To cancel a timer event before it fires, call talloc_free() on the
     204 * event returned from this function. This event is automatically
     205 * talloc_free()-ed after its event handler files, if it hasn't been freed yet.
     206 *
     207 * @note Unlike some mainloops, tevent timers are one-time events. To set up
     208 * a recurring event, it is necessary to call tevent_add_timer() again during
     209 * the handler processing.
     210 *
     211 * @note Due to the internal mainloop processing, a timer set to run
     212 * immediately will do so after any other pending timers fire, but before
     213 * any further file descriptor or signal handling events fire. Callers should
     214 * not rely on this behavior!
     215 */
     216struct tevent_timer *tevent_add_timer(struct tevent_context *ev,
     217                                      TALLOC_CTX *mem_ctx,
     218                                      struct timeval next_event,
     219                                      tevent_timer_handler_t handler,
     220                                      void *private_data);
     221#else
    83222struct tevent_timer *_tevent_add_timer(struct tevent_context *ev,
    84223                                       TALLOC_CTX *mem_ctx,
     
    91230        _tevent_add_timer(ev, mem_ctx, next_event, handler, private_data, \
    92231                          #handler, __location__)
    93 
     232#endif
     233
     234#ifdef DOXYGEN
     235/**
     236 * Initialize an immediate event object
     237 *
     238 * This object can be used to trigger an event to occur immediately after
     239 * returning from the current event (before any other event occurs)
     240 *
     241 * @param[in] mem_ctx  The talloc memory context to use as the parent
     242 *
     243 * @return An empty tevent_immediate object. Use tevent_schedule_immediate
     244 * to populate and use it.
     245 *
     246 * @note Available as of tevent 0.9.8
     247 */
     248struct tevent_immediate *tevent_create_immediate(TALLOC_CTX *mem_ctx);
     249#else
    94250struct tevent_immediate *_tevent_create_immediate(TALLOC_CTX *mem_ctx,
    95251                                                  const char *location);
    96252#define tevent_create_immediate(mem_ctx) \
    97253        _tevent_create_immediate(mem_ctx, __location__)
    98 
     254#endif
     255
     256#ifdef DOXYGEN
     257
     258/**
     259 * Schedule an event for immediate execution. This event will occur
     260 * immediately after returning from the current event (before any other
     261 * event occurs)
     262 *
     263 * @param[in] im       The tevent_immediate object to populate and use
     264 * @param[in] ctx      The tevent_context to run this event
     265 * @param[in] handler  The event handler to run when this event fires
     266 * @param[in] private_data  Data to pass to the event handler
     267 */
     268void tevent_schedule_immediate(struct tevent_immediate *im,
     269                struct tevent_context *ctx,
     270                tevent_immediate_handler_t handler,
     271                void *private_data);
     272#else
    99273void _tevent_schedule_immediate(struct tevent_immediate *im,
    100274                                struct tevent_context *ctx,
     
    106280        _tevent_schedule_immediate(im, ctx, handler, private_data, \
    107281                                   #handler, __location__);
    108 
     282#endif
     283
     284#ifdef DOXYGEN
     285/**
     286 * @brief Add a tevent signal handler
     287 *
     288 * tevent_add_signal() creates a new event for handling a signal the next
     289 * time through the mainloop. It implements a very simple traditional signal
     290 * handler whose only purpose is to add the handler event into the mainloop.
     291 *
     292 * @param[in]  ev       The event context to work on.
     293 *
     294 * @param[in]  mem_ctx  The talloc memory context to use.
     295 *
     296 * @param[in]  signum   The signal to trap
     297 *
     298 * @param[in]  handler  The callback handler for the signal.
     299 *
     300 * @param[in]  sa_flags sigaction flags for this signal handler.
     301 *
     302 * @param[in]  private_data  The private data passed to the callback handler.
     303 *
     304 * @return The newly-created signal handler event, or NULL on error.
     305 *
     306 * @note To cancel a signal handler, call talloc_free() on the event returned
     307 * from this function.
     308 */
     309struct tevent_signal *tevent_add_signal(struct tevent_context *ev,
     310                     TALLOC_CTX *mem_ctx,
     311                     int signum,
     312                     int sa_flags,
     313                     tevent_signal_handler_t handler,
     314                     void *private_data);
     315#else
    109316struct tevent_signal *_tevent_add_signal(struct tevent_context *ev,
    110317                                         TALLOC_CTX *mem_ctx,
     
    118325        _tevent_add_signal(ev, mem_ctx, signum, sa_flags, handler, private_data, \
    119326                           #handler, __location__)
    120 
     327#endif
     328
     329#ifdef DOXYGEN
     330/**
     331 * @brief Pass a single time through the mainloop
     332 *
     333 * This will process any appropriate signal, immediate, fd and timer events
     334 *
     335 * @param[in]  ev The event context to process
     336 *
     337 * @return Zero on success, nonzero if an internal error occurred
     338 */
     339int tevent_loop_once(struct tevent_context *ev);
     340#else
    121341int _tevent_loop_once(struct tevent_context *ev, const char *location);
    122342#define tevent_loop_once(ev) \
    123         _tevent_loop_once(ev, __location__) \
    124 
     343        _tevent_loop_once(ev, __location__)
     344#endif
     345
     346#ifdef DOXYGEN
     347/**
     348 * @brief Run the mainloop
     349 *
     350 * The mainloop will run until there are no events remaining to be processed
     351 *
     352 * @param[in]  ev The event context to process
     353 *
     354 * @return Zero if all events have been processed. Nonzero if an internal
     355 * error occurred.
     356 */
     357int tevent_loop_wait(struct tevent_context *ev);
     358#else
    125359int _tevent_loop_wait(struct tevent_context *ev, const char *location);
    126360#define tevent_loop_wait(ev) \
    127         _tevent_loop_wait(ev, __location__) \
    128 
     361        _tevent_loop_wait(ev, __location__)
     362#endif
     363
     364
     365/**
     366 * Assign a function to run when a tevent_fd is freed
     367 *
     368 * This function is a destructor for the tevent_fd. It does not automatically
     369 * close the file descriptor. If this is the desired behavior, then it must be
     370 * performed by the close_fn.
     371 *
     372 * @param[in] fde       File descriptor event on which to set the destructor
     373 * @param[in] close_fn  Destructor to execute when fde is freed
     374 */
    129375void tevent_fd_set_close_fn(struct tevent_fd *fde,
    130376                            tevent_fd_close_fn_t close_fn);
     377
     378/**
     379 * Automatically close the file descriptor when the tevent_fd is freed
     380 *
     381 * This function calls close(fd) internally.
     382 *
     383 * @param[in] fde  File descriptor event to auto-close
     384 */
    131385void tevent_fd_set_auto_close(struct tevent_fd *fde);
     386
     387/**
     388 * Return the flags set on this file descriptor event
     389 *
     390 * @param[in] fde  File descriptor event to query
     391 *
     392 * @return The flags set on the event. See #TEVENT_FD_READ and
     393 * #TEVENT_FD_WRITE
     394 */
    132395uint16_t tevent_fd_get_flags(struct tevent_fd *fde);
     396
     397/**
     398 * Set flags on a file descriptor event
     399 *
     400 * @param[in] fde    File descriptor event to set
     401 * @param[in] flags  Flags to set on the event. See #TEVENT_FD_READ and
     402 * #TEVENT_FD_WRITE
     403 */
    133404void tevent_fd_set_flags(struct tevent_fd *fde, uint16_t flags);
    134405
     406/**
     407 * Query whether tevent supports signal handling
     408 *
     409 * @param[in] ev  An initialized tevent context
     410 *
     411 * @return True if this platform and tevent context support signal handling
     412 */
    135413bool tevent_signal_support(struct tevent_context *ev);
    136414
     
    138416
    139417/* bits for file descriptor event flags */
     418
     419/**
     420 * Monitor a file descriptor for write availability
     421 */
    140422#define TEVENT_FD_READ 1
     423/**
     424 * Monitor a file descriptor for data to be read
     425 */
    141426#define TEVENT_FD_WRITE 2
    142427
     428/**
     429 * Convenience function for declaring a tevent_fd writable
     430 */
    143431#define TEVENT_FD_WRITEABLE(fde) \
    144432        tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) | TEVENT_FD_WRITE)
     433
     434/**
     435 * Convenience function for declaring a tevent_fd readable
     436 */
    145437#define TEVENT_FD_READABLE(fde) \
    146438        tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) | TEVENT_FD_READ)
    147439
     440/**
     441 * Convenience function for declaring a tevent_fd non-writable
     442 */
    148443#define TEVENT_FD_NOT_WRITEABLE(fde) \
    149444        tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) & ~TEVENT_FD_WRITE)
     445
     446/**
     447 * Convenience function for declaring a tevent_fd non-readable
     448 */
    150449#define TEVENT_FD_NOT_READABLE(fde) \
    151450        tevent_fd_set_flags(fde, tevent_fd_get_flags(fde) & ~TEVENT_FD_READ)
    152451
    153 /* DEBUG */
     452/**
     453 * Debug level of tevent
     454 */
    154455enum tevent_debug_level {
    155456        TEVENT_DEBUG_FATAL,
     
    159460};
    160461
     462/**
     463 * @brief The tevent debug callbac.
     464 *
     465 * @param[in]  context  The memory context to use.
     466 *
     467 * @param[in]  level    The debug level.
     468 *
     469 * @param[in]  fmt      The format string.
     470 *
     471 * @param[in]  ap       The arguments for the format string.
     472 */
     473typedef void (*tevent_debug_fn)(void *context,
     474                                enum tevent_debug_level level,
     475                                const char *fmt,
     476                                va_list ap) PRINTF_ATTRIBUTE(3,0);
     477
     478/**
     479 * Set destination for tevent debug messages
     480 *
     481 * @param[in] ev        Event context to debug
     482 * @param[in] debug     Function to handle output printing
     483 * @param[in] context   The context to pass to the debug function.
     484 *
     485 * @return Always returns 0 as of version 0.9.8
     486 *
     487 * @note Default is to emit no debug messages
     488 */
    161489int tevent_set_debug(struct tevent_context *ev,
    162                      void (*debug)(void *context,
    163                                    enum tevent_debug_level level,
    164                                    const char *fmt,
    165                                    va_list ap) PRINTF_ATTRIBUTE(3,0),
     490                     tevent_debug_fn debug,
    166491                     void *context);
     492
     493/**
     494 * Designate stderr for debug message output
     495 *
     496 * @param[in] ev     Event context to debug
     497 *
     498 * @note This function will only output TEVENT_DEBUG_FATAL, TEVENT_DEBUG_ERROR
     499 * and TEVENT_DEBUG_WARNING messages. For TEVENT_DEBUG_TRACE, please define a
     500 * function for tevent_set_debug()
     501 */
    167502int tevent_set_debug_stderr(struct tevent_context *ev);
    168503
    169504/**
    170  * An async request moves between the following 4 states:
     505 * @}
     506 */
     507
     508/**
     509 * @defgroup tevent_request The tevent request functions.
     510 * @ingroup tevent
     511 *
     512 * A tevent_req represents an asynchronous computation.
     513 *
     514 * The tevent_req group of API calls is the recommended way of
     515 * programming async computations within tevent. In particular the
     516 * file descriptor (tevent_add_fd) and timer (tevent_add_timed) events
     517 * are considered too low-level to be used in larger computations. To
     518 * read and write from and to sockets, Samba provides two calls on top
     519 * of tevent_add_fd: read_packet_send/recv and writev_send/recv. These
     520 * requests are much easier to compose than the low-level event
     521 * handlers called from tevent_add_fd.
     522 *
     523 * A lot of the simplicity tevent_req has brought to the notoriously
     524 * hairy async programming came via a set of conventions that every
     525 * async computation programmed should follow. One central piece of
     526 * these conventions is the naming of routines and variables.
     527 *
     528 * Every async computation needs a name (sensibly called "computation"
     529 * down from here). From this name quite a few naming conventions are
     530 * derived.
     531 *
     532 * Every computation that requires local state needs a
     533 * @code
     534 * struct computation_state {
     535 *     int local_var;
     536 * };
     537 * @endcode
     538 * Even if no local variables are required, such a state struct should
     539 * be created containing a dummy variable. Quite a few helper
     540 * functions and macros (for example tevent_req_create()) assume such
     541 * a state struct.
     542 *
     543 * An async computation is started by a computation_send
     544 * function. When it is finished, its result can be received by a
     545 * computation_recv function. For an example how to set up an async
     546 * computation, see the code example in the documentation for
     547 * tevent_req_create() and tevent_req_post(). The prototypes for _send
     548 * and _recv functions should follow some conventions:
     549 *
     550 * @code
     551 * struct tevent_req *computation_send(TALLOC_CTX *mem_ctx,
     552 *                                     struct tevent_req *ev,
     553 *                                     ... further args);
     554 * int computation_recv(struct tevent_req *req, ... further output args);
     555 * @endcode
     556 *
     557 * The "int" result of computation_recv() depends on the result the
     558 * sync version of the function would have, "int" is just an example
     559 * here.
     560 *
     561 * Another important piece of the conventions is that the program flow
     562 * is interrupted as little as possible. Because a blocking
     563 * sub-computation requires that the flow needs to continue in a
     564 * separate function that is the logical sequel of some computation,
     565 * it should lexically follow sending off the blocking
     566 * sub-computation. Setting the callback function via
     567 * tevent_req_set_callback() requires referencing a function lexically
     568 * below the call to tevent_req_set_callback(), forward declarations
     569 * are required. A lot of the async computations thus begin with a
     570 * sequence of declarations such as
     571 *
     572 * @code
     573 * static void computation_step1_done(struct tevent_req *subreq);
     574 * static void computation_step2_done(struct tevent_req *subreq);
     575 * static void computation_step3_done(struct tevent_req *subreq);
     576 * @endcode
     577 *
     578 * It really helps readability a lot to do these forward declarations,
     579 * because the lexically sequential program flow makes the async
     580 * computations almost as clear to read as a normal, sync program
     581 * flow.
     582 *
     583 * It is up to the user of the async computation to talloc_free it
     584 * after it has finished. If an async computation should be aborted,
     585 * the tevent_req structure can be talloc_free'ed. After it has
     586 * finished, it should talloc_free'ed by the API user.
     587 *
     588 * @{
     589 */
     590
     591/**
     592 * An async request moves from TEVENT_REQ_INIT to
     593 * TEVENT_REQ_IN_PROGRESS. All other states are valid after a request
     594 * has finished.
    171595 */
    172596enum tevent_req_state {
    173597        /**
    174          * we are creating the request
     598         * We are creating the request
    175599         */
    176600        TEVENT_REQ_INIT,
    177601        /**
    178          * we are waiting the request to complete
     602         * We are waiting the request to complete
    179603         */
    180604        TEVENT_REQ_IN_PROGRESS,
    181605        /**
    182          * the request is finished
     606         * The request is finished successfully
    183607         */
    184608        TEVENT_REQ_DONE,
    185609        /**
    186          * A user error has occured
     610         * A user error has occurred. The user error has been
     611         * indicated by tevent_req_error(), it can be retrieved via
     612         * tevent_req_is_error().
    187613         */
    188614        TEVENT_REQ_USER_ERROR,
    189615        /**
    190          * Request timed out
     616         * Request timed out after the timeout set by tevent_req_set_endtime.
    191617         */
    192618        TEVENT_REQ_TIMED_OUT,
    193619        /**
    194          * No memory in between
     620         * An internal allocation has failed, or tevent_req_nomem has
     621         * been given a NULL pointer as the first argument.
    195622         */
    196623        TEVENT_REQ_NO_MEMORY,
    197624        /**
    198          * the request is already received by the caller
     625         * The request has been received by the caller. No further
     626         * action is valid.
    199627         */
    200628        TEVENT_REQ_RECEIVED
     
    203631/**
    204632 * @brief An async request
    205  *
    206  * This represents an async request being processed by callbacks via an event
    207  * context. A user can issue for example a write request to a socket, giving
    208  * an implementation function the fd, the buffer and the number of bytes to
    209  * transfer. The function issuing the request will immediately return without
    210  * blocking most likely without having sent anything. The API user then fills
    211  * in req->async.fn and req->async.private_data, functions that are called
    212  * when the request is finished.
    213  *
    214  * It is up to the user of the async request to talloc_free it after it has
    215  * finished. This can happen while the completion function is called.
    216  */
    217 
     633 */
    218634struct tevent_req;
    219635
    220 typedef void (*tevent_req_fn)(struct tevent_req *);
    221 
     636/**
     637 * @brief A tevent request callback function.
     638 *
     639 * @param[in]  req      The tevent async request which executed this callback.
     640 */
     641typedef void (*tevent_req_fn)(struct tevent_req *req);
     642
     643/**
     644 * @brief Set an async request callback.
     645 *
     646 * See the documentation of tevent_req_post() for an example how this
     647 * is supposed to be used.
     648 *
     649 * @param[in]  req      The async request to set the callback.
     650 *
     651 * @param[in]  fn       The callback function to set.
     652 *
     653 * @param[in]  pvt      A pointer to private data to pass to the async request
     654 *                      callback.
     655 */
    222656void tevent_req_set_callback(struct tevent_req *req, tevent_req_fn fn, void *pvt);
     657
     658#ifdef DOXYGEN
     659/**
     660 * @brief Get the private data cast to the given type for a callback from
     661 *        a tevent request structure.
     662 *
     663 * @code
     664 * static void computation_done(struct tevent_req *subreq) {
     665 *     struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req);
     666 *     struct computation_state *state = tevent_req_data(req, struct computation_state);
     667 *     .... more things, eventually maybe call tevent_req_done(req);
     668 * }
     669 * @endcode
     670 *
     671 * @param[in]  req      The structure to get the callback data from.
     672 *
     673 * @param[in]  type     The type of the private callback data to get.
     674 *
     675 * @return              The type casted private data set NULL if not set.
     676 */
     677void *tevent_req_callback_data(struct tevent_req *req, #type);
     678#else
    223679void *_tevent_req_callback_data(struct tevent_req *req);
    224 void *_tevent_req_data(struct tevent_req *req);
    225 
    226680#define tevent_req_callback_data(_req, _type) \
    227681        talloc_get_type_abort(_tevent_req_callback_data(_req), _type)
     682#endif
     683
     684#ifdef DOXYGEN
     685/**
     686 * @brief Get the private data for a callback from a tevent request structure.
     687 *
     688 * @param[in]  req      The structure to get the callback data from.
     689 *
     690 * @param[in]  req      The structure to get the data from.
     691 *
     692 * @return              The private data or NULL if not set.
     693 */
     694void *tevent_req_callback_data_void(struct tevent_req *req);
     695#else
    228696#define tevent_req_callback_data_void(_req) \
    229697        _tevent_req_callback_data(_req)
     698#endif
     699
     700#ifdef DOXYGEN
     701/**
     702 * @brief Get the private data from a tevent request structure.
     703 *
     704 * When the tevent_req has been created by tevent_req_create, the
     705 * result of tevent_req_data() is the state variable created by
     706 * tevent_req_create() as a child of the req.
     707 *
     708 * @param[in]  req      The structure to get the private data from.
     709 *
     710 * @param[in]  type     The type of the private data
     711 *
     712 * @return              The private data or NULL if not set.
     713 */
     714void *tevent_req_data(struct tevent_req *req, #type);
     715#else
     716void *_tevent_req_data(struct tevent_req *req);
    230717#define tevent_req_data(_req, _type) \
    231718        talloc_get_type_abort(_tevent_req_data(_req), _type)
    232 
    233 typedef char *(*tevent_req_print_fn)(struct tevent_req *, TALLOC_CTX *);
    234 
     719#endif
     720
     721/**
     722 * @brief The print function which can be set for a tevent async request.
     723 *
     724 * @param[in]  req      The tevent async request.
     725 *
     726 * @param[in]  ctx      A talloc memory context which can be uses to allocate
     727 *                      memory.
     728 *
     729 * @return              An allocated string buffer to print.
     730 *
     731 * Example:
     732 * @code
     733 *   static char *my_print(struct tevent_req *req, TALLOC_CTX *mem_ctx)
     734 *   {
     735 *     struct my_data *data = tevent_req_data(req, struct my_data);
     736 *     char *result;
     737 *
     738 *     result = tevent_req_default_print(mem_ctx, req);
     739 *     if (result == NULL) {
     740 *       return NULL;
     741 *     }
     742 *
     743 *     return talloc_asprintf_append_buffer(result, "foo=%d, bar=%d",
     744 *       data->foo, data->bar);
     745 *   }
     746 * @endcode
     747 */
     748typedef char *(*tevent_req_print_fn)(struct tevent_req *req, TALLOC_CTX *ctx);
     749
     750/**
     751 * @brief This function sets a print function for the given request.
     752 *
     753 * This function can be used to setup a print function for the given request.
     754 * This will be triggered if the tevent_req_print() function was
     755 * called on the given request.
     756 *
     757 * @param[in]  req      The request to use.
     758 *
     759 * @param[in]  fn       A pointer to the print function
     760 *
     761 * @note This function should only be used for debugging.
     762 */
    235763void tevent_req_set_print_fn(struct tevent_req *req, tevent_req_print_fn fn);
    236764
     765/**
     766 * @brief The default print function for creating debug messages.
     767 *
     768 * The function should not be used by users of the async API,
     769 * but custom print function can use it and append custom text
     770 * to the string.
     771 *
     772 * @param[in]  req      The request to be printed.
     773 *
     774 * @param[in]  mem_ctx  The memory context for the result.
     775 *
     776 * @return              Text representation of request.
     777 *
     778 */
    237779char *tevent_req_default_print(struct tevent_req *req, TALLOC_CTX *mem_ctx);
    238780
     781/**
     782 * @brief Print an tevent_req structure in debug messages.
     783 *
     784 * This function should be used by callers of the async API.
     785 *
     786 * @param[in]  mem_ctx  The memory context for the result.
     787 *
     788 * @param[in] req       The request to be printed.
     789 *
     790 * @return              Text representation of request.
     791 */
    239792char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req);
    240793
    241 typedef bool (*tevent_req_cancel_fn)(struct tevent_req *);
    242 
     794/**
     795 * @brief A typedef for a cancel function for a tevent request.
     796 *
     797 * @param[in]  req      The tevent request calling this function.
     798 *
     799 * @return              True if the request could be canceled, false if not.
     800 */
     801typedef bool (*tevent_req_cancel_fn)(struct tevent_req *req);
     802
     803/**
     804 * @brief This function sets a cancel function for the given tevent request.
     805 *
     806 * This function can be used to setup a cancel function for the given request.
     807 * This will be triggered if the tevent_req_cancel() function was
     808 * called on the given request.
     809 *
     810 * @param[in]  req      The request to use.
     811 *
     812 * @param[in]  fn       A pointer to the cancel function.
     813 */
    243814void tevent_req_set_cancel_fn(struct tevent_req *req, tevent_req_cancel_fn fn);
    244815
     816#ifdef DOXYGEN
     817/**
     818 * @brief Try to cancel the given tevent request.
     819 *
     820 * This function can be used to cancel the given request.
     821 *
     822 * It is only possible to cancel a request when the implementation
     823 * has registered a cancel function via the tevent_req_set_cancel_fn().
     824 *
     825 * @param[in]  req      The request to use.
     826 *
     827 * @return              This function returns true is the request is cancelable,
     828 *                      othererwise false is returned.
     829 *
     830 * @note Even if the function returns true, the caller need to wait
     831 *       for the function to complete normally.
     832 *       Only the _recv() function of the given request indicates
     833 *       if the request was really canceled.
     834 */
     835bool tevent_req_cancel(struct tevent_req *req);
     836#else
    245837bool _tevent_req_cancel(struct tevent_req *req, const char *location);
    246838#define tevent_req_cancel(req) \
    247839        _tevent_req_cancel(req, __location__)
    248 
     840#endif
     841
     842#ifdef DOXYGEN
     843/**
     844 * @brief Create an async tevent request.
     845 *
     846 * The new async request will be initialized in state TEVENT_REQ_IN_PROGRESS.
     847 *
     848 * @code
     849 * struct tevent_req *req;
     850 * struct computation_state *state;
     851 * req = tevent_req_create(mem_ctx, &state, struct computation_state);
     852 * @endcode
     853 *
     854 * Tevent_req_create() creates the state variable as a talloc child of
     855 * its result. The state variable should be used as the talloc parent
     856 * for all temporary variables that are allocated during the async
     857 * computation. This way, when the user of the async computation frees
     858 * the request, the state as a talloc child will be free'd along with
     859 * all the temporary variables hanging off the state.
     860 *
     861 * @param[in] mem_ctx   The memory context for the result.
     862 * @param[in] pstate    Pointer to the private request state.
     863 * @param[in] type      The name of the request.
     864 *
     865 * @return              A new async request. NULL on error.
     866 */
     867struct tevent_req *tevent_req_create(TALLOC_CTX *mem_ctx,
     868                                     void **pstate, #type);
     869#else
    249870struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx,
    250871                                      void *pstate,
     
    256877        _tevent_req_create((_mem_ctx), (_pstate), sizeof(_type), \
    257878                           #_type, __location__)
    258 
     879#endif
     880
     881/**
     882 * @brief Set a timeout for an async request.
     883 *
     884 * @param[in]  req      The request to set the timeout for.
     885 *
     886 * @param[in]  ev       The event context to use for the timer.
     887 *
     888 * @param[in]  endtime  The endtime of the request.
     889 *
     890 * @return              True if succeeded, false if not.
     891 */
    259892bool tevent_req_set_endtime(struct tevent_req *req,
    260893                            struct tevent_context *ev,
    261894                            struct timeval endtime);
    262895
     896#ifdef DOXYGEN
     897/**
     898 * @brief Call the notify callback of the given tevent request manually.
     899 *
     900 * @param[in]  req      The tevent request to call the notify function from.
     901 *
     902 * @see tevent_req_set_callback()
     903 */
     904void tevent_req_notify_callback(struct tevent_req *req);
     905#else
    263906void _tevent_req_notify_callback(struct tevent_req *req, const char *location);
    264907#define tevent_req_notify_callback(req)         \
    265908        _tevent_req_notify_callback(req, __location__)
    266 
     909#endif
     910
     911#ifdef DOXYGEN
     912/**
     913 * @brief An async request has successfully finished.
     914 *
     915 * This function is to be used by implementors of async requests. When a
     916 * request is successfully finished, this function calls the user's completion
     917 * function.
     918 *
     919 * @param[in]  req       The finished request.
     920 */
     921void tevent_req_done(struct tevent_req *req);
     922#else
    267923void _tevent_req_done(struct tevent_req *req,
    268924                      const char *location);
    269925#define tevent_req_done(req) \
    270926        _tevent_req_done(req, __location__)
    271 
     927#endif
     928
     929#ifdef DOXYGEN
     930/**
     931 * @brief An async request has seen an error.
     932 *
     933 * This function is to be used by implementors of async requests. When a
     934 * request can not successfully completed, the implementation should call this
     935 * function with the appropriate status code.
     936 *
     937 * If error is 0 the function returns false and does nothing more.
     938 *
     939 * @param[in]  req      The request with an error.
     940 *
     941 * @param[in]  error    The error code.
     942 *
     943 * @return              On success true is returned, false if error is 0.
     944 *
     945 * @code
     946 * int error = first_function();
     947 * if (tevent_req_error(req, error)) {
     948 *      return;
     949 * }
     950 *
     951 * error = second_function();
     952 * if (tevent_req_error(req, error)) {
     953 *      return;
     954 * }
     955 *
     956 * tevent_req_done(req);
     957 * return;
     958 * @endcode
     959 */
     960bool tevent_req_error(struct tevent_req *req,
     961                      uint64_t error);
     962#else
    272963bool _tevent_req_error(struct tevent_req *req,
    273964                       uint64_t error,
     
    275966#define tevent_req_error(req, error) \
    276967        _tevent_req_error(req, error, __location__)
    277 
     968#endif
     969
     970#ifdef DOXYGEN
     971/**
     972 * @brief Helper function for nomem check.
     973 *
     974 * Convenience helper to easily check alloc failure within a callback
     975 * implementing the next step of an async request.
     976 *
     977 * @param[in]  p        The pointer to be checked.
     978 *
     979 * @param[in]  req      The request being processed.
     980 *
     981 * @code
     982 * p = talloc(mem_ctx, bla);
     983 * if (tevent_req_nomem(p, req)) {
     984 *      return;
     985 * }
     986 * @endcode
     987 */
     988bool tevent_req_nomem(const void *p,
     989                      struct tevent_req *req);
     990#else
    278991bool _tevent_req_nomem(const void *p,
    279992                       struct tevent_req *req,
     
    281994#define tevent_req_nomem(p, req) \
    282995        _tevent_req_nomem(p, req, __location__)
    283 
     996#endif
     997
     998/**
     999 * @brief Finish a request before the caller had the change to set the callback.
     1000 *
     1001 * An implementation of an async request might find that it can either finish
     1002 * the request without waiting for an external event, or it can not even start
     1003 * the engine. To present the illusion of a callback to the user of the API,
     1004 * the implementation can call this helper function which triggers an
     1005 * immediate timed event. This way the caller can use the same calling
     1006 * conventions, independent of whether the request was actually deferred.
     1007 *
     1008 * @code
     1009 * struct tevent_req *computation_send(TALLOC_CTX *mem_ctx,
     1010 *                                     struct tevent_context *ev)
     1011 * {
     1012 *     struct tevent_req *req, *subreq;
     1013 *     struct computation_state *state;
     1014 *     req = tevent_req_create(mem_ctx, &state, struct computation_state);
     1015 *     if (req == NULL) {
     1016 *         return NULL;
     1017 *     }
     1018 *     subreq = subcomputation_send(state, ev);
     1019 *     if (tevent_req_nomem(subreq, req)) {
     1020 *         return tevent_req_post(req, ev);
     1021 *     }
     1022 *     tevent_req_set_callback(subreq, computation_done, req);
     1023 *     return req;
     1024 * }
     1025 * @endcode
     1026 *
     1027 * @param[in]  req      The finished request.
     1028 *
     1029 * @param[in]  ev       The tevent_context for the timed event.
     1030 *
     1031 * @return              The given request will be returned.
     1032 */
    2841033struct tevent_req *tevent_req_post(struct tevent_req *req,
    2851034                                   struct tevent_context *ev);
    2861035
     1036/**
     1037 * @brief Check if the given request is still in progress.
     1038 *
     1039 * It is typically used by sync wrapper functions.
     1040 *
     1041 * @param[in]  req      The request to poll.
     1042 *
     1043 * @return              The boolean form of "is in progress".
     1044 */
    2871045bool tevent_req_is_in_progress(struct tevent_req *req);
    2881046
     1047/**
     1048 * @brief Actively poll for the given request to finish.
     1049 *
     1050 * This function is typically used by sync wrapper functions.
     1051 *
     1052 * @param[in]  req      The request to poll.
     1053 *
     1054 * @param[in]  ev       The tevent_context to be used.
     1055 *
     1056 * @return              On success true is returned. If a critical error has
     1057 *                      happened in the tevent loop layer false is returned.
     1058 *                      This is not the return value of the given request!
     1059 *
     1060 * @note This should only be used if the given tevent context was created by the
     1061 * caller, to avoid event loop nesting.
     1062 *
     1063 * @code
     1064 * req = tstream_writev_queue_send(mem_ctx,
     1065 *                                 ev_ctx,
     1066 *                                 tstream,
     1067 *                                 send_queue,
     1068 *                                 iov, 2);
     1069 * ok = tevent_req_poll(req, tctx->ev);
     1070 * rc = tstream_writev_queue_recv(req, &sys_errno);
     1071 * TALLOC_FREE(req);
     1072 * @endcode
     1073 */
    2891074bool tevent_req_poll(struct tevent_req *req,
    2901075                     struct tevent_context *ev);
    2911076
     1077/**
     1078 * @brief Get the tevent request state and the actual error set by
     1079 * tevent_req_error.
     1080 *
     1081 * @code
     1082 * int computation_recv(struct tevent_req *req, uint64_t *perr)
     1083 * {
     1084 *     enum tevent_req_state state;
     1085 *     uint64_t err;
     1086 *     if (tevent_req_is_error(req, &state, &err)) {
     1087 *         *perr = err;
     1088 *         return -1;
     1089 *     }
     1090 *     return 0;
     1091 * }
     1092 * @endcode
     1093 *
     1094 * @param[in]  req      The tevent request to get the error from.
     1095 *
     1096 * @param[out] state    A pointer to store the tevent request error state.
     1097 *
     1098 * @param[out] error    A pointer to store the error set by tevent_req_error().
     1099 *
     1100 * @return              True if the function could set error and state, false
     1101 *                      otherwise.
     1102 *
     1103 * @see tevent_req_error()
     1104 */
    2921105bool tevent_req_is_error(struct tevent_req *req,
    2931106                         enum tevent_req_state *state,
    2941107                         uint64_t *error);
    2951108
     1109/**
     1110 * @brief Use as the last action of a _recv() function.
     1111 *
     1112 * This function destroys the attached private data.
     1113 *
     1114 * @param[in]  req      The finished request.
     1115 */
    2961116void tevent_req_received(struct tevent_req *req);
    2971117
     1118/**
     1119 * @brief Create a tevent subrequest at a given time.
     1120 *
     1121 * The idea is that always the same syntax for tevent requests.
     1122 *
     1123 * @param[in]  mem_ctx  The talloc memory context to use.
     1124 *
     1125 * @param[in]  ev       The event handle to setup the request.
     1126 *
     1127 * @param[in]  wakeup_time The time to wakeup and execute the request.
     1128 *
     1129 * @return              The new subrequest, NULL on error.
     1130 *
     1131 * Example:
     1132 * @code
     1133 *   static void my_callback_wakeup_done(tevent_req *subreq)
     1134 *   {
     1135 *     struct tevent_req *req = tevent_req_callback_data(subreq,
     1136 *                              struct tevent_req);
     1137 *     bool ok;
     1138 *
     1139 *     ok = tevent_wakeup_recv(subreq);
     1140 *     TALLOC_FREE(subreq);
     1141 *     if (!ok) {
     1142 *         tevent_req_error(req, -1);
     1143 *         return;
     1144 *     }
     1145 *     ...
     1146 *   }
     1147 * @endcode
     1148 *
     1149 * @code
     1150 *   subreq = tevent_wakeup_send(mem_ctx, ev, wakeup_time);
     1151 *   if (tevent_req_nomem(subreq, req)) {
     1152 *     return false;
     1153 *   }
     1154 *   tevent_set_callback(subreq, my_callback_wakeup_done, req);
     1155 * @endcode
     1156 *
     1157 * @see tevent_wakeup_recv()
     1158 */
    2981159struct tevent_req *tevent_wakeup_send(TALLOC_CTX *mem_ctx,
    2991160                                      struct tevent_context *ev,
    3001161                                      struct timeval wakeup_time);
     1162
     1163/**
     1164 * @brief Check if the wakeup has been correctly executed.
     1165 *
     1166 * This function needs to be called in the callback function set after calling
     1167 * tevent_wakeup_send().
     1168 *
     1169 * @param[in]  req      The tevent request to check.
     1170 *
     1171 * @return              True on success, false otherwise.
     1172 *
     1173 * @see tevent_wakeup_recv()
     1174 */
    3011175bool tevent_wakeup_recv(struct tevent_req *req);
    3021176
     1177/* @} */
     1178
     1179/**
     1180 * @defgroup tevent_helpers The tevent helper functiions
     1181 * @ingroup tevent
     1182 *
     1183 * @todo description
     1184 *
     1185 * @{
     1186 */
     1187
     1188/**
     1189 * @brief Compare two timeval values.
     1190 *
     1191 * @param[in]  tv1      The first timeval value to compare.
     1192 *
     1193 * @param[in]  tv2      The second timeval value to compare.
     1194 *
     1195 * @return              0 if they are equal.
     1196 *                      1 if the first time is greater than the second.
     1197 *                      -1 if the first time is smaller than the second.
     1198 */
    3031199int tevent_timeval_compare(const struct timeval *tv1,
    3041200                           const struct timeval *tv2);
    3051201
     1202/**
     1203 * @brief Get a zero timval value.
     1204 *
     1205 * @return              A zero timval value.
     1206 */
    3061207struct timeval tevent_timeval_zero(void);
    3071208
     1209/**
     1210 * @brief Get a timeval value for the current time.
     1211 *
     1212 * @return              A timval value with the current time.
     1213 */
    3081214struct timeval tevent_timeval_current(void);
    3091215
     1216/**
     1217 * @brief Get a timeval structure with the given values.
     1218 *
     1219 * @param[in]  secs     The seconds to set.
     1220 *
     1221 * @param[in]  usecs    The milliseconds to set.
     1222 *
     1223 * @return              A timeval structure with the given values.
     1224 */
    3101225struct timeval tevent_timeval_set(uint32_t secs, uint32_t usecs);
    3111226
     1227/**
     1228 * @brief Get the difference between two timeval values.
     1229 *
     1230 * @param[in]  tv1      The first timeval.
     1231 *
     1232 * @param[in]  tv2      The second timeval.
     1233 *
     1234 * @return              A timeval structure with the difference between the
     1235 *                      first and the second value.
     1236 */
    3121237struct timeval tevent_timeval_until(const struct timeval *tv1,
    3131238                                    const struct timeval *tv2);
    3141239
     1240/**
     1241 * @brief Check if a given timeval structure is zero.
     1242 *
     1243 * @param[in]  tv       The timeval to check if it is zero.
     1244 *
     1245 * @return              True if it is zero, false otherwise.
     1246 */
    3151247bool tevent_timeval_is_zero(const struct timeval *tv);
    3161248
     1249/**
     1250 * @brief Add the given amount of time to a timeval structure.
     1251 *
     1252 * @param[in]  tv        The timeval structure to add the time.
     1253 *
     1254 * @param[in]  secs      The seconds to add to the timeval.
     1255 *
     1256 * @param[in]  usecs     The milliseconds to add to the timeval.
     1257 *
     1258 * @return               The timeval structure with the new time.
     1259 */
    3171260struct timeval tevent_timeval_add(const struct timeval *tv, uint32_t secs,
    3181261                                  uint32_t usecs);
    3191262
     1263/**
     1264 * @brief Get a timeval in the future with a specified offset from now.
     1265 *
     1266 * @param[in]  secs     The seconds of the offset from now.
     1267 *
     1268 * @param[in]  usecs    The milliseconds of the offset from now.
     1269 *
     1270 * @return              A timval with the given offset in the future.
     1271 */
    3201272struct timeval tevent_timeval_current_ofs(uint32_t secs, uint32_t usecs);
    3211273
     1274/* @} */
     1275
     1276
     1277/**
     1278 * @defgroup tevent_queue The tevent queue functions
     1279 * @ingroup tevent
     1280 *
     1281 * A tevent_queue is used to queue up async requests that must be
     1282 * serialized. For example writing buffers into a socket must be
     1283 * serialized. Writing a large lump of data into a socket can require
     1284 * multiple write(2) or send(2) system calls. If more than one async
     1285 * request is outstanding to write large buffers into a socket, every
     1286 * request must individually be completed before the next one begins,
     1287 * even if multiple syscalls are required.
     1288 *
     1289 * Take a look at @ref tevent_queue_tutorial for more details.
     1290 * @{
     1291 */
     1292
    3221293struct tevent_queue;
    3231294
     1295#ifdef DOXYGEN
     1296/**
     1297 * @brief Create and start a tevent queue.
     1298 *
     1299 * @param[in]  mem_ctx  The talloc memory context to allocate the queue.
     1300 *
     1301 * @param[in]  name     The name to use to identify the queue.
     1302 *
     1303 * @return              An allocated tevent queue on success, NULL on error.
     1304 *
     1305 * @see tevent_start()
     1306 * @see tevent_stop()
     1307 */
     1308struct tevent_queue *tevent_queue_create(TALLOC_CTX *mem_ctx,
     1309                                         const char *name);
     1310#else
    3241311struct tevent_queue *_tevent_queue_create(TALLOC_CTX *mem_ctx,
    3251312                                          const char *name,
     
    3281315#define tevent_queue_create(_mem_ctx, _name) \
    3291316        _tevent_queue_create((_mem_ctx), (_name), __location__)
    330 
     1317#endif
     1318
     1319/**
     1320 * @brief A callback trigger function run by the queue.
     1321 *
     1322 * @param[in]  req      The tevent request the trigger function is executed on.
     1323 *
     1324 * @param[in]  private_data The private data pointer specified by
     1325 *                          tevent_queue_add().
     1326 *
     1327 * @see tevent_queue_add()
     1328 */
    3311329typedef void (*tevent_queue_trigger_fn_t)(struct tevent_req *req,
    3321330                                          void *private_data);
     1331
     1332/**
     1333 * @brief Add a tevent request to the queue.
     1334 *
     1335 * @param[in]  queue    The queue to add the request.
     1336 *
     1337 * @param[in]  ev       The event handle to use for the request.
     1338 *
     1339 * @param[in]  req      The tevent request to add to the queue.
     1340 *
     1341 * @param[in]  trigger  The function triggered by the queue when the request
     1342 *                      is called.
     1343 *
     1344 * @param[in]  private_data The private data passed to the trigger function.
     1345 *
     1346 * @return              True if the request has been successfully added, false
     1347 *                      otherwise.
     1348 */
    3331349bool tevent_queue_add(struct tevent_queue *queue,
    3341350                      struct tevent_context *ev,
     
    3361352                      tevent_queue_trigger_fn_t trigger,
    3371353                      void *private_data);
     1354
     1355/**
     1356 * @brief Start a tevent queue.
     1357 *
     1358 * The queue is started by default.
     1359 *
     1360 * @param[in]  queue    The queue to start.
     1361 */
    3381362void tevent_queue_start(struct tevent_queue *queue);
     1363
     1364/**
     1365 * @brief Stop a tevent queue.
     1366 *
     1367 * The queue is started by default.
     1368 *
     1369 * @param[in]  queue    The queue to stop.
     1370 */
    3391371void tevent_queue_stop(struct tevent_queue *queue);
    3401372
     1373/**
     1374 * @brief Get the length of the queue.
     1375 *
     1376 * @param[in]  queue    The queue to get the length from.
     1377 *
     1378 * @return              The number of elements.
     1379 */
    3411380size_t tevent_queue_length(struct tevent_queue *queue);
    3421381
     
    3671406#endif
    3681407
    369 
    370 /**
     1408int tevent_re_initialise(struct tevent_context *ev);
     1409
     1410/* @} */
     1411
     1412/**
     1413 * @defgroup tevent_ops The tevent operation functions
     1414 * @ingroup tevent
     1415 *
    3711416 * The following structure and registration functions are exclusively
    3721417 * needed for people writing and pluggin a different event engine.
    3731418 * There is nothing useful for normal tevent user in here.
     1419 * @{
    3741420 */
    3751421
     
    4241470bool tevent_register_backend(const char *name, const struct tevent_ops *ops);
    4251471
    426 
    427 /**
     1472/* @} */
     1473
     1474/**
     1475 * @defgroup tevent_compat The tevent compatibility functions
     1476 * @ingroup tevent
     1477 *
    4281478 * The following definitions are usueful only for compatibility with the
    4291479 * implementation originally developed within the samba4 code and will be
    4301480 * soon removed. Please NEVER use in new code.
     1481 *
     1482 * @todo Ignore it?
     1483 *
     1484 * @{
    4311485 */
    4321486
     
    5051559#endif /* TEVENT_COMPAT_DEFINES */
    5061560
     1561/* @} */
     1562
    5071563#endif /* __TEVENT_H__ */
  • trunk/server/lib/tevent/tevent.pc.in

    r414 r745  
    99Requires: talloc
    1010Libs: -L${libdir} -ltevent
    11 Cflags: -I${includedir}
     11Cflags: @LIB_RPATH@ -I${includedir}
    1212URL: http://samba.org/
  • trunk/server/lib/tevent/tevent_epoll.c

    r414 r745  
    4343
    4444/*
    45   called when a epoll call fails, and we should fallback
    46   to using select
     45  called when a epoll call fails
    4746*/
    4847static void epoll_panic(struct epoll_event_context *epoll_ev, const char *reason)
     
    438437};
    439438
    440 bool tevent_epoll_init(void)
     439_PRIVATE_ bool tevent_epoll_init(void)
    441440{
    442441        return tevent_register_backend("epoll", &epoll_event_ops);
  • trunk/server/lib/tevent/tevent_fd.c

    r414 r745  
    5252        struct tevent_fd *fde;
    5353
     54        /* tevent will crash later on select() if we save
     55         * a negative file descriptor. Better to fail here
     56         * so that consumers will be able to debug it
     57         */
     58        if (fd < 0) return NULL;
     59
    5460        fde = talloc(mem_ctx?mem_ctx:ev, struct tevent_fd);
    5561        if (!fde) return NULL;
  • trunk/server/lib/tevent/tevent_internal.h

    r429 r745  
    163163        const char *location;
    164164        /* this is private for the events_ops implementation */
    165         uint16_t additional_flags;
     165        uint64_t additional_flags;
    166166        void *additional_data;
    167167};
     
    304304bool tevent_standard_init(void);
    305305bool tevent_select_init(void);
     306bool tevent_poll_init(void);
    306307#ifdef HAVE_EPOLL
    307308bool tevent_epoll_init(void);
  • trunk/server/lib/tevent/tevent_liboop.c

    r414 r745  
    3232 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    3333
    34  NOTE: this code compiles fine, but is completly *UNTESTED*
    35        and is only commited as example
     34 NOTE: this code compiles fine, but is completely *UNTESTED*
     35       and is only committed as an example
    3636
    3737 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!   
  • trunk/server/lib/tevent/tevent_req.c

    r414 r745  
    2727#include "tevent_internal.h"
    2828#include "tevent_util.h"
    29 
    30 /**
    31  * @brief The default print function for creating debug messages
    32  * @param[in] req       The request to be printed
    33  * @param[in] mem_ctx   The memory context for the result
    34  * @retval              Text representation of req
    35  *
    36  * The function should not be used by users of the asynx API,
    37  * but custom print function can use it and append custom text
    38  * to the string.
    39  */
    4029
    4130char *tevent_req_default_print(struct tevent_req *req, TALLOC_CTX *mem_ctx)
     
    5443}
    5544
    56 /**
    57  * @brief Print an tevent_req structure in debug messages
    58  * @param[in] mem_ctx   The memory context for the result
    59  * @param[in] req       The request to be printed
    60  * @retval              Text representation of req
    61  *
    62  * This function should be used by callers of the async API
    63  */
    64 
    6545char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req)
    6646{
     
    7151        return req->private_print(req, mem_ctx);
    7252}
    73 
    74 /**
    75  * @brief Create an async request
    76  * @param[in] mem_ctx   The memory context for the result
    77  * @param[in] ev        The event context this async request will be driven by
    78  * @retval              A new async request
    79  *
    80  * The new async request will be initialized in state ASYNC_REQ_IN_PROGRESS
    81  */
    8253
    8354struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx,
     
    134105}
    135106
    136 /**
    137  * @brief An async request has successfully finished
    138  * @param[in] req       The finished request
    139  *
    140  * tevent_req_done is to be used by implementors of async requests. When a
    141  * request is successfully finished, this function calls the user's completion
    142  * function.
    143  */
    144 
    145107void _tevent_req_done(struct tevent_req *req,
    146108                      const char *location)
     
    148110        tevent_req_finish(req, TEVENT_REQ_DONE, location);
    149111}
    150 
    151 /**
    152  * @brief An async request has seen an error
    153  * @param[in] req       The request with an error
    154  * @param[in] error     The error code
    155  *
    156  * tevent_req_done is to be used by implementors of async requests. When a
    157  * request can not successfully completed, the implementation should call this
    158  * function with the appropriate status code.
    159  *
    160  * If error is 0 the function returns false and does nothing more.
    161  *
    162  * Call pattern would be
    163  * \code
    164  * int error = first_function();
    165  * if (tevent_req_error(req, error)) {
    166  *      return;
    167  * }
    168  *
    169  * error = second_function();
    170  * if (tevent_req_error(req, error)) {
    171  *      return;
    172  * }
    173  *
    174  * tevent_req_done(req);
    175  * return;
    176  * \endcode
    177  */
    178112
    179113bool _tevent_req_error(struct tevent_req *req,
     
    190124}
    191125
    192 /**
    193  * @brief Helper function for nomem check
    194  * @param[in] p         The pointer to be checked
    195  * @param[in] req       The request being processed
    196  *
    197  * Convenience helper to easily check alloc failure within a callback
    198  * implementing the next step of an async request.
    199  *
    200  * Call pattern would be
    201  * \code
    202  * p = talloc(mem_ctx, bla);
    203  * if (tevent_req_nomem(p, req)) {
    204  *      return;
    205  * }
    206  * \endcode
    207  */
    208 
    209126bool _tevent_req_nomem(const void *p,
    210127                       struct tevent_req *req,
     
    219136
    220137/**
    221  * @brief Immediate event callback
    222  * @param[in] ev        Event context
    223  * @param[in] im        The immediate event
    224  * @param[in] priv      The async request to be finished
     138 * @internal
     139 *
     140 * @brief Immediate event callback.
     141 *
     142 * @param[in]  ev       The event context to use.
     143 *
     144 * @param[in]  im       The immediate event.
     145 *
     146 * @param[in]  priv     The async request to be finished.
    225147 */
    226148static void tevent_req_trigger(struct tevent_context *ev,
     
    235157}
    236158
    237 /**
    238  * @brief Finish a request before the caller had the change to set the callback
    239  * @param[in] req       The finished request
    240  * @param[in] ev        The tevent_context for the timed event
    241  * @retval              req will be returned
    242  *
    243  * An implementation of an async request might find that it can either finish
    244  * the request without waiting for an external event, or it can't even start
    245  * the engine. To present the illusion of a callback to the user of the API,
    246  * the implementation can call this helper function which triggers an
    247  * immediate timed event. This way the caller can use the same calling
    248  * conventions, independent of whether the request was actually deferred.
    249  */
    250 
    251159struct tevent_req *tevent_req_post(struct tevent_req *req,
    252160                                   struct tevent_context *ev)
     
    257165}
    258166
    259 /**
    260  * @brief This function destroys the attached private data
    261  * @param[in] req       The request to poll
    262  * @retval              The boolean form of "is in progress".
    263  *
    264  * This function can be used to ask if the given request
    265  * is still in progress.
    266  *
    267  * This function is typically used by sync wrapper functions.
    268  */
    269167bool tevent_req_is_in_progress(struct tevent_req *req)
    270168{
     
    276174}
    277175
    278 /**
    279  * @brief This function destroys the attached private data
    280  * @param[in] req       The finished request
    281  *
    282  * This function can be called as last action of a _recv()
    283  * function, it destroys the data attached to the tevent_req.
    284  */
    285176void tevent_req_received(struct tevent_req *req)
    286177{
     
    294185}
    295186
    296 /**
    297  * @brief This function destroys the attached private data
    298  * @param[in] req       The request to poll
    299  * @param[in] ev        The tevent_context to be used
    300  * @retval              If a critical error has happened in the
    301  *                      tevent loop layer false is returned.
    302  *                      Otherwise true is returned.
    303  *                      This is not the return value of the given request!
    304  *
    305  * This function can be used to actively poll for the
    306  * given request to finish.
    307  *
    308  * Note: this should only be used if the given tevent context
    309  *       was created by the caller, to avoid event loop nesting.
    310  *
    311  * This function is typically used by sync wrapper functions.
    312  */
    313187bool tevent_req_poll(struct tevent_req *req,
    314188                     struct tevent_context *ev)
     
    384258}
    385259
    386 /**
    387  * @brief This function sets a print function for the given request
    388  * @param[in] req       The given request
    389  * @param[in] fn        A pointer to the print function
    390  *
    391  * This function can be used to setup a print function for the given request.
    392  * This will be triggered if the tevent_req_print() function was
    393  * called on the given request.
    394  *
    395  * Note: this function should only be used for debugging.
    396  */
    397260void tevent_req_set_print_fn(struct tevent_req *req, tevent_req_print_fn fn)
    398261{
     
    400263}
    401264
    402 /**
    403  * @brief This function sets a cancel function for the given request
    404  * @param[in] req       The given request
    405  * @param[in] fn        A pointer to the cancel function
    406  *
    407  * This function can be used to setup a cancel function for the given request.
    408  * This will be triggered if the tevent_req_cancel() function was
    409  * called on the given request.
    410  *
    411  */
    412265void tevent_req_set_cancel_fn(struct tevent_req *req, tevent_req_cancel_fn fn)
    413266{
     
    415268}
    416269
    417 /**
    418  * @brief This function tries to cancel the given request
    419  * @param[in] req       The given request
    420  * @param[in] location  Automaticly filled with the __location__ macro
    421  *                      via the tevent_req_cancel() macro. This is for debugging
    422  *                      only!
    423  * @retval              This function returns true is the request is cancelable.
    424  *                      Otherwise false is returned.
    425  *
    426  * This function can be used to cancel the given request.
    427  *
    428  * It is only possible to cancel a request when the implementation
    429  * has registered a cancel function via the tevent_req_set_cancel_fn().
    430  *
    431  * Note: Even if the function returns true, the caller need to wait
    432  *       for the function to complete normally.
    433  *       Only the _recv() function of the given request indicates
    434  *       if the request was really canceled.
    435  */
    436270bool _tevent_req_cancel(struct tevent_req *req, const char *location)
    437271{
  • trunk/server/lib/tevent/tevent_select.c

    r593 r745  
    122122        if (!fde) return NULL;
    123123
    124         if (fde->fd > select_ev->maxfd) {
     124        if ((select_ev->maxfd != EVENT_INVALID_MAXFD)
     125            && (fde->fd > select_ev->maxfd)) {
    125126                select_ev->maxfd = fde->fd;
    126127        }
     
    252253};
    253254
    254 bool tevent_select_init(void)
     255_PRIVATE_ bool tevent_select_init(void)
    255256{
    256257        return tevent_register_backend("select", &select_event_ops);
  • trunk/server/lib/tevent/tevent_signal.c

    r664 r745  
    214214           multiple event contexts */
    215215        if (sig_state == NULL) {
    216                 sig_state = talloc_zero(talloc_autofree_context(), struct tevent_sig_state);
     216                sig_state = talloc_zero(NULL, struct tevent_sig_state);
    217217                if (sig_state == NULL) {
    218218                        return NULL;
  • trunk/server/lib/tevent/tevent_standard.c

    r593 r745  
    462462                        return -1;
    463463                }
    464 
    465464                if (fde->flags & TEVENT_FD_READ) {
    466465                        FD_SET(fde->fd, &r_fds);
     
    511510                        if (FD_ISSET(fde->fd, &r_fds)) flags |= TEVENT_FD_READ;
    512511                        if (FD_ISSET(fde->fd, &w_fds)) flags |= TEVENT_FD_WRITE;
    513                         if (flags) {
     512                        if (flags & fde->flags) {
    514513                                fde->handler(std_ev->ev, fde, flags, fde->private_data);
    515514                                break;
     
    568567
    569568
    570 bool tevent_standard_init(void)
     569_PRIVATE_ bool tevent_standard_init(void)
    571570{
    572571        return tevent_register_backend("standard", &std_event_ops);
  • trunk/server/lib/tevent/tevent_timed.c

    r414 r745  
    198198  do a single event loop using the events defined in ev
    199199
    200   return the delay untill the next timed event,
     200  return the delay until the next timed event,
    201201  or zero if a timed event was triggered
    202202*/
     
    209209                /* have a default tick time of 30 seconds. This guarantees
    210210                   that code that uses its own timeout checking will be
    211                    able to proceeed eventually */
     211                   able to proceed eventually */
    212212                return tevent_timeval_set(30, 0);
    213213        }
  • trunk/server/lib/tevent/tevent_util.h

    r414 r745  
    22   Unix SMB/CIFS implementation.
    33
    4    Copyright (C) Andrew Tridgell 1998-2005
     4   Copyright (C) Andrew Tridgell 1998-2010
    55   Copyright (C) Jelmer Vernooij 2005
    66
     
    2525#define _DLINKLIST_H
    2626
     27/*
     28  February 2010 - changed list format to have a prev pointer from the
     29  list head. This makes DLIST_ADD_END() O(1) even though we only have
     30  one list pointer.
    2731
    28 /* hook into the front of the list */
     32  The scheme is as follows:
     33
     34     1) with no entries in the list:
     35          list_head == NULL
     36
     37     2) with 1 entry in the list:
     38          list_head->next == NULL
     39          list_head->prev == list_head
     40
     41     3) with 2 entries in the list:
     42          list_head->next == element2
     43          list_head->prev == element2
     44          element2->prev == list_head
     45          element2->next == NULL
     46
     47     4) with N entries in the list:
     48          list_head->next == element2
     49          list_head->prev == elementN
     50          elementN->prev == element{N-1}
     51          elementN->next == NULL
     52
     53  This allows us to find the tail of the list by using
     54  list_head->prev, which means we can add to the end of the list in
     55  O(1) time
     56
     57
     58  Note that the 'type' arguments below are no longer needed, but
     59  are kept for now to prevent an incompatible argument change
     60 */
     61
     62
     63/*
     64   add an element at the front of a list
     65*/
    2966#define DLIST_ADD(list, p) \
    3067do { \
    3168        if (!(list)) { \
    32                 (list) = (p); \
    33                 (p)->next = (p)->prev = NULL; \
     69                (p)->prev = (list) = (p); \
     70                (p)->next = NULL; \
    3471        } else { \
     72                (p)->prev = (list)->prev; \
    3573                (list)->prev = (p); \
    3674                (p)->next = (list); \
    37                 (p)->prev = NULL; \
    3875                (list) = (p); \
    39         }\
     76        } \
    4077} while (0)
    4178
    42 /* remove an element from a list - element doesn't have to be in list. */
     79/*
     80   remove an element from a list
     81   Note that the element doesn't have to be in the list. If it
     82   isn't then this is a no-op
     83*/
    4384#define DLIST_REMOVE(list, p) \
    4485do { \
    4586        if ((p) == (list)) { \
     87                if ((p)->next) (p)->next->prev = (p)->prev; \
    4688                (list) = (p)->next; \
    47                 if (list) (list)->prev = NULL; \
     89        } else if ((list) && (p) == (list)->prev) {     \
     90                (p)->prev->next = NULL; \
     91                (list)->prev = (p)->prev; \
    4892        } else { \
    4993                if ((p)->prev) (p)->prev->next = (p)->next; \
    5094                if ((p)->next) (p)->next->prev = (p)->prev; \
    5195        } \
    52         if ((p) != (list)) (p)->next = (p)->prev = NULL; \
     96        if ((p) != (list)) (p)->next = (p)->prev = NULL;        \
    5397} while (0)
    5498
    55 /* promote an element to the top of the list */
    56 #define DLIST_PROMOTE(list, p) \
     99/*
     100   find the head of the list given any element in it.
     101   Note that this costs O(N), so you should avoid this macro
     102   if at all possible!
     103*/
     104#define DLIST_HEAD(p, result_head) \
    57105do { \
    58           DLIST_REMOVE(list, p); \
    59           DLIST_ADD(list, p); \
    60 } while (0)
     106       (result_head) = (p); \
     107       while (DLIST_PREV(result_head)) (result_head) = (result_head)->prev; \
     108} while(0)
    61109
    62 /* hook into the end of the list - needs a tmp pointer */
    63 #define DLIST_ADD_END(list, p, type) \
    64 do { \
    65                 if (!(list)) { \
    66                         (list) = (p); \
    67                         (p)->next = (p)->prev = NULL; \
    68                 } else { \
    69                         type tmp; \
    70                         for (tmp = (list); tmp->next; tmp = tmp->next) ; \
    71                         tmp->next = (p); \
    72                         (p)->next = NULL; \
    73                         (p)->prev = tmp; \
    74                 } \
    75 } while (0)
     110/* return the last element in the list */
     111#define DLIST_TAIL(list) ((list)?(list)->prev:NULL)
     112
     113/* return the previous element in the list. */
     114#define DLIST_PREV(p) (((p)->prev && (p)->prev->next != NULL)?(p)->prev:NULL)
    76115
    77116/* insert 'p' after the given element 'el' in a list. If el is NULL then
     
    82121                DLIST_ADD(list, p); \
    83122        } else { \
    84                 p->prev = el; \
    85                 p->next = el->next; \
    86                 el->next = p; \
    87                 if (p->next) p->next->prev = p; \
     123                (p)->prev = (el);   \
     124                (p)->next = (el)->next;         \
     125                (el)->next = (p);               \
     126                if ((p)->next) (p)->next->prev = (p);   \
     127                if ((list)->prev == (el)) (list)->prev = (p); \
    88128        }\
    89129} while (0)
    90130
    91 /* demote an element to the end of the list, needs a tmp pointer */
    92 #define DLIST_DEMOTE(list, p, tmp) \
     131
     132/*
     133   add to the end of a list.
     134   Note that 'type' is ignored
     135*/
     136#define DLIST_ADD_END(list, p, type)                    \
    93137do { \
    94                 DLIST_REMOVE(list, p); \
    95                 DLIST_ADD_END(list, p, tmp); \
     138        if (!(list)) { \
     139                DLIST_ADD(list, p); \
     140        } else { \
     141                DLIST_ADD_AFTER(list, p, (list)->prev); \
     142        } \
    96143} while (0)
    97144
    98 /* concatenate two lists - putting all elements of the 2nd list at the
    99    end of the first list */
    100 #define DLIST_CONCATENATE(list1, list2, type) \
     145/* promote an element to the from of a list */
     146#define DLIST_PROMOTE(list, p) \
    101147do { \
    102                 if (!(list1)) { \
    103                         (list1) = (list2); \
    104                 } else { \
    105                         type tmp; \
    106                         for (tmp = (list1); tmp->next; tmp = tmp->next) ; \
    107                         tmp->next = (list2); \
    108                         if (list2) { \
    109                                 (list2)->prev = tmp;    \
    110                         } \
     148          DLIST_REMOVE(list, p); \
     149          DLIST_ADD(list, p); \
     150} while (0)
     151
     152/*
     153   demote an element to the end of a list.
     154   Note that 'type' is ignored
     155*/
     156#define DLIST_DEMOTE(list, p, type)                     \
     157do { \
     158        DLIST_REMOVE(list, p); \
     159        DLIST_ADD_END(list, p, NULL);           \
     160} while (0)
     161
     162/*
     163   concatenate two lists - putting all elements of the 2nd list at the
     164   end of the first list.
     165   Note that 'type' is ignored
     166*/
     167#define DLIST_CONCATENATE(list1, list2, type)   \
     168do { \
     169        if (!(list1)) { \
     170                (list1) = (list2); \
     171        } else { \
     172                (list1)->prev->next = (list2); \
     173                if (list2) { \
     174                        void *_tmplist = (void *)(list1)->prev; \
     175                        (list1)->prev = (list2)->prev; \
     176                        (list2)->prev = _tmplist; \
    111177                } \
     178        } \
    112179} while (0)
    113180
Note: See TracChangeset for help on using the changeset viewer.