/* -*- 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> * */