⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ioqueue.h

📁 基于sip协议的网络电话源码
💻 H
📖 第 1 页 / 共 2 页
字号:
/* $Id: ioqueue.h 974 2007-02-19 01:13:53Z bennylp $ *//*  * Copyright (C)2003-2007 Benny Prijono <benny@prijono.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; 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 IOQueue: I/O Event Dispatching with Proactor Pattern * @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/** * When this flag is specified in ioqueue's recv() or send() operations, * the ioqueue will always mark the operation as asynchronous. */#define PJ_IOQUEUE_ALWAYS_ASYNC	    ((pj_uint32_t)1 << (pj_uint32_t)31)/** * 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. * * Also note that when I/O Completion Port backend is used, application * MUST close the handle immediately after unregistering the key. This is * because there is no unregistering API for IOCP. The only way to * unregister the handle from IOCP is to close the handle. * * @param key	    The key that was previously obtained from registration. *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -