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