server: document wl_event_loop and wl_event_source
This documents all the public API related to wl_event_loop and wl_event_source objects. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Yong Bakos <ybakos@humanoriented.com> [Pekka: fixed typos pointed by Yong] [Pekka: fixed typos pointed by Christopher] Reviewed-By: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
This commit is contained in:
parent
b88ada0760
commit
3ea73cba04
|
@ -19,6 +19,7 @@ scanned_src_files_Client = \
|
|||
|
||||
scanned_src_files_Server = \
|
||||
$(scanned_src_files_shared) \
|
||||
$(top_srcdir)/src/event-loop.c \
|
||||
$(top_srcdir)/src/wayland-server.c \
|
||||
$(top_srcdir)/src/wayland-server.h \
|
||||
$(top_srcdir)/src/wayland-server-core.h \
|
||||
|
|
244
src/event-loop.c
244
src/event-loop.c
|
@ -42,6 +42,8 @@
|
|||
#include "wayland-server-core.h"
|
||||
#include "wayland-os.h"
|
||||
|
||||
/** \cond INTERNAL */
|
||||
|
||||
struct wl_event_loop {
|
||||
int epoll_fd;
|
||||
struct wl_list check_list;
|
||||
|
@ -70,6 +72,8 @@ struct wl_event_source_fd {
|
|||
int fd;
|
||||
};
|
||||
|
||||
/** \endcond */
|
||||
|
||||
static int
|
||||
wl_event_source_fd_dispatch(struct wl_event_source *source,
|
||||
struct epoll_event *ep)
|
||||
|
@ -125,6 +129,30 @@ add_source(struct wl_event_loop *loop,
|
|||
return source;
|
||||
}
|
||||
|
||||
/** Create a file descriptor event source
|
||||
*
|
||||
* \param loop The event loop that will process the new source.
|
||||
* \param fd The file descriptor to watch.
|
||||
* \param mask A bitwise-or of which events to watch for: \c WL_EVENT_READABLE,
|
||||
* \c WL_EVENT_WRITABLE.
|
||||
* \param func The file descriptor dispatch function.
|
||||
* \param data User data.
|
||||
* \return A new file descriptor event source.
|
||||
*
|
||||
* The given file descriptor is initially watched for the events given in
|
||||
* \c mask. This can be changed as needed with wl_event_source_fd_update().
|
||||
*
|
||||
* If it is possible that program execution causes the file descriptor to be
|
||||
* read while leaving the data in a buffer without actually processing it,
|
||||
* it may be necessary to register the file descriptor source to be re-checked,
|
||||
* see wl_event_source_check(). This will ensure that the dispatch function
|
||||
* gets called even if the file descriptor is not readable or writable
|
||||
* anymore. This is especially useful with IPC libraries that automatically
|
||||
* buffer incoming data, possibly as a side-effect of other operations.
|
||||
*
|
||||
* \sa wl_event_loop_fd_func_t
|
||||
* \memberof wl_event_source
|
||||
*/
|
||||
WL_EXPORT struct wl_event_source *
|
||||
wl_event_loop_add_fd(struct wl_event_loop *loop,
|
||||
int fd, uint32_t mask,
|
||||
|
@ -145,6 +173,26 @@ wl_event_loop_add_fd(struct wl_event_loop *loop,
|
|||
return add_source(loop, &source->base, mask, data);
|
||||
}
|
||||
|
||||
/** Update a file descriptor source's event mask
|
||||
*
|
||||
* \param source The file descriptor event source to update.
|
||||
* \param mask The new mask, a bitwise-or of: \c WL_EVENT_READABLE,
|
||||
* \c WL_EVENT_WRITABLE.
|
||||
* \return 0 on success, -1 on failure.
|
||||
*
|
||||
* This changes which events, readable and/or writable, cause the dispatch
|
||||
* callback to be called on.
|
||||
*
|
||||
* File descriptors are usually writable to begin with, so they do not need to
|
||||
* be polled for writable until a write actually fails. When a write fails,
|
||||
* the event mask can be changed to poll for readable and writable, delivering
|
||||
* a dispatch callback when it is possible to write more. Once all data has
|
||||
* been written, the mask can be changed to poll only for readable to avoid
|
||||
* busy-looping on dispatch.
|
||||
*
|
||||
* \sa wl_event_loop_add_fd()
|
||||
* \memberof wl_event_source
|
||||
*/
|
||||
WL_EXPORT int
|
||||
wl_event_source_fd_update(struct wl_event_source *source, uint32_t mask)
|
||||
{
|
||||
|
@ -161,11 +209,15 @@ wl_event_source_fd_update(struct wl_event_source *source, uint32_t mask)
|
|||
return epoll_ctl(loop->epoll_fd, EPOLL_CTL_MOD, source->fd, &ep);
|
||||
}
|
||||
|
||||
/** \cond INTERNAL */
|
||||
|
||||
struct wl_event_source_timer {
|
||||
struct wl_event_source base;
|
||||
wl_event_loop_timer_func_t func;
|
||||
};
|
||||
|
||||
/** \endcond */
|
||||
|
||||
static int
|
||||
wl_event_source_timer_dispatch(struct wl_event_source *source,
|
||||
struct epoll_event *ep)
|
||||
|
@ -187,6 +239,19 @@ struct wl_event_source_interface timer_source_interface = {
|
|||
wl_event_source_timer_dispatch,
|
||||
};
|
||||
|
||||
/** Create a timer event source
|
||||
*
|
||||
* \param loop The event loop that will process the new source.
|
||||
* \param func The timer dispatch function.
|
||||
* \param data User data.
|
||||
* \return A new timer event source.
|
||||
*
|
||||
* The timer is initially disarmed. It needs to be armed with a call to
|
||||
* wl_event_source_timer_update() before it can trigger a dispatch call.
|
||||
*
|
||||
* \sa wl_event_loop_timer_func_t
|
||||
* \memberof wl_event_source
|
||||
*/
|
||||
WL_EXPORT struct wl_event_source *
|
||||
wl_event_loop_add_timer(struct wl_event_loop *loop,
|
||||
wl_event_loop_timer_func_t func,
|
||||
|
@ -206,6 +271,22 @@ wl_event_loop_add_timer(struct wl_event_loop *loop,
|
|||
return add_source(loop, &source->base, WL_EVENT_READABLE, data);
|
||||
}
|
||||
|
||||
/** Arm or disarm a timer
|
||||
*
|
||||
* \param source The timer event source to modify.
|
||||
* \param ms_delay The timeout in milliseconds.
|
||||
* \return 0 on success, -1 on failure.
|
||||
*
|
||||
* If the timeout is zero, the timer is disarmed.
|
||||
*
|
||||
* If the timeout is non-zero, the timer is set to expire after the given
|
||||
* timeout in milliseconds. When the timer expires, the dispatch function
|
||||
* set with wl_event_loop_add_timer() is called once from
|
||||
* wl_event_loop_dispatch(). If another dispatch is desired after another
|
||||
* expiry, wl_event_source_timer_update() needs to be called again.
|
||||
*
|
||||
* \memberof wl_event_source
|
||||
*/
|
||||
WL_EXPORT int
|
||||
wl_event_source_timer_update(struct wl_event_source *source, int ms_delay)
|
||||
{
|
||||
|
@ -221,12 +302,16 @@ wl_event_source_timer_update(struct wl_event_source *source, int ms_delay)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/** \cond INTERNAL */
|
||||
|
||||
struct wl_event_source_signal {
|
||||
struct wl_event_source base;
|
||||
int signal_number;
|
||||
wl_event_loop_signal_func_t func;
|
||||
};
|
||||
|
||||
/** \endcond */
|
||||
|
||||
static int
|
||||
wl_event_source_signal_dispatch(struct wl_event_source *source,
|
||||
struct epoll_event *ep)
|
||||
|
@ -249,6 +334,25 @@ struct wl_event_source_interface signal_source_interface = {
|
|||
wl_event_source_signal_dispatch,
|
||||
};
|
||||
|
||||
/** Create a POSIX signal event source
|
||||
*
|
||||
* \param loop The event loop that will process the new source.
|
||||
* \param signal_number Number of the signal to watch for.
|
||||
* \param func The signal dispatch function.
|
||||
* \param data User data.
|
||||
* \return A new signal event source.
|
||||
*
|
||||
* This function blocks the normal delivery of the given signal in the calling
|
||||
* thread, and creates a "watch" for it. Signal delivery no longer happens
|
||||
* asynchronously, but by wl_event_loop_dispatch() calling the dispatch
|
||||
* callback function \c func.
|
||||
*
|
||||
* It is the caller's responsibility to ensure that all other threads have
|
||||
* also blocked the signal.
|
||||
*
|
||||
* \sa wl_event_loop_signal_func_t
|
||||
* \memberof wl_event_source
|
||||
*/
|
||||
WL_EXPORT struct wl_event_source *
|
||||
wl_event_loop_add_signal(struct wl_event_loop *loop,
|
||||
int signal_number,
|
||||
|
@ -275,15 +379,39 @@ wl_event_loop_add_signal(struct wl_event_loop *loop,
|
|||
return add_source(loop, &source->base, WL_EVENT_READABLE, data);
|
||||
}
|
||||
|
||||
/** \cond INTERNAL */
|
||||
|
||||
struct wl_event_source_idle {
|
||||
struct wl_event_source base;
|
||||
wl_event_loop_idle_func_t func;
|
||||
};
|
||||
|
||||
/** \endcond */
|
||||
|
||||
struct wl_event_source_interface idle_source_interface = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
/** Create an idle task
|
||||
*
|
||||
* \param loop The event loop that will process the new task.
|
||||
* \param func The idle task dispatch function.
|
||||
* \param data User data.
|
||||
* \return A new idle task (an event source).
|
||||
*
|
||||
* Idle tasks are dispatched before wl_event_loop_dispatch() goes to sleep.
|
||||
* See wl_event_loop_dispatch() for more details.
|
||||
*
|
||||
* Idle tasks fire once, and are automatically destroyed right after the
|
||||
* callback function has been called.
|
||||
*
|
||||
* An idle task can be cancelled before the callback has been called by
|
||||
* wl_event_source_remove(). Calling wl_event_source_remove() after or from
|
||||
* within the callback results in undefined behaviour.
|
||||
*
|
||||
* \sa wl_event_loop_idle_func_t
|
||||
* \memberof wl_event_source
|
||||
*/
|
||||
WL_EXPORT struct wl_event_source *
|
||||
wl_event_loop_add_idle(struct wl_event_loop *loop,
|
||||
wl_event_loop_idle_func_t func,
|
||||
|
@ -307,12 +435,40 @@ wl_event_loop_add_idle(struct wl_event_loop *loop,
|
|||
return &source->base;
|
||||
}
|
||||
|
||||
/** Mark event source to be re-checked
|
||||
*
|
||||
* \param source The event source to be re-checked.
|
||||
*
|
||||
* This function permanently marks the event source to be re-checked after
|
||||
* the normal dispatch of sources in wl_event_loop_dispatch(). Re-checking
|
||||
* will keep iterating over all such event sources until the dispatch
|
||||
* function for them all returns zero.
|
||||
*
|
||||
* Re-checking is used on sources that may become ready to dispatch as a
|
||||
* side-effect of dispatching themselves or other event sources, including idle
|
||||
* sources. Re-checking ensures all the incoming events have been fully drained
|
||||
* before wl_event_loop_dispatch() returns.
|
||||
*
|
||||
* \memberof wl_event_source
|
||||
*/
|
||||
WL_EXPORT void
|
||||
wl_event_source_check(struct wl_event_source *source)
|
||||
{
|
||||
wl_list_insert(source->loop->check_list.prev, &source->link);
|
||||
}
|
||||
|
||||
/** Remove an event source from its event loop
|
||||
*
|
||||
* \param source The event source to be removed.
|
||||
* \return Zero.
|
||||
*
|
||||
* The event source is removed from the event loop it was created for,
|
||||
* and is effectively destroyed. This invalidates \c source .
|
||||
* The dispatch function of the source will no longer be called through this
|
||||
* source.
|
||||
*
|
||||
* \memberof wl_event_source
|
||||
*/
|
||||
WL_EXPORT int
|
||||
wl_event_source_remove(struct wl_event_source *source)
|
||||
{
|
||||
|
@ -343,6 +499,20 @@ wl_event_loop_process_destroy_list(struct wl_event_loop *loop)
|
|||
wl_list_init(&loop->destroy_list);
|
||||
}
|
||||
|
||||
/** Create a new event loop context
|
||||
*
|
||||
* \return A new event loop context object.
|
||||
*
|
||||
* This creates a new event loop context. Initially this context is empty.
|
||||
* Event sources need to be explicitly added to it.
|
||||
*
|
||||
* Normally the event loop is run by calling wl_event_loop_dispatch() in
|
||||
* a loop until the program terminates. Alternatively, an event loop can be
|
||||
* embedded in another event loop by its file descriptor, see
|
||||
* wl_event_loop_get_fd().
|
||||
*
|
||||
* \memberof wl_event_loop
|
||||
*/
|
||||
WL_EXPORT struct wl_event_loop *
|
||||
wl_event_loop_create(void)
|
||||
{
|
||||
|
@ -366,6 +536,19 @@ wl_event_loop_create(void)
|
|||
return loop;
|
||||
}
|
||||
|
||||
/** Destroy an event loop context
|
||||
*
|
||||
* \param loop The event loop to be destroyed.
|
||||
*
|
||||
* This emits the event loop destroy signal, closes the event loop file
|
||||
* descriptor, and frees \c loop.
|
||||
*
|
||||
* If the event loop has existing sources, those cannot be safely removed
|
||||
* afterwards. Therefore one must call wl_event_source_remove() on all
|
||||
* event sources before destroying the event loop context.
|
||||
*
|
||||
* \memberof wl_event_loop
|
||||
*/
|
||||
WL_EXPORT void
|
||||
wl_event_loop_destroy(struct wl_event_loop *loop)
|
||||
{
|
||||
|
@ -391,6 +574,13 @@ post_dispatch_check(struct wl_event_loop *loop)
|
|||
return n;
|
||||
}
|
||||
|
||||
/** Dispatch the idle sources
|
||||
*
|
||||
* \param loop The event loop whose idle sources are dispatched.
|
||||
*
|
||||
* \sa wl_event_loop_add_idle()
|
||||
* \memberof wl_event_loop
|
||||
*/
|
||||
WL_EXPORT void
|
||||
wl_event_loop_dispatch_idle(struct wl_event_loop *loop)
|
||||
{
|
||||
|
@ -404,6 +594,26 @@ wl_event_loop_dispatch_idle(struct wl_event_loop *loop)
|
|||
}
|
||||
}
|
||||
|
||||
/** Wait for events and dispatch them
|
||||
*
|
||||
* \param loop The event loop whose sources to wait for.
|
||||
* \param timeout The polling timeout in milliseconds.
|
||||
* \return 0 for success, -1 for polling error.
|
||||
*
|
||||
* All the associated event sources are polled. This function blocks until
|
||||
* any event source delivers an event (idle sources excluded), or the timeout
|
||||
* expires. A timeout of -1 disables the timeout, causing the function to block
|
||||
* indefinitely. A timeout of zero causes the poll to always return immediately.
|
||||
*
|
||||
* All idle sources are dispatched before blocking. An idle source is destroyed
|
||||
* when it is dispatched. After blocking, all other ready sources are
|
||||
* dispatched. Then, idle sources are dispatched again, in case the dispatched
|
||||
* events created idle sources. Finally, all sources marked with
|
||||
* wl_event_source_check() are dispatched in a loop until their dispatch
|
||||
* functions all return zero.
|
||||
*
|
||||
* \memberof wl_event_loop
|
||||
*/
|
||||
WL_EXPORT int
|
||||
wl_event_loop_dispatch(struct wl_event_loop *loop, int timeout)
|
||||
{
|
||||
|
@ -434,12 +644,36 @@ wl_event_loop_dispatch(struct wl_event_loop *loop, int timeout)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/** Get the event loop file descriptor
|
||||
*
|
||||
* \param loop The event loop context.
|
||||
* \return The aggregate file descriptor.
|
||||
*
|
||||
* This function returns the aggregate file descriptor, that represents all
|
||||
* the event sources (idle sources excluded) associated with the given event
|
||||
* loop context. When any event source makes an event available, it will be
|
||||
* reflected in the aggregate file descriptor.
|
||||
*
|
||||
* When the aggregate file descriptor delivers an event, one can call
|
||||
* wl_event_loop_dispatch() on the event loop context to dispatch all the
|
||||
* available events.
|
||||
*
|
||||
* \memberof wl_event_loop
|
||||
*/
|
||||
WL_EXPORT int
|
||||
wl_event_loop_get_fd(struct wl_event_loop *loop)
|
||||
{
|
||||
return loop->epoll_fd;
|
||||
}
|
||||
|
||||
/** Register a destroy listener for an event loop context
|
||||
*
|
||||
* \param loop The event loop context whose destruction to listen for.
|
||||
* \param listener The listener with the callback to be called.
|
||||
*
|
||||
* \sa wl_listener
|
||||
* \memberof wl_event_loop
|
||||
*/
|
||||
WL_EXPORT void
|
||||
wl_event_loop_add_destroy_listener(struct wl_event_loop *loop,
|
||||
struct wl_listener *listener)
|
||||
|
@ -447,10 +681,18 @@ wl_event_loop_add_destroy_listener(struct wl_event_loop *loop,
|
|||
wl_signal_add(&loop->destroy_signal, listener);
|
||||
}
|
||||
|
||||
/** Get the listener struct for the specified callback
|
||||
*
|
||||
* \param loop The event loop context to inspect.
|
||||
* \param notify The destroy callback to find.
|
||||
* \return The wl_listener registered to the event loop context with
|
||||
* the given callback pointer.
|
||||
*
|
||||
* \memberof wl_event_loop
|
||||
*/
|
||||
WL_EXPORT struct wl_listener *
|
||||
wl_event_loop_get_destroy_listener(struct wl_event_loop *loop,
|
||||
wl_notify_func_t notify)
|
||||
{
|
||||
return wl_signal_get(&loop->destroy_signal, notify);
|
||||
}
|
||||
|
||||
|
|
|
@ -43,11 +43,88 @@ enum {
|
|||
WL_EVENT_ERROR = 0x08
|
||||
};
|
||||
|
||||
/** File descriptor dispatch function type
|
||||
*
|
||||
* Functions of this type are used as callbacks for file descriptor events.
|
||||
*
|
||||
* \param fd The file descriptor delivering the event.
|
||||
* \param mask Describes the kind of the event as a bitwise-or of:
|
||||
* \c WL_EVENT_READABLE, \c WL_EVENT_WRITABLE, \c WL_EVENT_HANGUP,
|
||||
* \c WL_EVENT_ERROR.
|
||||
* \param data The user data argument of the related wl_event_loop_add_fd()
|
||||
* call.
|
||||
* \return If the event source is registered for re-check with
|
||||
* wl_event_source_check(): 0 for all done, 1 for needing a re-check.
|
||||
* If not registered, the return value is ignored and should be zero.
|
||||
*
|
||||
* \sa wl_event_loop_add_fd()
|
||||
* \memberof wl_event_source
|
||||
*/
|
||||
typedef int (*wl_event_loop_fd_func_t)(int fd, uint32_t mask, void *data);
|
||||
|
||||
/** Timer dispatch function type
|
||||
*
|
||||
* Functions of this type are used as callbacks for timer expiry.
|
||||
*
|
||||
* \param data The user data argument of the related wl_event_loop_add_timer()
|
||||
* call.
|
||||
* \return If the event source is registered for re-check with
|
||||
* wl_event_source_check(): 0 for all done, 1 for needing a re-check.
|
||||
* If not registered, the return value is ignored and should be zero.
|
||||
*
|
||||
* \sa wl_event_loop_add_timer()
|
||||
* \memberof wl_event_source
|
||||
*/
|
||||
typedef int (*wl_event_loop_timer_func_t)(void *data);
|
||||
|
||||
/** Signal dispatch function type
|
||||
*
|
||||
* Functions of this type are used as callbacks for (POSIX) signals.
|
||||
*
|
||||
* \param signal_number
|
||||
* \param data The user data argument of the related wl_event_loop_add_signal()
|
||||
* call.
|
||||
* \return If the event source is registered for re-check with
|
||||
* wl_event_source_check(): 0 for all done, 1 for needing a re-check.
|
||||
* If not registered, the return value is ignored and should be zero.
|
||||
*
|
||||
* \sa wl_event_loop_add_signal()
|
||||
* \memberof wl_event_source
|
||||
*/
|
||||
typedef int (*wl_event_loop_signal_func_t)(int signal_number, void *data);
|
||||
|
||||
/** Idle task function type
|
||||
*
|
||||
* Functions of this type are used as callbacks before blocking in
|
||||
* wl_event_loop_dispatch().
|
||||
*
|
||||
* \param data The user data argument of the related wl_event_loop_add_idle()
|
||||
* call.
|
||||
*
|
||||
* \sa wl_event_loop_add_idle() wl_event_loop_dispatch()
|
||||
* \memberof wl_event_source
|
||||
*/
|
||||
typedef void (*wl_event_loop_idle_func_t)(void *data);
|
||||
|
||||
/** \struct wl_event_loop
|
||||
*
|
||||
* \brief An event loop context
|
||||
*
|
||||
* Usually you create an event loop context, add sources to it, and call
|
||||
* wl_event_loop_dispatch() in a loop to process events.
|
||||
*
|
||||
* \sa wl_event_source
|
||||
*/
|
||||
|
||||
/** \struct wl_event_source
|
||||
*
|
||||
* \brief An abstract event source
|
||||
*
|
||||
* This is the generic type for fd, timer, signal, and idle sources.
|
||||
* Functions that operate on specific source types must not be used with
|
||||
* a different type, even if the function signature allows it.
|
||||
*/
|
||||
|
||||
struct wl_event_loop *
|
||||
wl_event_loop_create(void);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user