1353 lines
35 KiB
C
1353 lines
35 KiB
C
/* -*- C -*- */
|
|
|
|
/**@MODULEPAGE "su" - OS Services and Utilities
|
|
*
|
|
* @section su_meta Module Information
|
|
*
|
|
* The @b su module contains a simple, portable socket/timing/synchronizing
|
|
* library developed for Sofia communications software.
|
|
*
|
|
* @CONTACT Pekka Pessi <Pekka.Pessi@nokia.com>
|
|
*
|
|
* @STATUS @SofiaSIP Core library
|
|
*
|
|
* @LICENSE LGPL
|
|
*
|
|
* @section su_overview Overview
|
|
*
|
|
* The @b su module provides following interfaces for application programs:
|
|
*
|
|
* - su_types.h - integral types
|
|
* - su.h - @ref su_socket
|
|
* - su_localinfo.h - get list of local IP addresses
|
|
* - su_wait.h - @ref su_wait
|
|
* - su_time.h - @ref su_time
|
|
* - su_alloc.h - @ref su_alloc
|
|
* - su_log.h - @ref su_log
|
|
* - su_tag.h - @ref su_tag
|
|
* - su_md5.h - @ref su_md5
|
|
* - su_uniqueid.h - @ref su_uniqueid
|
|
*
|
|
* The @b su library also contains some collection datatypes:
|
|
* - htable.h - @ref su_htable
|
|
* - rbtree.h - balanced red-black trees
|
|
* - su_strlst.h - @ref su_strlst
|
|
* - su_vector.h - @ref su_vector
|
|
*
|
|
* There are also some convenience macros for unit test programs:
|
|
* - tstdef.h - macros for unit tests
|
|
*
|
|
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
|
|
* @author Jari Selin <Jari.Selin@nokia.com>
|
|
*
|
|
* @par SU Debug Log
|
|
*
|
|
* The debugging output from @b su module is controlled by #su_log_global
|
|
* log object. The environment variable #SU_DEBUG sets the default log
|
|
* level.
|
|
*/
|
|
|
|
/**@maindefgroup su OS Utilities
|
|
*
|
|
* The "su" module contains OS utilies for Sofia.
|
|
*
|
|
* The @b su is a simple, portable socket/timing/synchronizing library
|
|
* developed for Sofia communications software. Currently, interface to
|
|
* it consists of following parts:
|
|
*
|
|
* - <a href=su_types_h.html>su_types</a> - basic integer types
|
|
* - <a href=group_su_socket.html>su_socket</a> - socket functions
|
|
* - <a href=group_su_wait.html>su_wait</a> - synchronization functions
|
|
* - <a href=group_su_time.html>su_time</a> - time functions
|
|
* - <a href=group_su_alloc.html>su_alloc</a> - memory management functions
|
|
* - <a href=group_su_log.html>su_log</a> - generic logging functions
|
|
* - <a href=group_su_tag.html>su_tag</a> - tag list function
|
|
* - <a href=group_su_md5.html>su_md5</a> - MD5 hashing
|
|
*/
|
|
|
|
/**@defgroup su_programs Shell Programs
|
|
*
|
|
* The @b su module provides few shell utilities:
|
|
* - @ref localinfo (localinfo.c)
|
|
* - @ref addrinfo (addrinfo.c)
|
|
*/
|
|
|
|
/**@defgroup su_socket Socket Functions
|
|
*
|
|
* @brief The <su.h> contains the portable socket functions.
|
|
*
|
|
* The <su.h> contains following functions, macros, and types:
|
|
* - su_init(): initializes sockets
|
|
* - su_deinit(): deinitializes sockets
|
|
* - su_socket(): creates a socket
|
|
* - su_close(): closes a socket
|
|
* - su_ioctl(): ioctl to a socket
|
|
* - su_setreuseaddr(): set/reset reusing the addresses/ports for a socket
|
|
* - su_setblocking(): enables/disables blocking
|
|
* - su_isblocking(): checks if the previous call failed because it
|
|
* would have blocked
|
|
* - su_errno(): the latest socket error
|
|
* - su_perror(): prints the latest socket error message to stderr
|
|
* - su_strerror(): returns the given socket error message
|
|
* - su_perror2(): prints the given socket error message to stderr
|
|
* - su_soerror(): returns the error code associated with the socket
|
|
* - su_getmsgsize(): return the number of bytes that can be recv()ed from
|
|
* a socket
|
|
* - su_getlocalip(): return an IP address belonging to the local host
|
|
* - su_vsend(): scatter-gather send
|
|
* - su_vrecv(): scatter-gather receive
|
|
* - #su_iovec_t: structure holding scatter-gather IO vector
|
|
*/
|
|
|
|
/**@defgroup su_htable Hash tables
|
|
*
|
|
* Hash tables.
|
|
*
|
|
* The hash table interface and implementation is defined in
|
|
* <sofia-sip/htable.h>. Example code and tests for the implementation is in
|
|
* test_htable.c.
|
|
*/
|
|
|
|
|
|
/* <a name="su_wallclock"></a>
|
|
* <h3>Function @c su_wallclock() - get current time</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_time.h>
|
|
*
|
|
* void su_wallclock(su_time_t *tv);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote>
|
|
* Fills the @a tv with the current NTP timestamp.
|
|
* </blockquote>
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c tv <td>pointer to the timeval object
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <a name="su_now"></a>
|
|
* <h3>Function @c su_now() - get current time</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_time.h>
|
|
*
|
|
* su_time_t su_now(void);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote>
|
|
* Return the current NTP timestamp.
|
|
* </blockquote>
|
|
*
|
|
*
|
|
* <h4>Return Value</h4>
|
|
* <blockquote>
|
|
* The structure containing the current NTP timestamp.
|
|
* </blockquote>
|
|
*
|
|
* <a name="su_time_print"></a>
|
|
* <h3>Function @c su_time_print() - print an NTP timestamp</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_time.h>
|
|
*
|
|
* int su_time_print(char *s, int n, su_time_t const *tv);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote>
|
|
* This function prints an NTP timestamp as a decimal number to the
|
|
* given buffer.
|
|
* </blockquote>
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c char *s <td>pointer to buffer
|
|
* <tr><td>@c int n <td>buffer size
|
|
* <tr><td>@c su_time_t const tv <td>pointer to the timeval object
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <h4>Return Value</h4>
|
|
* <blockquote>
|
|
* The number of characters printed, excluding the final NUL.
|
|
* </blockquote>
|
|
*
|
|
* <a name="su_duration"></a>
|
|
* <h3>Function @c su_duration() - return time difference in milliseconds</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_time.h>
|
|
*
|
|
* su_duration_t su_duration(su_time_t t1, su_time_t t2);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote>
|
|
* Calculates the duration in milliseconds from @a t2 to @a t1 in milliseconds. If the difference is bigger
|
|
* than @c SU_MAX_DURATION, return @c SU_MAX_DURATION instead.
|
|
* </blockquote>
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c t1 <td>after time
|
|
* <tr><td>@c t2 <td>before time
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <h4>Return Value</h4>
|
|
* <blockquote>
|
|
* The duration in milliseconds between the two times.
|
|
* </blockquote>
|
|
*
|
|
* <a name="su_alloc.h"></a>
|
|
* <h1><su_alloc.h></h1>
|
|
*
|
|
* This section describes memory management functions.
|
|
*
|
|
*
|
|
* The
|
|
* @c su_alloc library provides convenience functions for
|
|
* memory management. The library defines an object @c su_home_t for
|
|
* collecting multiple memory allocations under one handle.
|
|
*
|
|
* <ul>
|
|
* - Function @c su_home_create()
|
|
* - create an su_home_t object
|
|
*
|
|
* - Function @c su_home_destroy()
|
|
* - free a home object
|
|
*
|
|
* - Function @c su_alloc()
|
|
* - allocate a memory block
|
|
*
|
|
* - Function @c su_zalloc()
|
|
* - allocate and zero a memory block
|
|
*
|
|
* - Function @c su_salloc()
|
|
* - allocate a structure
|
|
*
|
|
* - Function @c su_free()
|
|
* - free a memory block
|
|
*
|
|
* </ul>
|
|
*
|
|
*
|
|
* The functions for implementing objects derived from @c su_home_t
|
|
* are as follows:
|
|
* <ul>
|
|
* - Function @c su_home_init()
|
|
* - initialize an @c su_home_t object
|
|
*
|
|
* - Function @c su_home_deinit()
|
|
* - free memory blocks from home
|
|
*
|
|
* </ul>
|
|
*
|
|
* <a name="su_home_create"></a>
|
|
* <h3>Function @c su_home_create() - create an su_home_t object</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_alloc.h>
|
|
*
|
|
* su_home_t *su_home_create(void);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote>
|
|
* The function @c su_home_create() creates a home object used to
|
|
* collect multiple memory allocations under one handle, so that they can be
|
|
* freed by calling <dfn>su_home_destroy()</dfn>.
|
|
* </blockquote>
|
|
*
|
|
* <h4>Return Value</h4>
|
|
* <blockquote>
|
|
* This function returns a pointer to an @c su_home_t object, or
|
|
* @c NULL upon an error.
|
|
* </blockquote>
|
|
*
|
|
* <a name="su_home_destroy"></a>
|
|
* <h3>Function @c su_home_destroy() - free a home object</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_alloc.h>
|
|
*
|
|
* void su_home_destroy(su_home_t *h);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote>
|
|
* The function @c su_home_destroy() frees a home object, and all
|
|
* memory blocks associated with it.
|
|
* </blockquote>
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c su_home_t *h <td>pointer to a home object
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <a name="su_alloc"></a>
|
|
* <h3>Function @c su_alloc() - allocate a memory block</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_alloc.h>
|
|
*
|
|
* void *su_alloc(su_home_t *h, int n);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote>
|
|
* The function @c su_alloc() allocates a memory block of a given size.
|
|
*
|
|
*
|
|
* If @a h is @c NULL, this function behaves exactly like
|
|
* @c malloc().
|
|
* </blockquote>
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c su_home_t *h <td>pointer to a home object
|
|
* <tr><td>@c int n <td>size of the memory block to be allocated
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <h4>Return Value</h4>
|
|
* <blockquote>
|
|
* This function returns a pointer to the allocated memory block, or
|
|
* @c NULL, if an error occurred.
|
|
* </blockquote>
|
|
*
|
|
* <a name="su_zalloc"></a>
|
|
* <h3>Function @c su_zalloc() - allocate and zero a memory block</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_alloc.h>
|
|
*
|
|
* void *su_zalloc(su_home_t *h, int n)
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote>
|
|
* The function @c su_zalloc() allocates a memory block with a given
|
|
* size and zeroes the allocated block.
|
|
* </blockquote>
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c su_home_t *h <td>pointer to a home object
|
|
* <tr><td>@c int n <td>size of the memory block to be allocated
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <h4>Return Value</h4>
|
|
* <blockquote>
|
|
* This function returns a pointer to the allocated memory block, or
|
|
* @c NULL, if an error occurred.
|
|
* </blockquote>
|
|
*
|
|
* <a name="su_salloc"></a>
|
|
* <h3>Function @c su_salloc() - allocate a structure</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_alloc.h>
|
|
*
|
|
* void *su_salloc(su_home_t *h, int s);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote>
|
|
* The function su_salloc() allocates a structure with a given size,
|
|
* zeros it, and initializes the size field to the given size.
|
|
* </blockquote>
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c su_home_t *h <td>pointer to a home object
|
|
* <tr><td>@c int n <td>size of the structure to be allocated
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <h4>Return Value</h4>
|
|
* <blockquote>
|
|
* This function returns a pointer to the allocated memory block, or
|
|
* @c NULL, if an error occurred.
|
|
* </blockquote>
|
|
*
|
|
* <a name="su_free"></a>
|
|
* <h3>Function @c su_free() - free a memory block</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_alloc.h>
|
|
*
|
|
* void su_free(su_home_t *h, void *vb);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote>
|
|
* The function @c su_free() frees a single memory block.
|
|
* </blockquote>
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c su_home_t *h <td>pointer to a home object
|
|
* <tr><td>@c void *vb <td>pointer to the memory block to be freed
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <h4>Return Value</h4>
|
|
* <blockquote>
|
|
* </blockquote>
|
|
*
|
|
* <a name="su_home_init"></a>
|
|
* <h3>Function @c su_home_init() - initialize an @c su_home_t object</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_alloc.h>
|
|
*
|
|
* int su_home_init(su_home_t *h);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote>
|
|
* The function @c su_home_init() initializes an object derived from
|
|
* @c su_home_t. It checks that the @a suh_size field is valid.
|
|
* </blockquote>
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c su_home_t *h <td>pointer to a home object
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <h4>Return Value</h4>
|
|
* <blockquote>
|
|
* The function @c su_home_init() returns @c 0 when
|
|
* successful, or @c -1 upon an error.
|
|
* </blockquote>
|
|
*
|
|
* <h4>Note</h4>
|
|
* <blockquote><strong>This is an internal function, and it is intended for
|
|
* implementing the objects derived from @c su_home_t.</strong>
|
|
* </blockquote>
|
|
*
|
|
* <a name="su_home_deinit"></a>
|
|
* <h3>Function @c su_home_deinit() - free memory blocks from home </h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_alloc.h>
|
|
*
|
|
* void su_home_deinit(su_home_t *h);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote>
|
|
* The function @c su_home_deinit() frees the memory blocks
|
|
* associated with the home object.
|
|
* </blockquote>
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c su_home_t *h <td>pointer to a home object
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <h4>Note</h4>
|
|
* <blockquote><strong>This is an internal function, and it is intended for
|
|
* implementing the objects derived from @c su_home_t.</strong>
|
|
* </blockquote>
|
|
*
|
|
*
|
|
* <a name="su_wait.h"></a>
|
|
* <h1><su_wait.h></h1>
|
|
*
|
|
* This section describes synchronization functionality.
|
|
* The @c su_wait library provides portable synchronization
|
|
* primitives needed for running communication software.
|
|
*
|
|
* Synchronization means that the program can stop waiting for events,
|
|
* set callback functions for events, schedule timers, and set callback
|
|
* functions for timers. In other words, it is an OS-independent
|
|
* @c poll()/@c select()/@c WaitForMultipleObjects()
|
|
* interface, spiced up with timer interface.
|
|
*
|
|
* The library provides three kinds of objects: root
|
|
* objects (@c su_root_t), wait objects
|
|
* (@c su_wait_t), and timer objects
|
|
* (@c su_timer_t).
|
|
*
|
|
* <a name="wait"></a>
|
|
* <h2>Wait Objects</h2>
|
|
*
|
|
*
|
|
* Wait objects are used to signal I/O events to the process.
|
|
* The events are as follows:
|
|
*
|
|
* <dl>
|
|
* <dt>SU_WAIT_IN
|
|
* <dd>incoming data is available
|
|
*
|
|
* <dt>SU_WAIT_OUT
|
|
* <dd>data can be output
|
|
*
|
|
* <dt>SU_WAIT_ERR
|
|
* <dd>an error occurred
|
|
*
|
|
* <dt>SU_WAIT_HUP
|
|
* <dd>the socket connection was closed
|
|
*
|
|
* <dt>SU_WAIT_ACCEPT
|
|
* <dd>a listening socket accepted a new connection attempt
|
|
* </dl>
|
|
*
|
|
*
|
|
* It is possible to combine several events with |, binary or operator.
|
|
*
|
|
*
|
|
* Public API contains functions as follows:
|
|
* <ul>
|
|
* - su_wait_create()
|
|
* - su_wait_destroy()
|
|
* - su_wait()
|
|
* - su_wait_events()
|
|
* </ul>
|
|
*
|
|
*
|
|
* In Unix, the wait object is @c struct poll. The structure contains a file
|
|
* handle, a mask describing expected events, and a mask containing the
|
|
* occurred events after calling @c poll(), ie. @c su_wait().
|
|
*
|
|
*
|
|
* In Windows, the wait object is a @c HANDLE (a descriptor of a Windows
|
|
* kernel entity).
|
|
*
|
|
*
|
|
* <a name="su_wait_create"></a>
|
|
* <h3>Function @c su_wait_create()</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_wait.h>
|
|
*
|
|
* int su_wait_create(su_wait_t *newwait, su_socket_t socket, int events)</pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
*
|
|
* <blockquote>
|
|
* @c Su_wait_create() creates a new wait object for a
|
|
* @a socket with given @a events. The new wait object is
|
|
* assigned to the @a newwait parameter.
|
|
* </blockquote>
|
|
*
|
|
* <h4>Parameters</h4>
|
|
*
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c newwait<td>the newly created wait object
|
|
* <tr><td>@c socket <td>socket descriptor
|
|
* <tr><td>@c events <td>mask for events that can signal this wait object
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <h4>Return Value</h4>
|
|
*
|
|
* <blockquote>
|
|
* 0 if the call was successful, -1 otherwise.
|
|
* </blockquote>
|
|
*
|
|
* <a name="su_wait_destroy"></a>
|
|
* <h3>Function @c su_wait_destroy()</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre> #include <su_wait.h>
|
|
*
|
|
* int su_wait_destroy(su_wait_t *waitobj);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote>Destroy a wait object.
|
|
* </blockquote>
|
|
*
|
|
*
|
|
* <h4>Parameters</h4>
|
|
*
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c waitobj <td>pointer to wait object
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <h4>Return Value</h4>
|
|
*
|
|
* <blockquote>
|
|
* 0 when successful, -1 upon an error.
|
|
* </blockquote>
|
|
*
|
|
* <a name="su_wait"></a>
|
|
* <h3>Function @c su_wait()</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_wait.h>
|
|
*
|
|
* int su_wait(su_wait_t waits[], unsigned n, long timeout);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote> Block until a event specified by wait objects or a timeout occurs.
|
|
*
|
|
*
|
|
* In Unix, this is poll.
|
|
*
|
|
*
|
|
* In Windows, this is WSAWaitForMultipleEvents
|
|
* </blockquote>
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c waits <td>array of wait objects
|
|
* <tr><td>@c n <td>number of wait objects in array waits
|
|
* <tr><td>@c timeout <td>timeout in milliseocnds
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <h4>Return Value</h4>
|
|
* <blockquote>
|
|
* Index of the signaled wait object, if any, SU_WAIT_TIMEOUT if timeout
|
|
* occurred, and -1 upon an error.
|
|
* </blockquote>
|
|
*
|
|
* <a name="su_wait_events"></a>
|
|
* <h3>Function @c su_wait_events()</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_wait.h>
|
|
*
|
|
* int su_wait_events(su_wait_t *waitobj, su_socket_t s);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote> Return an mask describing events occurred.
|
|
* </blockquote>
|
|
*
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c waitobj <td>pointer to wait object
|
|
* <tr><td>@c s <td>socket
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <h4>Return Value</h4>
|
|
* <blockquote> Binary mask describing the events.
|
|
* </blockquote>
|
|
*
|
|
* <a name="su_wait_mask"></a>
|
|
* <h3>Function @c su_wait_mask()</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_wait.h>
|
|
*
|
|
* int su_wait_mask(su_wait_t *waitobj, su_socket_t s, int events);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote>
|
|
* Sets the mask describing events that can signal the wait object.
|
|
* </blockquote>
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c waitobj <td>pointer to wait object
|
|
* <tr><td>@c s <td>socket
|
|
* <tr><td>@c events <td>new event mask
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <h4>Return Value</h4>
|
|
* <blockquote>
|
|
* 0 when successful, -1 upon an error.
|
|
* </blockquote>
|
|
*
|
|
* <a name="root"></a>
|
|
* <h2>Root objects</h2>
|
|
*
|
|
*
|
|
* Root object is a structure containing a list of wait objects,
|
|
* associated callback functions, and arguments to these functions.
|
|
* It can also contain a list of timers, and a magic cookie (a pointer
|
|
* defined by root object user.)
|
|
*
|
|
*
|
|
* The public API contains following functions:
|
|
* <ul>
|
|
* - su_root_create()
|
|
* - su_root_destroy()
|
|
* - su_root_magic()
|
|
* - su_root_register()
|
|
* - su_root_unregister()
|
|
* - su_root_run()
|
|
* - su_root_break()
|
|
* - su_root_step()
|
|
* </ul>
|
|
*
|
|
* These functions are intended for implementing su_root API:
|
|
* <ul>
|
|
* - su_root_init()
|
|
* - su_root_deinit()
|
|
* - su_root_query()
|
|
* - su_root_event()
|
|
* </ul>
|
|
*
|
|
* <a name="su_root_create"></a>
|
|
* <h3>Function @c su_root_create()</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_wait.h>
|
|
*
|
|
* su_root_t *su_root_create(su_root_magic_t *magic);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote> Allocate and initialize an instance of su_root_t
|
|
* </blockquote>
|
|
*
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c magic <td>pointer to user data
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <h4>Return Value</h4>
|
|
* <blockquote> A pointer to allocated su_root_t instance, NULL on error.
|
|
* </blockquote>
|
|
*
|
|
*
|
|
* <a name="su_root_destroy"></a>
|
|
* <h3>Function @c su_root_destroy()</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_wait.h>
|
|
*
|
|
* void su_root_destroy(su_root_t *root);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote> Deinitialize and free an instance of su_root_t
|
|
* </blockquote>
|
|
*
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c root <td>pointer to a root structure
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
*
|
|
* <a name="su_root_magic"></a>
|
|
* <h3>Function @c su_root_magic()</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_wait.h>
|
|
*
|
|
* su_root_magic_t *su_root_magic(su_root_t *root);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote> Return the user data pointer that was given input to su_root_create() or
|
|
*
|
|
* su_root_init().
|
|
* </blockquote>
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c root <td>pointer to a root object
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <h4>Return Value</h4>
|
|
* <blockquote> A pointer to user data
|
|
* </blockquote>
|
|
*
|
|
*
|
|
* <a name="su_root_register"></a>
|
|
* <h3>Function @c su_root_register()</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_wait.h>
|
|
*
|
|
* int su_root_register(su_root_t *root,
|
|
* su_wait_t *waits,
|
|
* su_wakeup_f callback,
|
|
* su_wakeup_arg_t arg,
|
|
* int priority);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote> Register a su_wait_t object. The wait object, a callback function and
|
|
*
|
|
* a argument is stored to the root object. The callback function is called,
|
|
* when the wait object is signaled.
|
|
*
|
|
* Please note if identical wait objects are inserted, only first one is
|
|
* ever signalled.
|
|
* </blockquote>
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c root <td>pointer to root object
|
|
* <tr><td>@c waits <td>pointer to wait object
|
|
* <tr><td>@c callback <td>callback function pointer
|
|
* <tr><td>@c arg <td>argument given to callback function when it is invoked
|
|
* <tr><td>@c priority <td>relative priority of the wait object
|
|
* (0 is normal, 1 important, 2 realtime)
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <h4>Return Value</h4>
|
|
* <blockquote> Index of the wait object, or -1 upon an error.
|
|
* </blockquote>
|
|
*
|
|
*
|
|
* <a name="su_root_unregister"></a>
|
|
* <h3>Function @c su_root_unregister()</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_wait.h>
|
|
*
|
|
* int su_root_unregister(su_root_t *root,
|
|
* su_wait_t *wait,
|
|
* su_wakeup_f callback,
|
|
* su_wakeup_arg_t arg);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote> UnRegisters a su_wait_t object. The wait object, a callback function and
|
|
*
|
|
* a argument are removed from the root object. The callback function is called,
|
|
* when the wait object is signaled.
|
|
* </blockquote>
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c root <td>pointer to root object
|
|
* <tr><td>@c waits <td>pointer to wait object
|
|
* <tr><td>@c callback <td>callback function pointer (may be NULL)
|
|
* <tr><td>@c arg <td>argument given to callback function when it
|
|
* is invoked (may be NULL)
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <h4>Return Value</h4>
|
|
* <blockquote> Index of the wait object, or -1 upon an error.
|
|
* </blockquote>
|
|
*
|
|
*
|
|
* <a name="su_root_run"></a>
|
|
* <h3>Function @c su_root_run()</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_wait.h>
|
|
*
|
|
* void su_root_run(su_root_t *root);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote> This function waits for wait objects and the timers associated with
|
|
* the root object. When any wait object is signaled or timer is
|
|
* expired, it invokes the callbacks, and returns waiting.
|
|
*
|
|
*
|
|
* This function returns when su_root_break() is called from a callback.
|
|
* </blockquote>
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c root <td>pointer to root object
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
*
|
|
* <a name="su_root_break"></a>
|
|
* <h3>Function @c su_root_break()</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_wait.h>
|
|
*
|
|
* void su_root_break(su_root_t *root);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote> If this function is used to terminate execution of su_root_run(). It
|
|
*
|
|
* can be called from a callback function.
|
|
* </blockquote>
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c root <td>pointer to root object
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
*
|
|
* <a name="su_root_step"></a>
|
|
* <h3>Function @c su_root_step()</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_wait.h>
|
|
*
|
|
* su_duration_t su_root_step(su_root_t *root, su_duration_t tout);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote> This function waits for wait objects and the timers associated with
|
|
* the @a root object. When any wait object is signaled or timer is
|
|
* expired, it invokes the callbacks, and returns.
|
|
*
|
|
*
|
|
* This function returns when a callback has been invoked or @a tout
|
|
* milliseconds is elapsed.
|
|
* </blockquote>
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c root <td>pointer to root object
|
|
* <tr><td>@c tout <td>timeout in milliseconds
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <h4>Return Value</h4>
|
|
* <blockquote>
|
|
* Milliseconds to the next invocation of timer, or SU_WAIT_FOREVER if
|
|
* there are no active timers.
|
|
* </blockquote>
|
|
*
|
|
* <a name="timer"></a>
|
|
* <h2>Timer objects</h2>
|
|
*
|
|
* Timers are used to schedule some task to be executed at given time or
|
|
* after a default interval. The default interval is specified when the
|
|
* timer is created. We call timer activation "setting the timer", and
|
|
* deactivation "resetting the timer" (as in SDL). When the given time has
|
|
* arrived or the default interval has elapsed, the timer expires and
|
|
* it is ready for execution.
|
|
*
|
|
* These functions are available for handling timers:
|
|
*
|
|
* - su_timer_create()
|
|
* - su_timer_destroy()
|
|
* - su_timer_set()
|
|
* - su_timer_set_at()
|
|
* - su_timer_reset()
|
|
* - su_timer_run()
|
|
*
|
|
* <a name="su_timer_create"></a>
|
|
* <h3>Function @c su_timer_create()</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_wait.h>
|
|
*
|
|
* su_timer_t *su_timer_create(su_root_t *root, su_duration_t msec);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
*
|
|
* <blockquote>
|
|
* Allocate and initialize an instance of su_timer_t.
|
|
* </blockquote>
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c root <td>the root object with which the timer will be associated
|
|
* <tr><td>@c msec <td>the default duration of the timer
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <h4>Return Value</h4>
|
|
* <blockquote> A pointer to allocated timer instance, NULL on error.
|
|
* </blockquote>
|
|
*
|
|
*
|
|
* <a name="su_timer_destroy"></a>
|
|
* <h3>Function @c su_timer_destroy()</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_wait.h>
|
|
*
|
|
* void su_timer_destroy(su_timer_t *t);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote> Deinitialize and free an instance of su_timer_t.
|
|
* </blockquote>
|
|
*
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c t <td>pointer to the timer object
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
*
|
|
* <a name="su_timer_set"></a>
|
|
* <h3>Function @c su_timer_set()</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_wait.h>
|
|
*
|
|
* int su_timer_set(su_timer_t *t,
|
|
* su_timer_f wakeup,
|
|
* su_wakeup_arg_t arg);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote> Sets the given timer to expire after the default duration.
|
|
*
|
|
* The timer must have an default duration.
|
|
* </blockquote>
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c t <td>pointer to the timer object
|
|
* <tr><td>@c wakeup <td>pointer to the wakeup function
|
|
* <tr><td>@c arg <td>argument given to the wakeup function
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <h4>Return Value</h4>
|
|
* <blockquote> 0 if successful, -1 otherwise.
|
|
* </blockquote>
|
|
*
|
|
*
|
|
* <a name="su_timer_set_at"></a>
|
|
* <h3>Function @c su_timer_set_at()</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_wait.h>
|
|
*
|
|
* int su_timer_set_at(su_timer_t *t,
|
|
* su_timer_f wakeup,
|
|
* su_wakeup_arg_t arg,
|
|
* su_time_t when);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote> Sets the timer to expire at given time.
|
|
* </blockquote>
|
|
*
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c t <td>pointer to the timer object
|
|
* <tr><td>@c wakeup <td>pointer to the wakeup function
|
|
* <tr><td>@c arg <td>argument given to the wakeup function
|
|
* <tr><td>@c when <td>time structure defining the wakeup time
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <h4>Return Value</h4>
|
|
* <blockquote> 0 if successful, -1 otherwise.
|
|
* </blockquote>
|
|
*
|
|
*
|
|
* <a name="su_timer_reset"></a>
|
|
* <h3>Function @c su_timer_reset()</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_wait.h>
|
|
*
|
|
* int su_timer_reset(su_timer_t *t);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote> Resets the given timer.
|
|
* </blockquote>
|
|
*
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c t <td>pointer to the timer object
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <h4>Return Value</h4>
|
|
* <blockquote> 0 if successful, -1 otherwise.
|
|
* </blockquote>
|
|
*
|
|
* <a name="su_timer_run"></a>
|
|
* <h3>Function @c su_timer_run()</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_wait.h>
|
|
*
|
|
* su_duration_t su_timer_run(su_timer_t ** const t0, su_duration_t tout);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote> Expires and executes expired timers in queue.
|
|
* </blockquote>
|
|
*
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c t0 <td>pointer to the timer queue
|
|
* <tr><td>@c tout <td>timeout in milliseconds
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <h4>Return Value</h4>
|
|
* <blockquote>
|
|
* The duration in milliseconds before the next timer expires, or timeout (2**31 - 1
|
|
* ms), whichever is shorter.
|
|
* </blockquote>
|
|
*
|
|
* <!--
|
|
* Root object is used for synchronizing. There must be one root object per
|
|
* thread. There are two alternative ways for creating a root object. If you
|
|
* are just using su_root_t, and don't want to <a
|
|
* href="#inherit_su_root_t">inherit from it</a>, you can use
|
|
* @c su_create().
|
|
* -->
|
|
*
|
|
* <a name="su_wait_internal.h"></a>
|
|
* <h1><su_wait_internal.h></h1>
|
|
*
|
|
*
|
|
* This section contains the internal functions, that is, functions used to
|
|
* implement objects in @c <su_wait.h>.
|
|
*
|
|
* <a name="su_root_init"></a>
|
|
* <h3>Function @c su_root_init()</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_wait.h>
|
|
* #include <su_wait_internal.h>
|
|
*
|
|
* int su_root_init(su_root_t *root, su_root_magic_t *magic);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
*
|
|
* <blockquote>
|
|
*
|
|
* Initialize an instance of @c su_root_t. The caller should allocate
|
|
* the memory required for su_root_t, and set the sur_size to the size of the
|
|
* allocated structure.
|
|
*
|
|
* </blockquote>
|
|
*
|
|
* <h4>Parameters</h4>
|
|
*
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c root <td>pointer to a uninitialized root structure
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <h4>Return Value</h4>
|
|
* <blockquote> 0 when call was successful, -1 otherwise.
|
|
* </blockquote>
|
|
*
|
|
*
|
|
* <h4>Note</h4>
|
|
* <blockquote>
|
|
* <strong>This is an internal function, and it is intended for implementing
|
|
* the objects derived from @c su_root_t.</strong>
|
|
* </blockquote>
|
|
*
|
|
*
|
|
* <a name="su_root_deinit"></a>
|
|
* <h3>Function @c su_root_deinit()</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_wait.h>
|
|
* #include <su_wait_internal.h>
|
|
*
|
|
* void su_root_deinit(su_root_t *root);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote> Deinitialize an instance of su_root_t
|
|
* </blockquote>
|
|
*
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c root <td>pointer to a root structure
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <h4>Note</h4>
|
|
* <blockquote> <strong>This is an internal function, and it is intended for
|
|
* implementing the objects derived from @c su_root_t.</strong>
|
|
* </blockquote>
|
|
*
|
|
* <a name="su_root_query"></a>
|
|
* <h3>Function @c su_root_query()</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_wait.h>
|
|
* #include <su_wait_internal.h>
|
|
*
|
|
* unsigned su_root_query(su_root_t *root, su_wait_t *waits, unsigned n_waits);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote> Copies the su_wait_t objects from the root. The number of wait objects
|
|
*
|
|
* can be found out by calling su_root_query() with n_waits as zero.
|
|
* </blockquote>
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c waits <td>pointer to array to which wait objects are copied
|
|
* <tr><td>@c root <td>pointer to root object
|
|
* <tr><td>@c n_waits <td>number of wait objects fitting in array waits
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <h4>Return Value</h4>
|
|
* <blockquote> Number of wait objects, or 0 upon an error.
|
|
* </blockquote>
|
|
*
|
|
*
|
|
* <h4>Note</h4>
|
|
* <blockquote><strong>This is an internal function, and it is intended for
|
|
* implementing the objects derived from @c su_root_t.</strong>
|
|
* </blockquote>
|
|
*
|
|
*
|
|
* <a name="su_root_event"></a>
|
|
* <h3>Function @c su_root_event()</h3>
|
|
*
|
|
* <h4>Synopsis</h4>
|
|
*
|
|
* <blockquote><pre>
|
|
* #include <su_wait.h>
|
|
* #include <su_wait_internal.h>
|
|
*
|
|
* void su_root_event(su_root_t *root, su_wait_t *waitobj);
|
|
* </pre></blockquote>
|
|
*
|
|
* <h4>Description</h4>
|
|
* <blockquote> Invokes the callback function associated with the wait object.
|
|
*
|
|
*
|
|
* If waitobj is NULL, check if a wait object associated with root is
|
|
* signaled, and its callback is invoked.
|
|
* </blockquote>
|
|
*
|
|
* <h4>Parameters</h4>
|
|
* <blockquote>
|
|
* <table cellpadding=3 cellspacing=0 border=1>
|
|
* <tr><td>@c root <td>pointer to root object
|
|
* <tr><td>@c waitobj <td>pointer to wait object, or NULL
|
|
* </table>
|
|
* </blockquote>
|
|
*
|
|
* <h4>Note</h4>
|
|
* <blockquote><strong>This is an internal function, and it is intended for
|
|
* implementing the objects derived from @c su_root_t.</strong>
|
|
* </blockquote>
|
|
*
|
|
*/
|