320 lines
8.3 KiB
C
320 lines
8.3 KiB
C
/* $Header: /pjproject-0.3/pjlib/include/pj/equeue.h 2 10/14/05 12:26a Bennylp $ */
|
|
#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__ */
|