freeswitch/libs/sofia-sip/libsofia-sip-ua/su/su.docs

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 &lt;su_time.h&gt;
*
* 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 &lt;su_time.h&gt;
*
* 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 &lt;su_time.h&gt;
*
* 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 &lt;su_time.h&gt;
*
* 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>&lt;su_alloc.h&gt;</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 &lt;su_alloc.h&gt;
*
* 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 &lt;su_alloc.h&gt;
*
* 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 &lt;su_alloc.h&gt;
*
* 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 &lt;su_alloc.h&gt;
*
* 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 &lt;su_alloc.h&gt;
*
* 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 &lt;su_alloc.h&gt;
*
* 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 &lt;su_alloc.h&gt;
*
* 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 &lt;su_alloc.h&gt;
*
* 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>&lt;su_wait.h&gt;</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 &lt;su_wait.h&gt;
*
* 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 &lt;su_wait.h&gt;
*
* 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 &lt;su_wait.h&gt;
*
* 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 &lt;su_wait.h&gt;
*
* 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 &lt;su_wait.h&gt;
*
* 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 &lt;su_wait.h&gt;
*
* 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 &lt;su_wait.h&gt;
*
* 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 &lt;su_wait.h&gt;
*
* 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 &lt;su_wait.h&gt;
*
* 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 &lt;su_wait.h&gt;
*
* 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 &lt;su_wait.h&gt;
*
* 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 &lt;su_wait.h&gt;
*
* 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 &lt;su_wait.h&gt;
*
* 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 &lt;su_wait.h&gt;
*
* 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 &lt;su_wait.h&gt;
*
* 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 &lt;su_wait.h&gt;
*
* 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 &lt;su_wait.h&gt;
*
* 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 &lt;su_wait.h&gt;
*
* 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 &lt;su_wait.h&gt;
*
* 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>&lt;su_wait_internal.h&gt;</h1>
*
*
* This section contains the internal functions, that is, functions used to
* implement objects in @c &lt;su_wait.h&gt;.
*
* <a name="su_root_init"></a>
* <h3>Function @c su_root_init()</h3>
*
* <h4>Synopsis</h4>
*
* <blockquote><pre>
* #include &lt;su_wait.h&gt;
* #include &lt;su_wait_internal.h&gt;
*
* 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 &lt;su_wait.h&gt;
* #include &lt;su_wait_internal.h&gt;
*
* 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 &lt;su_wait.h&gt;
* #include &lt;su_wait_internal.h&gt;
*
* 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 &lt;su_wait.h&gt;
* #include &lt;su_wait_internal.h&gt;
*
* 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>
*
*/