| /* $Id$ */ |
| /* |
| * Copyright (C)2003-2006 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_EQUEUE_H__ |
| #define __PJ_EQUEUE_H__ |
| |
| /** |
| * @file equeue.h |
| * @brief Event Queue |
| */ |
| #include <pj/types.h> |
| |
| |
| PJ_BEGIN_DECL |
| |
| /** |
| * @defgroup PJ_EQUEUE Event Queue |
| * @brief Event Queue |
| * @ingroup PJ_OS |
| * @{ |
| */ |
| |
| |
| /** |
| * Opaque data type for Event Queue. |
| */ |
| typedef struct pj_equeue_t pj_equeue_t; |
| |
| /** |
| * Opaque data type for Event Queue key. |
| */ |
| typedef struct pj_equeue_key_t pj_equeue_key_t; |
| |
| |
| /** |
| * This structure describes the callbacks to be called when I/O operation |
| * completes. |
| */ |
| typedef struct pj_io_callback |
| { |
| /** |
| * This callback is called when #pj_equeue_read, #pj_equeue_recv or |
| * #pj_equeue_recvfrom completes. |
| * |
| * @param key The key. |
| * @param bytes_read The size of data that has just been read. |
| */ |
| void (*on_read_complete)(pj_equeue_key_t *key, pj_ssize_t bytes_read); |
| |
| /** |
| * This callback is called when #pj_equeue_write, #pj_equeue_send, or |
| * #pj_equeue_sendto completes. |
| * |
| * @param key The key. |
| * @param bytes_read The size of data that has just been written. |
| */ |
| void (*on_write_complete)(pj_equeue_key_t *key, pj_ssize_t bytes_sent); |
| |
| /** |
| * This callback is called when #pj_equeue_accept completes. |
| * |
| * @param key The key. |
| * @param status Zero if the operation completes successfully. |
| */ |
| void (*on_accept_complete)(pj_equeue_key_t *key, int status); |
| |
| /** |
| * This callback is called when #pj_equeue_connect completes. |
| * |
| * @param key The key. |
| * @param status Zero if the operation completes successfully. |
| */ |
| void (*on_connect_complete)(pj_equeue_key_t *key, int status); |
| |
| } pj_io_callback; |
| |
| /** |
| * Event Queue options. |
| */ |
| typedef struct pj_equeue_options |
| { |
| /** Maximum number of threads that are allowed to access Event Queue |
| * simulteneously. |
| */ |
| unsigned nb_threads; |
| |
| /** If non-zero, then no mutex protection will be used. */ |
| pj_bool_t no_lock; |
| |
| /** Interval of the busy loop inside the event queue. |
| * The time resolution here determines the accuracy of the |
| * timer in the Event Queue. |
| */ |
| pj_time_val poll_interval; |
| |
| } pj_equeue_options; |
| |
| |
| /** |
| * Error value returned by I/O operations to indicate that the operation |
| * can't complete immediately and will complete later. |
| */ |
| #define PJ_EQUEUE_PENDING (-2) |
| |
| /** |
| * Types of Event Queue operation. |
| */ |
| typedef enum pj_equeue_op |
| { |
| PJ_EQUEUE_OP_NONE = 0, /**< No operation. */ |
| PJ_EQUEUE_OP_READ = 1, /**< read() operation. */ |
| PJ_EQUEUE_OP_RECV_FROM = 2, /**< recvfrom() operation. */ |
| PJ_EQUEUE_OP_WRITE = 4, /**< write() operation. */ |
| PJ_EQUEUE_OP_SEND_TO = 8, /**< sendto() operation. */ |
| #if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0 |
| PJ_EQUEUE_OP_ACCEPT = 16, /**< accept() operation. */ |
| PJ_EQUEUE_OP_CONNECT = 32, /**< connect() operation. */ |
| #endif /* PJ_HAS_TCP */ |
| } pj_equeue_op; |
| |
| |
| |
| /** |
| * Initialize Event Queue options with default values. |
| * |
| * @param options Event Queue options. |
| */ |
| PJ_DECL(void) pj_equeue_options_init(pj_equeue_options *options); |
| |
| /** |
| * Create a new Event Queue framework. |
| * |
| * @param pool The pool to allocate the event queue structure. |
| * @param options Event queue options, or if NULL is given, then |
| * default options will be used. |
| * @param equeue Pointer to receive event queue structure. |
| * |
| * @return zero on success. |
| */ |
| PJ_DECL(pj_status_t) pj_equeue_create( pj_pool_t *pool, |
| const pj_equeue_options *options, |
| pj_equeue_t **equeue); |
| |
| /** |
| * Get the first instance of Event Queue, or NULL if no Event Queue |
| * instance has been created in the application. |
| * |
| * @return The first instance of Event Queue created, or NULL. |
| */ |
| PJ_DECL(pj_equeue_t*) pj_equeue_instance(void); |
| |
| /** |
| * Destroy the Event Queue. |
| * |
| * @param equeue The Event Queue instance to be destroyed. |
| */ |
| PJ_DECL(pj_status_t) pj_equeue_destroy( pj_equeue_t *equeue ); |
| |
| /** |
| * Customize the lock object that is used by the Event Queue. |
| * |
| * @param equeue The Event Queue instance. |
| * @param lock The lock object. |
| * @param auto_del If non-zero, the lock will be destroyed by |
| * Event Queue. |
| * |
| * @return Zero on success. |
| */ |
| PJ_DECL(pj_status_t) pj_equeue_set_lock( pj_equeue_t *equeue, |
| pj_lock_t *lock, |
| pj_bool_t auto_del); |
| |
| /** |
| * Associate an Event Queue key to particular handle. The key is also |
| * associated with the callback and user data, which will be used by |
| * the Event Queue framework when signalling event back to application. |
| * |
| * @param pool To allocate the resource for the specified handle, which |
| * must be valid until the handle/key is unregistered |
| * from Event Queue. |
| * @param equeue The Event Queue. |
| * @param hnd The OS handle to be registered, which can be a socket |
| * descriptor (pj_sock_t), file descriptor, etc. |
| * @param cb Callback to be called when I/O operation completes. |
| * @param user_data User data to be associated with the key. |
| * @param key Pointer to receive the key. |
| * |
| * @return Zero on success. |
| */ |
| PJ_DECL(pj_status_t) pj_equeue_register( pj_pool_t *pool, |
| pj_equeue_t *equeue, |
| pj_oshandle_t hnd, |
| pj_io_callback *cb, |
| void *user_data, |
| pj_equeue_key_t **key); |
| |
| /** |
| * Retrieve user data associated with a key. |
| * |
| * @param key The Event Queue key. |
| * |
| * @return User data associated with the key. |
| */ |
| PJ_DECL(void*) pj_equeue_get_user_data( pj_equeue_key_t *key ); |
| |
| |
| /** |
| * Unregister Event Queue key from the Event Queue. |
| * |
| * @param equeue The Event Queue. |
| * @param key The key. |
| * |
| * @return Zero on success. |
| */ |
| PJ_DECL(pj_status_t) pj_equeue_unregister( pj_equeue_t *equeue, |
| pj_equeue_key_t *key); |
| |
| /** |
| * Instruct the Event 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_equeue_poll(). |
| * |
| * @param key The key that uniquely identifies the handle. |
| * @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 size The maximum size to be read. |
| * |
| * @return |
| * - zero or positive number to indicate the number of bytes has been |
| * read, and in this case the operation was not queued. |
| * - (-1) on error, which in this case operation was not queued. |
| * - PJ_EQUEUE_PENDING if the operation has been queued. |
| */ |
| PJ_DECL(pj_ssize_t) pj_equeue_read( pj_equeue_key_t *key, |
| void *buffer, |
| pj_size_t size); |
| |
| /** |
| * Start recv() operation on the specified handle. |
| * |
| * @see ::pj_ioqueue_read |
| */ |
| PJ_DECL(pj_ssize_t) pj_equeue_recv( pj_equeue_key_t *key, |
| void *buf, |
| pj_size_t size, |
| unsigned flags); |
| |
| /** |
| * Start recvfrom() operation on the specified handle. |
| * |
| * @see ::pj_equeue_read |
| */ |
| PJ_DECL(pj_ssize_t) pj_equeue_recvfrom( pj_equeue_key_t *key, |
| void *buf, |
| pj_size_t size, |
| unsigned flags, |
| pj_sockaddr_t *addr, |
| int *addrlen ); |
| |
| /** |
| * Write. |
| */ |
| PJ_DECL(pj_ssize_t) pj_equeue_write( pj_equeue_key_t *key, |
| const void *buf, |
| pj_size_t size); |
| |
| /** |
| * Send. |
| */ |
| PJ_DECL(pj_ssize_t) pj_equeue_send( pj_equeue_key_t *key, |
| const void *buf, |
| pj_size_t size, |
| unsigned flags); |
| |
| /** |
| * Sendto. |
| */ |
| PJ_DECL(pj_ssize_t) pj_equeue_sendto( pj_equeue_key_t *key, |
| const void *buf, |
| pj_size_t size, |
| unsigned flags, |
| const pj_sockaddr_t *addr, |
| int addrlen); |
| |
| /** |
| * Schedule timer. |
| */ |
| PJ_DECL(pj_status_t) pj_equeue_schedule_timer( pj_equeue_t *equeue, |
| const pj_time_val *timeout, |
| pj_timer_entry *entry); |
| |
| /** |
| * Cancel timer. |
| */ |
| PJ_DECL(pj_status_t) pj_equeue_cancel_timer( pj_equeue_t *equeue, |
| pj_timer_entry *entry); |
| |
| /** |
| * Poll for events. |
| */ |
| PJ_DECL(pj_status_t) pj_equeue_poll( pj_equeue_t *equeue, |
| const pj_time_val *timeout ); |
| |
| /** |
| * Run. |
| */ |
| PJ_DECL(pj_status_t) pj_equeue_run( pj_equeue_t *equeue ); |
| |
| /** |
| * Stop all running threads. |
| */ |
| PJ_DECL(pj_status_t) pj_equeue_stop( pj_equeue_t *equeue ); |
| |
| |
| /** @} */ |
| |
| PJ_END_DECL |
| |
| #endif /* __PJ_EQUEUE_H__ */ |