diff options
Diffstat (limited to 'pjlib/include/pj/ioqueue.h')
-rw-r--r-- | pjlib/include/pj/ioqueue.h | 1195 |
1 files changed, 608 insertions, 587 deletions
diff --git a/pjlib/include/pj/ioqueue.h b/pjlib/include/pj/ioqueue.h index d1aea694..87f9c104 100644 --- a/pjlib/include/pj/ioqueue.h +++ b/pjlib/include/pj/ioqueue.h @@ -1,344 +1,365 @@ -/* $Id$ - */ - -#ifndef __PJ_IOQUEUE_H__ -#define __PJ_IOQUEUE_H__ - -/** - * @file ioqueue.h - * @brief I/O Dispatching Mechanism - */ - -#include <pj/types.h> - -PJ_BEGIN_DECL - -/** - * @defgroup PJ_IO Input/Output - * @brief Input/Output - * @ingroup PJ_OS - * - * This section contains API building blocks to perform network I/O and - * communications. If provides: - * - @ref PJ_SOCK - *\n - * A highly portable socket abstraction, runs on all kind of - * network APIs such as standard BSD socket, Windows socket, Linux - * \b kernel socket, PalmOS networking API, etc. - * - * - @ref pj_addr_resolve - *\n - * Portable address resolution, which implements #pj_gethostbyname(). - * - * - @ref PJ_SOCK_SELECT - *\n - * A portable \a select() like API (#pj_sock_select()) which can be - * implemented with various back-ends. - * - * - @ref PJ_IOQUEUE - *\n - * Framework for dispatching network events. - * - * For more information see the modules below. - */ - -/** - * @defgroup PJ_IOQUEUE I/O Event Dispatching Queue - * @ingroup PJ_IO - * @{ - * - * I/O Queue provides API for performing asynchronous I/O operations. It - * conforms to proactor pattern, which allows application to submit an - * asynchronous operation and to be notified later when the operation has - * completed. - * - * The I/O Queue can work on both socket and file descriptors. For - * asynchronous file operations however, one must make sure that the correct - * file I/O back-end is used, because not all file I/O back-end can be - * used with the ioqueue. Please see \ref PJ_FILE_IO for more details. - * - * The framework works natively in platforms where asynchronous operation API - * exists, such as in Windows NT with IoCompletionPort/IOCP. In other - * platforms, the I/O queue abstracts the operating system's event poll API - * to provide semantics similar to IoCompletionPort with minimal penalties - * (i.e. per ioqueue and per handle mutex protection). - * - * The I/O queue provides more than just unified abstraction. It also: - * - makes sure that the operation uses the most effective way to utilize - * the underlying mechanism, to achieve the maximum theoritical - * throughput possible on a given platform. - * - choose the most efficient mechanism for event polling on a given - * platform. - * - * Currently, the I/O Queue is implemented using: - * - <tt><b>select()</b></tt>, as the common denominator, but the least - * efficient. Also the number of descriptor is limited to - * \c PJ_IOQUEUE_MAX_HANDLES (which by default is 64). - * - <tt><b>/dev/epoll</b></tt> on Linux (user mode and kernel mode), - * a much faster replacement for select() on Linux (and more importantly - * doesn't have limitation on number of descriptors). - * - <b>I/O Completion ports</b> on Windows NT/2000/XP, which is the most - * efficient way to dispatch events in Windows NT based OSes, and most - * importantly, it doesn't have the limit on how many handles to monitor. - * And it works with files (not only sockets) as well. - * - * - * \section pj_ioqueue_concurrency_sec Concurrency Rules - * - * The items below describe rules that must be obeyed when using the I/O - * queue, with regard to concurrency: - * - simultaneous operations (by different threads) to different key is safe. - * - simultaneous operations to the same key is also safe, except - * <b>unregistration</b>, which is described below. - * - <b>care must be taken when unregistering a key</b> from the - * ioqueue. Application must take care that when one thread is issuing - * an unregistration, other thread is not simultaneously invoking an - * operation <b>to the same key</b>. - *\n - * This happens because the ioqueue functions are working with a pointer - * to the key, and there is a possible race condition where the pointer - * has been rendered invalid by other threads before the ioqueue has a - * chance to acquire mutex on it. - * - * \section pj_ioqeuue_examples_sec Examples - * - * For some examples on how to use the I/O Queue, please see: - * - * - \ref page_pjlib_ioqueue_tcp_test - * - \ref page_pjlib_ioqueue_udp_test - * - \ref page_pjlib_ioqueue_perf_test - */ - - -/** - * This structure describes operation specific key to be submitted to - * I/O Queue when performing the asynchronous operation. This key will - * be returned to the application when completion callback is called. - * - * Application normally wants to attach it's specific data in the - * \c user_data field so that it can keep track of which operation has - * completed when the callback is called. Alternatively, application can - * also extend this struct to include its data, because the pointer that - * is returned in the completion callback will be exactly the same as - * the pointer supplied when the asynchronous function is called. - */ -typedef struct pj_ioqueue_op_key_t -{ - void *internal__[32]; /**< Internal I/O Queue data. */ - void *user_data; /**< Application data. */ -} pj_ioqueue_op_key_t; - -/** - * This structure describes the callbacks to be called when I/O operation - * completes. - */ -typedef struct pj_ioqueue_callback -{ - /** - * This callback is called when #pj_ioqueue_recv or #pj_ioqueue_recvfrom - * completes. - * - * @param key The key. - * @param op_key Operation key. - * @param bytes_read >= 0 to indicate the amount of data read, - * otherwise negative value containing the error - * code. To obtain the pj_status_t error code, use - * (pj_status_t code = -bytes_read). - */ - void (*on_read_complete)(pj_ioqueue_key_t *key, - pj_ioqueue_op_key_t *op_key, - pj_ssize_t bytes_read); - - /** - * This callback is called when #pj_ioqueue_write or #pj_ioqueue_sendto - * completes. - * - * @param key The key. - * @param op_key Operation key. - * @param bytes_sent >= 0 to indicate the amount of data written, - * otherwise negative value containing the error - * code. To obtain the pj_status_t error code, use - * (pj_status_t code = -bytes_sent). - */ - void (*on_write_complete)(pj_ioqueue_key_t *key, - pj_ioqueue_op_key_t *op_key, - pj_ssize_t bytes_sent); - - /** - * This callback is called when #pj_ioqueue_accept completes. - * - * @param key The key. - * @param op_key Operation key. - * @param sock Newly connected socket. - * @param status Zero if the operation completes successfully. - */ - void (*on_accept_complete)(pj_ioqueue_key_t *key, - pj_ioqueue_op_key_t *op_key, - pj_sock_t sock, - pj_status_t status); - - /** - * This callback is called when #pj_ioqueue_connect completes. - * - * @param key The key. - * @param status PJ_SUCCESS if the operation completes successfully. - */ - void (*on_connect_complete)(pj_ioqueue_key_t *key, - pj_status_t status); -} pj_ioqueue_callback; - - -/** - * Types of pending I/O Queue operation. This enumeration is only used - * internally within the ioqueue. - */ -typedef enum pj_ioqueue_operation_e -{ - PJ_IOQUEUE_OP_NONE = 0, /**< No operation. */ - PJ_IOQUEUE_OP_READ = 1, /**< read() operation. */ - PJ_IOQUEUE_OP_RECV = 2, /**< recv() operation. */ - PJ_IOQUEUE_OP_RECV_FROM = 4, /**< recvfrom() operation. */ - PJ_IOQUEUE_OP_WRITE = 8, /**< write() operation. */ - PJ_IOQUEUE_OP_SEND = 16, /**< send() operation. */ - PJ_IOQUEUE_OP_SEND_TO = 32, /**< sendto() operation. */ -#if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0 - PJ_IOQUEUE_OP_ACCEPT = 64, /**< accept() operation. */ - PJ_IOQUEUE_OP_CONNECT = 128, /**< connect() operation. */ -#endif /* PJ_HAS_TCP */ -} pj_ioqueue_operation_e; - - -/** - * This macro specifies the maximum number of events that can be - * processed by the ioqueue on a single poll cycle, on implementation - * that supports it. The value is only meaningfull when specified - * during PJLIB build. - */ -#ifndef PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL -# define PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL (16) -#endif - -/** - * Return the name of the ioqueue implementation. - * - * @return Implementation name. - */ -PJ_DECL(const char*) pj_ioqueue_name(void); - - -/** - * Create a new I/O Queue framework. - * - * @param pool The pool to allocate the I/O queue structure. - * @param max_fd The maximum number of handles to be supported, which - * should not exceed PJ_IOQUEUE_MAX_HANDLES. - * @param ioqueue Pointer to hold the newly created I/O Queue. - * - * @return PJ_SUCCESS on success. - */ -PJ_DECL(pj_status_t) pj_ioqueue_create( pj_pool_t *pool, - pj_size_t max_fd, - pj_ioqueue_t **ioqueue); - -/** - * Destroy the I/O queue. - * - * @param ioque The I/O Queue to be destroyed. - * - * @return PJ_SUCCESS if success. - */ -PJ_DECL(pj_status_t) pj_ioqueue_destroy( pj_ioqueue_t *ioque ); - -/** - * Set the lock object to be used by the I/O Queue. This function can only - * be called right after the I/O queue is created, before any handle is - * registered to the I/O queue. - * - * Initially the I/O queue is created with non-recursive mutex protection. - * Applications can supply alternative lock to be used by calling this - * function. - * - * @param ioque The ioqueue instance. - * @param lock The lock to be used by the ioqueue. - * @param auto_delete In non-zero, the lock will be deleted by the ioqueue. - * - * @return PJ_SUCCESS or the appropriate error code. - */ -PJ_DECL(pj_status_t) pj_ioqueue_set_lock( pj_ioqueue_t *ioque, - pj_lock_t *lock, - pj_bool_t auto_delete ); - -/** - * Register a socket to the I/O queue framework. - * When a socket is registered to the IOQueue, it may be modified to use - * non-blocking IO. If it is modified, there is no guarantee that this - * modification will be restored after the socket is unregistered. - * - * @param pool To allocate the resource for the specified handle, - * which must be valid until the handle/key is unregistered - * from I/O Queue. - * @param ioque The I/O Queue. - * @param sock The socket. - * @param user_data User data to be associated with the key, which can be - * retrieved later. - * @param cb Callback to be called when I/O operation completes. - * @param key Pointer to receive the key to be associated with this - * socket. Subsequent I/O queue operation will need this - * key. - * - * @return PJ_SUCCESS on success, or the error code. - */ -PJ_DECL(pj_status_t) pj_ioqueue_register_sock( pj_pool_t *pool, - pj_ioqueue_t *ioque, - pj_sock_t sock, - void *user_data, - const pj_ioqueue_callback *cb, - pj_ioqueue_key_t **key ); - -/** - * Unregister from the I/O Queue framework. Caller must make sure that - * the key doesn't have any pending operations before calling this function, +/* $Id$
+ */
+/*
+ * PJLIB - PJ Foundation Library
+ * (C)2003-2005 Benny Prijono <bennylp@bulukucing.org>
+ *
+ * Author:
+ * Benny Prijono <bennylp@bulukucing.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __PJ_IOQUEUE_H__
+#define __PJ_IOQUEUE_H__
+
+/**
+ * @file ioqueue.h
+ * @brief I/O Dispatching Mechanism
+ */
+
+#include <pj/types.h>
+
+PJ_BEGIN_DECL
+
+/**
+ * @defgroup PJ_IO Input/Output
+ * @brief Input/Output
+ * @ingroup PJ_OS
+ *
+ * This section contains API building blocks to perform network I/O and
+ * communications. If provides:
+ * - @ref PJ_SOCK
+ *\n
+ * A highly portable socket abstraction, runs on all kind of
+ * network APIs such as standard BSD socket, Windows socket, Linux
+ * \b kernel socket, PalmOS networking API, etc.
+ *
+ * - @ref pj_addr_resolve
+ *\n
+ * Portable address resolution, which implements #pj_gethostbyname().
+ *
+ * - @ref PJ_SOCK_SELECT
+ *\n
+ * A portable \a select() like API (#pj_sock_select()) which can be
+ * implemented with various back-ends.
+ *
+ * - @ref PJ_IOQUEUE
+ *\n
+ * Framework for dispatching network events.
+ *
+ * For more information see the modules below.
+ */
+
+/**
+ * @defgroup PJ_IOQUEUE I/O Event Dispatching Queue
+ * @ingroup PJ_IO
+ * @{
+ *
+ * I/O Queue provides API for performing asynchronous I/O operations. It
+ * conforms to proactor pattern, which allows application to submit an
+ * asynchronous operation and to be notified later when the operation has
+ * completed.
+ *
+ * The I/O Queue can work on both socket and file descriptors. For
+ * asynchronous file operations however, one must make sure that the correct
+ * file I/O back-end is used, because not all file I/O back-end can be
+ * used with the ioqueue. Please see \ref PJ_FILE_IO for more details.
+ *
+ * The framework works natively in platforms where asynchronous operation API
+ * exists, such as in Windows NT with IoCompletionPort/IOCP. In other
+ * platforms, the I/O queue abstracts the operating system's event poll API
+ * to provide semantics similar to IoCompletionPort with minimal penalties
+ * (i.e. per ioqueue and per handle mutex protection).
+ *
+ * The I/O queue provides more than just unified abstraction. It also:
+ * - makes sure that the operation uses the most effective way to utilize
+ * the underlying mechanism, to achieve the maximum theoritical
+ * throughput possible on a given platform.
+ * - choose the most efficient mechanism for event polling on a given
+ * platform.
+ *
+ * Currently, the I/O Queue is implemented using:
+ * - <tt><b>select()</b></tt>, as the common denominator, but the least
+ * efficient. Also the number of descriptor is limited to
+ * \c PJ_IOQUEUE_MAX_HANDLES (which by default is 64).
+ * - <tt><b>/dev/epoll</b></tt> on Linux (user mode and kernel mode),
+ * a much faster replacement for select() on Linux (and more importantly
+ * doesn't have limitation on number of descriptors).
+ * - <b>I/O Completion ports</b> on Windows NT/2000/XP, which is the most
+ * efficient way to dispatch events in Windows NT based OSes, and most
+ * importantly, it doesn't have the limit on how many handles to monitor.
+ * And it works with files (not only sockets) as well.
+ *
+ *
+ * \section pj_ioqueue_concurrency_sec Concurrency Rules
+ *
+ * The items below describe rules that must be obeyed when using the I/O
+ * queue, with regard to concurrency:
+ * - simultaneous operations (by different threads) to different key is safe.
+ * - simultaneous operations to the same key is also safe, except
+ * <b>unregistration</b>, which is described below.
+ * - <b>care must be taken when unregistering a key</b> from the
+ * ioqueue. Application must take care that when one thread is issuing
+ * an unregistration, other thread is not simultaneously invoking an
+ * operation <b>to the same key</b>.
+ *\n
+ * This happens because the ioqueue functions are working with a pointer
+ * to the key, and there is a possible race condition where the pointer
+ * has been rendered invalid by other threads before the ioqueue has a
+ * chance to acquire mutex on it.
+ *
+ * \section pj_ioqeuue_examples_sec Examples
+ *
+ * For some examples on how to use the I/O Queue, please see:
+ *
+ * - \ref page_pjlib_ioqueue_tcp_test
+ * - \ref page_pjlib_ioqueue_udp_test
+ * - \ref page_pjlib_ioqueue_perf_test
+ */
+
+
+/**
+ * This structure describes operation specific key to be submitted to
+ * I/O Queue when performing the asynchronous operation. This key will
+ * be returned to the application when completion callback is called.
+ *
+ * Application normally wants to attach it's specific data in the
+ * \c user_data field so that it can keep track of which operation has
+ * completed when the callback is called. Alternatively, application can
+ * also extend this struct to include its data, because the pointer that
+ * is returned in the completion callback will be exactly the same as
+ * the pointer supplied when the asynchronous function is called.
+ */
+typedef struct pj_ioqueue_op_key_t
+{
+ void *internal__[32]; /**< Internal I/O Queue data. */
+ void *user_data; /**< Application data. */
+} pj_ioqueue_op_key_t;
+
+/**
+ * This structure describes the callbacks to be called when I/O operation
+ * completes.
+ */
+typedef struct pj_ioqueue_callback
+{
+ /**
+ * This callback is called when #pj_ioqueue_recv or #pj_ioqueue_recvfrom
+ * completes.
+ *
+ * @param key The key.
+ * @param op_key Operation key.
+ * @param bytes_read >= 0 to indicate the amount of data read,
+ * otherwise negative value containing the error
+ * code. To obtain the pj_status_t error code, use
+ * (pj_status_t code = -bytes_read).
+ */
+ void (*on_read_complete)(pj_ioqueue_key_t *key,
+ pj_ioqueue_op_key_t *op_key,
+ pj_ssize_t bytes_read);
+
+ /**
+ * This callback is called when #pj_ioqueue_write or #pj_ioqueue_sendto
+ * completes.
+ *
+ * @param key The key.
+ * @param op_key Operation key.
+ * @param bytes_sent >= 0 to indicate the amount of data written,
+ * otherwise negative value containing the error
+ * code. To obtain the pj_status_t error code, use
+ * (pj_status_t code = -bytes_sent).
+ */
+ void (*on_write_complete)(pj_ioqueue_key_t *key,
+ pj_ioqueue_op_key_t *op_key,
+ pj_ssize_t bytes_sent);
+
+ /**
+ * This callback is called when #pj_ioqueue_accept completes.
+ *
+ * @param key The key.
+ * @param op_key Operation key.
+ * @param sock Newly connected socket.
+ * @param status Zero if the operation completes successfully.
+ */
+ void (*on_accept_complete)(pj_ioqueue_key_t *key,
+ pj_ioqueue_op_key_t *op_key,
+ pj_sock_t sock,
+ pj_status_t status);
+
+ /**
+ * This callback is called when #pj_ioqueue_connect completes.
+ *
+ * @param key The key.
+ * @param status PJ_SUCCESS if the operation completes successfully.
+ */
+ void (*on_connect_complete)(pj_ioqueue_key_t *key,
+ pj_status_t status);
+} pj_ioqueue_callback;
+
+
+/**
+ * Types of pending I/O Queue operation. This enumeration is only used
+ * internally within the ioqueue.
+ */
+typedef enum pj_ioqueue_operation_e
+{
+ PJ_IOQUEUE_OP_NONE = 0, /**< No operation. */
+ PJ_IOQUEUE_OP_READ = 1, /**< read() operation. */
+ PJ_IOQUEUE_OP_RECV = 2, /**< recv() operation. */
+ PJ_IOQUEUE_OP_RECV_FROM = 4, /**< recvfrom() operation. */
+ PJ_IOQUEUE_OP_WRITE = 8, /**< write() operation. */
+ PJ_IOQUEUE_OP_SEND = 16, /**< send() operation. */
+ PJ_IOQUEUE_OP_SEND_TO = 32, /**< sendto() operation. */
+#if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0
+ PJ_IOQUEUE_OP_ACCEPT = 64, /**< accept() operation. */
+ PJ_IOQUEUE_OP_CONNECT = 128, /**< connect() operation. */
+#endif /* PJ_HAS_TCP */
+} pj_ioqueue_operation_e;
+
+
+/**
+ * This macro specifies the maximum number of events that can be
+ * processed by the ioqueue on a single poll cycle, on implementation
+ * that supports it. The value is only meaningfull when specified
+ * during PJLIB build.
+ */
+#ifndef PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL
+# define PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL (16)
+#endif
+
+/**
+ * Return the name of the ioqueue implementation.
+ *
+ * @return Implementation name.
+ */
+PJ_DECL(const char*) pj_ioqueue_name(void);
+
+
+/**
+ * Create a new I/O Queue framework.
+ *
+ * @param pool The pool to allocate the I/O queue structure.
+ * @param max_fd The maximum number of handles to be supported, which
+ * should not exceed PJ_IOQUEUE_MAX_HANDLES.
+ * @param ioqueue Pointer to hold the newly created I/O Queue.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_create( pj_pool_t *pool,
+ pj_size_t max_fd,
+ pj_ioqueue_t **ioqueue);
+
+/**
+ * Destroy the I/O queue.
+ *
+ * @param ioque The I/O Queue to be destroyed.
+ *
+ * @return PJ_SUCCESS if success.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_destroy( pj_ioqueue_t *ioque );
+
+/**
+ * Set the lock object to be used by the I/O Queue. This function can only
+ * be called right after the I/O queue is created, before any handle is
+ * registered to the I/O queue.
+ *
+ * Initially the I/O queue is created with non-recursive mutex protection.
+ * Applications can supply alternative lock to be used by calling this
+ * function.
+ *
+ * @param ioque The ioqueue instance.
+ * @param lock The lock to be used by the ioqueue.
+ * @param auto_delete In non-zero, the lock will be deleted by the ioqueue.
+ *
+ * @return PJ_SUCCESS or the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_set_lock( pj_ioqueue_t *ioque,
+ pj_lock_t *lock,
+ pj_bool_t auto_delete );
+
+/**
+ * Register a socket to the I/O queue framework.
+ * When a socket is registered to the IOQueue, it may be modified to use
+ * non-blocking IO. If it is modified, there is no guarantee that this
+ * modification will be restored after the socket is unregistered.
+ *
+ * @param pool To allocate the resource for the specified handle,
+ * which must be valid until the handle/key is unregistered
+ * from I/O Queue.
+ * @param ioque The I/O Queue.
+ * @param sock The socket.
+ * @param user_data User data to be associated with the key, which can be
+ * retrieved later.
+ * @param cb Callback to be called when I/O operation completes.
+ * @param key Pointer to receive the key to be associated with this
+ * socket. Subsequent I/O queue operation will need this
+ * key.
+ *
+ * @return PJ_SUCCESS on success, or the error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_register_sock( pj_pool_t *pool,
+ pj_ioqueue_t *ioque,
+ pj_sock_t sock,
+ void *user_data,
+ const pj_ioqueue_callback *cb,
+ pj_ioqueue_key_t **key );
+
+/**
+ * Unregister from the I/O Queue framework. Caller must make sure that
+ * the key doesn't have any pending operations before calling this function,
* by calling #pj_ioqueue_is_pending() for all previously submitted
* operations except asynchronous connect, and if necessary call
* #pj_ioqueue_post_completion() to cancel the pending operations.
*
* Note that asynchronous connect operation will automatically be
- * cancelled during the unregistration. - * - * @param key The key that was previously obtained from registration. - * + * cancelled during the unregistration.
+ *
+ * @param key The key that was previously obtained from registration.
+ *
* @return PJ_SUCCESS on success or the error code.
*
- * @see pj_ioqueue_is_pending - */ -PJ_DECL(pj_status_t) pj_ioqueue_unregister( pj_ioqueue_key_t *key ); - - -/** - * Get user data associated with an ioqueue key. - * - * @param key The key that was previously obtained from registration. - * - * @return The user data associated with the descriptor, or NULL - * on error or if no data is associated with the key during - * registration. - */ -PJ_DECL(void*) pj_ioqueue_get_user_data( pj_ioqueue_key_t *key ); - -/** - * Set or change the user data to be associated with the file descriptor or - * handle or socket descriptor. - * - * @param key The key that was previously obtained from registration. - * @param user_data User data to be associated with the descriptor. - * @param old_data Optional parameter to retrieve the old user data. - * - * @return PJ_SUCCESS on success or the error code. - */ -PJ_DECL(pj_status_t) pj_ioqueue_set_user_data( pj_ioqueue_key_t *key, - void *user_data, - void **old_data); - + * @see pj_ioqueue_is_pending
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_unregister( pj_ioqueue_key_t *key );
+
+
+/**
+ * Get user data associated with an ioqueue key.
+ *
+ * @param key The key that was previously obtained from registration.
+ *
+ * @return The user data associated with the descriptor, or NULL
+ * on error or if no data is associated with the key during
+ * registration.
+ */
+PJ_DECL(void*) pj_ioqueue_get_user_data( pj_ioqueue_key_t *key );
+
+/**
+ * Set or change the user data to be associated with the file descriptor or
+ * handle or socket descriptor.
+ *
+ * @param key The key that was previously obtained from registration.
+ * @param user_data User data to be associated with the descriptor.
+ * @param old_data Optional parameter to retrieve the old user data.
+ *
+ * @return PJ_SUCCESS on success or the error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_set_user_data( pj_ioqueue_key_t *key,
+ void *user_data,
+ void **old_data);
+
/**
* Initialize operation key.
@@ -384,256 +405,256 @@ PJ_DECL(pj_status_t) pj_ioqueue_post_completion( pj_ioqueue_key_t *key, pj_ssize_t bytes_status );
- -#if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0 -/** - * Instruct I/O Queue to accept incoming connection on the specified - * listening socket. This function will return immediately (i.e. non-blocking) - * regardless whether a connection is immediately available. If the function - * can't complete immediately, the caller will be notified about the incoming - * connection when it calls pj_ioqueue_poll(). If a new connection is - * immediately available, the function returns PJ_SUCCESS with the new - * connection; in this case, the callback WILL NOT be called. - * - * @param key The key which registered to the server socket. - * @param op_key An operation specific key to be associated with the - * pending operation, so that application can keep track of - * which operation has been completed when the callback is - * called. - * @param new_sock Argument which contain pointer to receive the new socket - * for the incoming connection. - * @param local Optional argument which contain pointer to variable to - * receive local address. - * @param remote Optional argument which contain pointer to variable to - * receive the remote address. - * @param addrlen On input, contains the length of the buffer for the - * address, and on output, contains the actual length of the - * address. This argument is optional. - * @return - * - PJ_SUCCESS When connection is available immediately, and the - * parameters will be updated to contain information about - * the new connection. In this case, a completion callback - * WILL NOT be called. - * - PJ_EPENDING If no connection is available immediately. When a new - * connection arrives, the callback will be called. - * - non-zero which indicates the appropriate error code. - */ -PJ_DECL(pj_status_t) pj_ioqueue_accept( pj_ioqueue_key_t *key, - pj_ioqueue_op_key_t *op_key, - pj_sock_t *sock, - pj_sockaddr_t *local, - pj_sockaddr_t *remote, - int *addrlen ); - -/** - * Initiate non-blocking socket connect. If the socket can NOT be connected - * immediately, asynchronous connect() will be scheduled and caller will be - * notified via completion callback when it calls pj_ioqueue_poll(). If - * socket is connected immediately, the function returns PJ_SUCCESS and - * completion callback WILL NOT be called. - * - * @param key The key associated with TCP socket - * @param addr The remote address. - * @param addrlen The remote address length. - * - * @return - * - PJ_SUCCESS If socket is connected immediately. In this case, the - * completion callback WILL NOT be called. - * - PJ_EPENDING If operation is queued, or - * - non-zero Indicates the error code. - */ -PJ_DECL(pj_status_t) pj_ioqueue_connect( pj_ioqueue_key_t *key, - const pj_sockaddr_t *addr, - int addrlen ); - -#endif /* PJ_HAS_TCP */ - -/** - * Poll the I/O Queue for completed events. - * - * @param ioque the I/O Queue. - * @param timeout polling timeout, or NULL if the thread wishes to wait - * indefinetely for the event. - * - * @return - * - zero if timed out (no event). - * - (<0) if error occured during polling. Callback will NOT be called. - * - (>1) to indicate numbers of events. Callbacks have been called. - */ -PJ_DECL(int) pj_ioqueue_poll( pj_ioqueue_t *ioque, - const pj_time_val *timeout); - - -/** - * Instruct the I/O Queue to read from the specified handle. This function - * returns immediately (i.e. non-blocking) regardless whether some data has - * been transfered. If the operation can't complete immediately, caller will - * be notified about the completion when it calls pj_ioqueue_poll(). If data - * is immediately available, the function will return PJ_SUCCESS and the - * callback WILL NOT be called. - * - * @param key The key that uniquely identifies the handle. - * @param op_key An operation specific key to be associated with the - * pending operation, so that application can keep track of - * which operation has been completed when the callback is - * called. Caller must make sure that this key remains - * valid until the function completes. - * @param buffer The buffer to hold the read data. The caller MUST make sure - * that this buffer remain valid until the framework completes - * reading the handle. - * @param length On input, it specifies the size of the buffer. If data is - * available to be read immediately, the function returns - * PJ_SUCCESS and this argument will be filled with the - * amount of data read. If the function is pending, caller - * will be notified about the amount of data read in the - * callback. This parameter can point to local variable in - * caller's stack and doesn't have to remain valid for the - * duration of pending operation. - * @param flags Recv flag. - * - * @return - * - PJ_SUCCESS If immediate data has been received in the buffer. In this - * case, the callback WILL NOT be called. - * - PJ_EPENDING If the operation has been queued, and the callback will be - * called when data has been received. - * - non-zero The return value indicates the error code. - */ -PJ_DECL(pj_status_t) pj_ioqueue_recv( pj_ioqueue_key_t *key, - pj_ioqueue_op_key_t *op_key, - void *buffer, - pj_ssize_t *length, - unsigned flags ); - -/** - * This function behaves similarly as #pj_ioqueue_recv(), except that it is - * normally called for socket, and the remote address will also be returned - * along with the data. Caller MUST make sure that both buffer and addr - * remain valid until the framework completes reading the data. - * - * @param key The key that uniquely identifies the handle. - * @param op_key An operation specific key to be associated with the - * pending operation, so that application can keep track of - * which operation has been completed when the callback is - * called. - * @param buffer The buffer to hold the read data. The caller MUST make sure - * that this buffer remain valid until the framework completes - * reading the handle. - * @param length On input, it specifies the size of the buffer. If data is - * available to be read immediately, the function returns - * PJ_SUCCESS and this argument will be filled with the - * amount of data read. If the function is pending, caller - * will be notified about the amount of data read in the - * callback. This parameter can point to local variable in - * caller's stack and doesn't have to remain valid for the - * duration of pending operation. - * @param flags Recv flag. - * @param addr Optional Pointer to buffer to receive the address. - * @param addrlen On input, specifies the length of the address buffer. - * On output, it will be filled with the actual length of - * the address. This argument can be NULL if \c addr is not - * specified. - * - * @return - * - PJ_SUCCESS If immediate data has been received. In this case, the - * callback must have been called before this function - * returns, and no pending operation is scheduled. - * - PJ_EPENDING If the operation has been queued. - * - non-zero The return value indicates the error code. - */ -PJ_DECL(pj_status_t) pj_ioqueue_recvfrom( pj_ioqueue_key_t *key, - pj_ioqueue_op_key_t *op_key, - void *buffer, - pj_ssize_t *length, - unsigned flags, - pj_sockaddr_t *addr, - int *addrlen); - -/** - * Instruct the I/O Queue to write to the handle. This function will return - * immediately (i.e. non-blocking) regardless whether some data has been - * transfered. If the function can't complete immediately, the caller will - * be notified about the completion when it calls pj_ioqueue_poll(). If - * operation completes immediately and data has been transfered, the function - * returns PJ_SUCCESS and the callback will NOT be called. - * - * @param key The key that identifies the handle. - * @param op_key An operation specific key to be associated with the - * pending operation, so that application can keep track of - * which operation has been completed when the callback is - * called. - * @param data The data to send. Caller MUST make sure that this buffer - * remains valid until the write operation completes. - * @param length On input, it specifies the length of data to send. When - * data was sent immediately, this function returns PJ_SUCCESS - * and this parameter contains the length of data sent. If - * data can not be sent immediately, an asynchronous operation - * is scheduled and caller will be notified via callback the - * number of bytes sent. This parameter can point to local - * variable on caller's stack and doesn't have to remain - * valid until the operation has completed. - * @param flags Send flags. - * - * @return - * - PJ_SUCCESS If data was immediately transfered. In this case, no - * pending operation has been scheduled and the callback - * WILL NOT be called. - * - PJ_EPENDING If the operation has been queued. Once data base been - * transfered, the callback will be called. - * - non-zero The return value indicates the error code. - */ -PJ_DECL(pj_status_t) pj_ioqueue_send( pj_ioqueue_key_t *key, - pj_ioqueue_op_key_t *op_key, - const void *data, - pj_ssize_t *length, - unsigned flags ); - - -/** - * Instruct the I/O Queue to write to the handle. This function will return - * immediately (i.e. non-blocking) regardless whether some data has been - * transfered. If the function can't complete immediately, the caller will - * be notified about the completion when it calls pj_ioqueue_poll(). If - * operation completes immediately and data has been transfered, the function - * returns PJ_SUCCESS and the callback will NOT be called. - * - * @param key the key that identifies the handle. - * @param op_key An operation specific key to be associated with the - * pending operation, so that application can keep track of - * which operation has been completed when the callback is - * called. - * @param data the data to send. Caller MUST make sure that this buffer - * remains valid until the write operation completes. - * @param length On input, it specifies the length of data to send. When - * data was sent immediately, this function returns PJ_SUCCESS - * and this parameter contains the length of data sent. If - * data can not be sent immediately, an asynchronous operation - * is scheduled and caller will be notified via callback the - * number of bytes sent. This parameter can point to local - * variable on caller's stack and doesn't have to remain - * valid until the operation has completed. - * @param flags send flags. - * @param addr Optional remote address. - * @param addrlen Remote address length, \c addr is specified. - * - * @return - * - PJ_SUCCESS If data was immediately written. - * - PJ_EPENDING If the operation has been queued. - * - non-zero The return value indicates the error code. - */ -PJ_DECL(pj_status_t) pj_ioqueue_sendto( pj_ioqueue_key_t *key, - pj_ioqueue_op_key_t *op_key, - const void *data, - pj_ssize_t *length, - unsigned flags, - const pj_sockaddr_t *addr, - int addrlen); - - -/** - * !} - */ - -PJ_END_DECL - -#endif /* __PJ_IOQUEUE_H__ */ - +
+#if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0
+/**
+ * Instruct I/O Queue to accept incoming connection on the specified
+ * listening socket. This function will return immediately (i.e. non-blocking)
+ * regardless whether a connection is immediately available. If the function
+ * can't complete immediately, the caller will be notified about the incoming
+ * connection when it calls pj_ioqueue_poll(). If a new connection is
+ * immediately available, the function returns PJ_SUCCESS with the new
+ * connection; in this case, the callback WILL NOT be called.
+ *
+ * @param key The key which registered to the server socket.
+ * @param op_key An operation specific key to be associated with the
+ * pending operation, so that application can keep track of
+ * which operation has been completed when the callback is
+ * called.
+ * @param new_sock Argument which contain pointer to receive the new socket
+ * for the incoming connection.
+ * @param local Optional argument which contain pointer to variable to
+ * receive local address.
+ * @param remote Optional argument which contain pointer to variable to
+ * receive the remote address.
+ * @param addrlen On input, contains the length of the buffer for the
+ * address, and on output, contains the actual length of the
+ * address. This argument is optional.
+ * @return
+ * - PJ_SUCCESS When connection is available immediately, and the
+ * parameters will be updated to contain information about
+ * the new connection. In this case, a completion callback
+ * WILL NOT be called.
+ * - PJ_EPENDING If no connection is available immediately. When a new
+ * connection arrives, the callback will be called.
+ * - non-zero which indicates the appropriate error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_accept( pj_ioqueue_key_t *key,
+ pj_ioqueue_op_key_t *op_key,
+ pj_sock_t *sock,
+ pj_sockaddr_t *local,
+ pj_sockaddr_t *remote,
+ int *addrlen );
+
+/**
+ * Initiate non-blocking socket connect. If the socket can NOT be connected
+ * immediately, asynchronous connect() will be scheduled and caller will be
+ * notified via completion callback when it calls pj_ioqueue_poll(). If
+ * socket is connected immediately, the function returns PJ_SUCCESS and
+ * completion callback WILL NOT be called.
+ *
+ * @param key The key associated with TCP socket
+ * @param addr The remote address.
+ * @param addrlen The remote address length.
+ *
+ * @return
+ * - PJ_SUCCESS If socket is connected immediately. In this case, the
+ * completion callback WILL NOT be called.
+ * - PJ_EPENDING If operation is queued, or
+ * - non-zero Indicates the error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_connect( pj_ioqueue_key_t *key,
+ const pj_sockaddr_t *addr,
+ int addrlen );
+
+#endif /* PJ_HAS_TCP */
+
+/**
+ * Poll the I/O Queue for completed events.
+ *
+ * @param ioque the I/O Queue.
+ * @param timeout polling timeout, or NULL if the thread wishes to wait
+ * indefinetely for the event.
+ *
+ * @return
+ * - zero if timed out (no event).
+ * - (<0) if error occured during polling. Callback will NOT be called.
+ * - (>1) to indicate numbers of events. Callbacks have been called.
+ */
+PJ_DECL(int) pj_ioqueue_poll( pj_ioqueue_t *ioque,
+ const pj_time_val *timeout);
+
+
+/**
+ * Instruct the I/O Queue to read from the specified handle. This function
+ * returns immediately (i.e. non-blocking) regardless whether some data has
+ * been transfered. If the operation can't complete immediately, caller will
+ * be notified about the completion when it calls pj_ioqueue_poll(). If data
+ * is immediately available, the function will return PJ_SUCCESS and the
+ * callback WILL NOT be called.
+ *
+ * @param key The key that uniquely identifies the handle.
+ * @param op_key An operation specific key to be associated with the
+ * pending operation, so that application can keep track of
+ * which operation has been completed when the callback is
+ * called. Caller must make sure that this key remains
+ * valid until the function completes.
+ * @param buffer The buffer to hold the read data. The caller MUST make sure
+ * that this buffer remain valid until the framework completes
+ * reading the handle.
+ * @param length On input, it specifies the size of the buffer. If data is
+ * available to be read immediately, the function returns
+ * PJ_SUCCESS and this argument will be filled with the
+ * amount of data read. If the function is pending, caller
+ * will be notified about the amount of data read in the
+ * callback. This parameter can point to local variable in
+ * caller's stack and doesn't have to remain valid for the
+ * duration of pending operation.
+ * @param flags Recv flag.
+ *
+ * @return
+ * - PJ_SUCCESS If immediate data has been received in the buffer. In this
+ * case, the callback WILL NOT be called.
+ * - PJ_EPENDING If the operation has been queued, and the callback will be
+ * called when data has been received.
+ * - non-zero The return value indicates the error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_recv( pj_ioqueue_key_t *key,
+ pj_ioqueue_op_key_t *op_key,
+ void *buffer,
+ pj_ssize_t *length,
+ unsigned flags );
+
+/**
+ * This function behaves similarly as #pj_ioqueue_recv(), except that it is
+ * normally called for socket, and the remote address will also be returned
+ * along with the data. Caller MUST make sure that both buffer and addr
+ * remain valid until the framework completes reading the data.
+ *
+ * @param key The key that uniquely identifies the handle.
+ * @param op_key An operation specific key to be associated with the
+ * pending operation, so that application can keep track of
+ * which operation has been completed when the callback is
+ * called.
+ * @param buffer The buffer to hold the read data. The caller MUST make sure
+ * that this buffer remain valid until the framework completes
+ * reading the handle.
+ * @param length On input, it specifies the size of the buffer. If data is
+ * available to be read immediately, the function returns
+ * PJ_SUCCESS and this argument will be filled with the
+ * amount of data read. If the function is pending, caller
+ * will be notified about the amount of data read in the
+ * callback. This parameter can point to local variable in
+ * caller's stack and doesn't have to remain valid for the
+ * duration of pending operation.
+ * @param flags Recv flag.
+ * @param addr Optional Pointer to buffer to receive the address.
+ * @param addrlen On input, specifies the length of the address buffer.
+ * On output, it will be filled with the actual length of
+ * the address. This argument can be NULL if \c addr is not
+ * specified.
+ *
+ * @return
+ * - PJ_SUCCESS If immediate data has been received. In this case, the
+ * callback must have been called before this function
+ * returns, and no pending operation is scheduled.
+ * - PJ_EPENDING If the operation has been queued.
+ * - non-zero The return value indicates the error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_recvfrom( pj_ioqueue_key_t *key,
+ pj_ioqueue_op_key_t *op_key,
+ void *buffer,
+ pj_ssize_t *length,
+ unsigned flags,
+ pj_sockaddr_t *addr,
+ int *addrlen);
+
+/**
+ * Instruct the I/O Queue to write to the handle. This function will return
+ * immediately (i.e. non-blocking) regardless whether some data has been
+ * transfered. If the function can't complete immediately, the caller will
+ * be notified about the completion when it calls pj_ioqueue_poll(). If
+ * operation completes immediately and data has been transfered, the function
+ * returns PJ_SUCCESS and the callback will NOT be called.
+ *
+ * @param key The key that identifies the handle.
+ * @param op_key An operation specific key to be associated with the
+ * pending operation, so that application can keep track of
+ * which operation has been completed when the callback is
+ * called.
+ * @param data The data to send. Caller MUST make sure that this buffer
+ * remains valid until the write operation completes.
+ * @param length On input, it specifies the length of data to send. When
+ * data was sent immediately, this function returns PJ_SUCCESS
+ * and this parameter contains the length of data sent. If
+ * data can not be sent immediately, an asynchronous operation
+ * is scheduled and caller will be notified via callback the
+ * number of bytes sent. This parameter can point to local
+ * variable on caller's stack and doesn't have to remain
+ * valid until the operation has completed.
+ * @param flags Send flags.
+ *
+ * @return
+ * - PJ_SUCCESS If data was immediately transfered. In this case, no
+ * pending operation has been scheduled and the callback
+ * WILL NOT be called.
+ * - PJ_EPENDING If the operation has been queued. Once data base been
+ * transfered, the callback will be called.
+ * - non-zero The return value indicates the error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_send( pj_ioqueue_key_t *key,
+ pj_ioqueue_op_key_t *op_key,
+ const void *data,
+ pj_ssize_t *length,
+ unsigned flags );
+
+
+/**
+ * Instruct the I/O Queue to write to the handle. This function will return
+ * immediately (i.e. non-blocking) regardless whether some data has been
+ * transfered. If the function can't complete immediately, the caller will
+ * be notified about the completion when it calls pj_ioqueue_poll(). If
+ * operation completes immediately and data has been transfered, the function
+ * returns PJ_SUCCESS and the callback will NOT be called.
+ *
+ * @param key the key that identifies the handle.
+ * @param op_key An operation specific key to be associated with the
+ * pending operation, so that application can keep track of
+ * which operation has been completed when the callback is
+ * called.
+ * @param data the data to send. Caller MUST make sure that this buffer
+ * remains valid until the write operation completes.
+ * @param length On input, it specifies the length of data to send. When
+ * data was sent immediately, this function returns PJ_SUCCESS
+ * and this parameter contains the length of data sent. If
+ * data can not be sent immediately, an asynchronous operation
+ * is scheduled and caller will be notified via callback the
+ * number of bytes sent. This parameter can point to local
+ * variable on caller's stack and doesn't have to remain
+ * valid until the operation has completed.
+ * @param flags send flags.
+ * @param addr Optional remote address.
+ * @param addrlen Remote address length, \c addr is specified.
+ *
+ * @return
+ * - PJ_SUCCESS If data was immediately written.
+ * - PJ_EPENDING If the operation has been queued.
+ * - non-zero The return value indicates the error code.
+ */
+PJ_DECL(pj_status_t) pj_ioqueue_sendto( pj_ioqueue_key_t *key,
+ pj_ioqueue_op_key_t *op_key,
+ const void *data,
+ pj_ssize_t *length,
+ unsigned flags,
+ const pj_sockaddr_t *addr,
+ int addrlen);
+
+
+/**
+ * !}
+ */
+
+PJ_END_DECL
+
+#endif /* __PJ_IOQUEUE_H__ */
+
|