Benny Prijono | e0312a7 | 2005-11-18 00:16:43 +0000 | [diff] [blame] | 1 | /* $Id$ */
|
Benny Prijono | e722461 | 2005-11-13 19:40:44 +0000 | [diff] [blame] | 2 | /*
|
Benny Prijono | e0312a7 | 2005-11-18 00:16:43 +0000 | [diff] [blame] | 3 | * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
|
Benny Prijono | e722461 | 2005-11-13 19:40:44 +0000 | [diff] [blame] | 4 | *
|
Benny Prijono | e0312a7 | 2005-11-18 00:16:43 +0000 | [diff] [blame] | 5 | * This program is free software; you can redistribute it and/or modify
|
| 6 | * it under the terms of the GNU General Public License as published by
|
| 7 | * the Free Software Foundation; either version 2 of the License, or
|
| 8 | * (at your option) any later version.
|
Benny Prijono | e722461 | 2005-11-13 19:40:44 +0000 | [diff] [blame] | 9 | *
|
Benny Prijono | e0312a7 | 2005-11-18 00:16:43 +0000 | [diff] [blame] | 10 | * This program is distributed in the hope that it will be useful,
|
Benny Prijono | e722461 | 2005-11-13 19:40:44 +0000 | [diff] [blame] | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
Benny Prijono | e0312a7 | 2005-11-18 00:16:43 +0000 | [diff] [blame] | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 13 | * GNU General Public License for more details.
|
| 14 | *
|
| 15 | * You should have received a copy of the GNU General Public License
|
| 16 | * along with this program; if not, write to the Free Software
|
| 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
Benny Prijono | e722461 | 2005-11-13 19:40:44 +0000 | [diff] [blame] | 18 | */
|
| 19 | #ifndef __PJ_EQUEUE_H__
|
| 20 | #define __PJ_EQUEUE_H__
|
| 21 |
|
| 22 | /**
|
| 23 | * @file equeue.h
|
| 24 | * @brief Event Queue
|
| 25 | */
|
| 26 | #include <pj/types.h>
|
| 27 |
|
| 28 |
|
| 29 | PJ_BEGIN_DECL
|
| 30 |
|
| 31 | /**
|
| 32 | * @defgroup PJ_EQUEUE Event Queue
|
| 33 | * @brief Event Queue
|
| 34 | * @ingroup PJ_OS
|
| 35 | * @{
|
| 36 | */
|
| 37 |
|
| 38 |
|
| 39 | /**
|
| 40 | * Opaque data type for Event Queue.
|
| 41 | */
|
| 42 | typedef struct pj_equeue_t pj_equeue_t;
|
| 43 |
|
| 44 | /**
|
| 45 | * Opaque data type for Event Queue key.
|
| 46 | */
|
| 47 | typedef struct pj_equeue_key_t pj_equeue_key_t;
|
| 48 |
|
| 49 |
|
| 50 | /**
|
| 51 | * This structure describes the callbacks to be called when I/O operation
|
| 52 | * completes.
|
| 53 | */
|
| 54 | typedef struct pj_io_callback
|
| 55 | {
|
| 56 | /**
|
| 57 | * This callback is called when #pj_equeue_read, #pj_equeue_recv or
|
| 58 | * #pj_equeue_recvfrom completes.
|
| 59 | *
|
| 60 | * @param key The key.
|
| 61 | * @param bytes_read The size of data that has just been read.
|
| 62 | */
|
| 63 | void (*on_read_complete)(pj_equeue_key_t *key, pj_ssize_t bytes_read);
|
| 64 |
|
| 65 | /**
|
| 66 | * This callback is called when #pj_equeue_write, #pj_equeue_send, or
|
| 67 | * #pj_equeue_sendto completes.
|
| 68 | *
|
| 69 | * @param key The key.
|
| 70 | * @param bytes_read The size of data that has just been written.
|
| 71 | */
|
| 72 | void (*on_write_complete)(pj_equeue_key_t *key, pj_ssize_t bytes_sent);
|
| 73 |
|
| 74 | /**
|
| 75 | * This callback is called when #pj_equeue_accept completes.
|
| 76 | *
|
| 77 | * @param key The key.
|
| 78 | * @param status Zero if the operation completes successfully.
|
| 79 | */
|
| 80 | void (*on_accept_complete)(pj_equeue_key_t *key, int status);
|
| 81 |
|
| 82 | /**
|
| 83 | * This callback is called when #pj_equeue_connect completes.
|
| 84 | *
|
| 85 | * @param key The key.
|
| 86 | * @param status Zero if the operation completes successfully.
|
| 87 | */
|
| 88 | void (*on_connect_complete)(pj_equeue_key_t *key, int status);
|
| 89 |
|
| 90 | } pj_io_callback;
|
| 91 |
|
| 92 | /**
|
| 93 | * Event Queue options.
|
| 94 | */
|
| 95 | typedef struct pj_equeue_options
|
| 96 | {
|
| 97 | /** Maximum number of threads that are allowed to access Event Queue
|
| 98 | * simulteneously.
|
| 99 | */
|
| 100 | unsigned nb_threads;
|
| 101 |
|
| 102 | /** If non-zero, then no mutex protection will be used. */
|
| 103 | pj_bool_t no_lock;
|
| 104 |
|
| 105 | /** Interval of the busy loop inside the event queue.
|
| 106 | * The time resolution here determines the accuracy of the
|
| 107 | * timer in the Event Queue.
|
| 108 | */
|
| 109 | pj_time_val poll_interval;
|
| 110 |
|
| 111 | } pj_equeue_options;
|
| 112 |
|
| 113 |
|
| 114 | /**
|
| 115 | * Error value returned by I/O operations to indicate that the operation
|
| 116 | * can't complete immediately and will complete later.
|
| 117 | */
|
| 118 | #define PJ_EQUEUE_PENDING (-2)
|
| 119 |
|
| 120 | /**
|
| 121 | * Types of Event Queue operation.
|
| 122 | */
|
| 123 | typedef enum pj_equeue_op
|
| 124 | {
|
| 125 | PJ_EQUEUE_OP_NONE = 0, /**< No operation. */
|
| 126 | PJ_EQUEUE_OP_READ = 1, /**< read() operation. */
|
| 127 | PJ_EQUEUE_OP_RECV_FROM = 2, /**< recvfrom() operation. */
|
| 128 | PJ_EQUEUE_OP_WRITE = 4, /**< write() operation. */
|
| 129 | PJ_EQUEUE_OP_SEND_TO = 8, /**< sendto() operation. */
|
| 130 | #if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0
|
| 131 | PJ_EQUEUE_OP_ACCEPT = 16, /**< accept() operation. */
|
| 132 | PJ_EQUEUE_OP_CONNECT = 32, /**< connect() operation. */
|
| 133 | #endif /* PJ_HAS_TCP */
|
| 134 | } pj_equeue_op;
|
| 135 |
|
| 136 |
|
| 137 |
|
| 138 | /**
|
| 139 | * Initialize Event Queue options with default values.
|
| 140 | *
|
| 141 | * @param options Event Queue options.
|
| 142 | */
|
| 143 | PJ_DECL(void) pj_equeue_options_init(pj_equeue_options *options);
|
| 144 |
|
| 145 | /**
|
| 146 | * Create a new Event Queue framework.
|
| 147 | *
|
| 148 | * @param pool The pool to allocate the event queue structure.
|
| 149 | * @param options Event queue options, or if NULL is given, then
|
| 150 | * default options will be used.
|
| 151 | * @param equeue Pointer to receive event queue structure.
|
| 152 | *
|
| 153 | * @return zero on success.
|
| 154 | */
|
| 155 | PJ_DECL(pj_status_t) pj_equeue_create( pj_pool_t *pool,
|
| 156 | const pj_equeue_options *options,
|
| 157 | pj_equeue_t **equeue);
|
| 158 |
|
| 159 | /**
|
| 160 | * Get the first instance of Event Queue, or NULL if no Event Queue
|
| 161 | * instance has been created in the application.
|
| 162 | *
|
| 163 | * @return The first instance of Event Queue created, or NULL.
|
| 164 | */
|
| 165 | PJ_DECL(pj_equeue_t*) pj_equeue_instance(void);
|
| 166 |
|
| 167 | /**
|
| 168 | * Destroy the Event Queue.
|
| 169 | *
|
| 170 | * @param equeue The Event Queue instance to be destroyed.
|
| 171 | */
|
| 172 | PJ_DECL(pj_status_t) pj_equeue_destroy( pj_equeue_t *equeue );
|
| 173 |
|
| 174 | /**
|
| 175 | * Customize the lock object that is used by the Event Queue.
|
| 176 | *
|
| 177 | * @param equeue The Event Queue instance.
|
| 178 | * @param lock The lock object.
|
| 179 | * @param auto_del If non-zero, the lock will be destroyed by
|
| 180 | * Event Queue.
|
| 181 | *
|
| 182 | * @return Zero on success.
|
| 183 | */
|
| 184 | PJ_DECL(pj_status_t) pj_equeue_set_lock( pj_equeue_t *equeue,
|
| 185 | pj_lock_t *lock,
|
| 186 | pj_bool_t auto_del);
|
| 187 |
|
| 188 | /**
|
| 189 | * Associate an Event Queue key to particular handle. The key is also
|
| 190 | * associated with the callback and user data, which will be used by
|
| 191 | * the Event Queue framework when signalling event back to application.
|
| 192 | *
|
| 193 | * @param pool To allocate the resource for the specified handle, which
|
| 194 | * must be valid until the handle/key is unregistered
|
| 195 | * from Event Queue.
|
| 196 | * @param equeue The Event Queue.
|
| 197 | * @param hnd The OS handle to be registered, which can be a socket
|
| 198 | * descriptor (pj_sock_t), file descriptor, etc.
|
| 199 | * @param cb Callback to be called when I/O operation completes.
|
| 200 | * @param user_data User data to be associated with the key.
|
| 201 | * @param key Pointer to receive the key.
|
| 202 | *
|
| 203 | * @return Zero on success.
|
| 204 | */
|
| 205 | PJ_DECL(pj_status_t) pj_equeue_register( pj_pool_t *pool,
|
| 206 | pj_equeue_t *equeue,
|
| 207 | pj_oshandle_t hnd,
|
| 208 | pj_io_callback *cb,
|
| 209 | void *user_data,
|
| 210 | pj_equeue_key_t **key);
|
| 211 |
|
| 212 | /**
|
| 213 | * Retrieve user data associated with a key.
|
| 214 | *
|
| 215 | * @param key The Event Queue key.
|
| 216 | *
|
| 217 | * @return User data associated with the key.
|
| 218 | */
|
| 219 | PJ_DECL(void*) pj_equeue_get_user_data( pj_equeue_key_t *key );
|
| 220 |
|
| 221 |
|
| 222 | /**
|
| 223 | * Unregister Event Queue key from the Event Queue.
|
| 224 | *
|
| 225 | * @param equeue The Event Queue.
|
| 226 | * @param key The key.
|
| 227 | *
|
| 228 | * @return Zero on success.
|
| 229 | */
|
| 230 | PJ_DECL(pj_status_t) pj_equeue_unregister( pj_equeue_t *equeue,
|
| 231 | pj_equeue_key_t *key);
|
| 232 |
|
| 233 | /**
|
| 234 | * Instruct the Event Queue to read from the specified handle. This function
|
| 235 | * returns immediately (i.e. non-blocking) regardless whether some data has
|
| 236 | * been transfered. If the operation can't complete immediately, caller will
|
| 237 | * be notified about the completion when it calls pj_equeue_poll().
|
| 238 | *
|
| 239 | * @param key The key that uniquely identifies the handle.
|
| 240 | * @param buffer The buffer to hold the read data. The caller MUST make sure
|
| 241 | * that this buffer remain valid until the framework completes
|
| 242 | * reading the handle.
|
| 243 | * @param size The maximum size to be read.
|
| 244 | *
|
| 245 | * @return
|
| 246 | * - zero or positive number to indicate the number of bytes has been
|
| 247 | * read, and in this case the operation was not queued.
|
| 248 | * - (-1) on error, which in this case operation was not queued.
|
| 249 | * - PJ_EQUEUE_PENDING if the operation has been queued.
|
| 250 | */
|
| 251 | PJ_DECL(pj_ssize_t) pj_equeue_read( pj_equeue_key_t *key,
|
| 252 | void *buffer,
|
| 253 | pj_size_t size);
|
| 254 |
|
| 255 | /**
|
| 256 | * Start recv() operation on the specified handle.
|
| 257 | *
|
| 258 | * @see ::pj_ioqueue_read
|
| 259 | */
|
| 260 | PJ_DECL(pj_ssize_t) pj_equeue_recv( pj_equeue_key_t *key,
|
| 261 | void *buf,
|
| 262 | pj_size_t size,
|
| 263 | unsigned flags);
|
| 264 |
|
| 265 | /**
|
| 266 | * Start recvfrom() operation on the specified handle.
|
| 267 | *
|
| 268 | * @see ::pj_equeue_read
|
| 269 | */
|
| 270 | PJ_DECL(pj_ssize_t) pj_equeue_recvfrom( pj_equeue_key_t *key,
|
| 271 | void *buf,
|
| 272 | pj_size_t size,
|
| 273 | unsigned flags,
|
| 274 | pj_sockaddr_t *addr,
|
| 275 | int *addrlen );
|
| 276 |
|
| 277 | /**
|
| 278 | * Write.
|
| 279 | */
|
| 280 | PJ_DECL(pj_ssize_t) pj_equeue_write( pj_equeue_key_t *key,
|
| 281 | const void *buf,
|
| 282 | pj_size_t size);
|
| 283 |
|
| 284 | /**
|
| 285 | * Send.
|
| 286 | */
|
| 287 | PJ_DECL(pj_ssize_t) pj_equeue_send( pj_equeue_key_t *key,
|
| 288 | const void *buf,
|
| 289 | pj_size_t size,
|
| 290 | unsigned flags);
|
| 291 |
|
| 292 | /**
|
| 293 | * Sendto.
|
| 294 | */
|
| 295 | PJ_DECL(pj_ssize_t) pj_equeue_sendto( pj_equeue_key_t *key,
|
| 296 | const void *buf,
|
| 297 | pj_size_t size,
|
| 298 | unsigned flags,
|
| 299 | const pj_sockaddr_t *addr,
|
| 300 | int addrlen);
|
| 301 |
|
| 302 | /**
|
| 303 | * Schedule timer.
|
| 304 | */
|
| 305 | PJ_DECL(pj_status_t) pj_equeue_schedule_timer( pj_equeue_t *equeue,
|
| 306 | const pj_time_val *timeout,
|
| 307 | pj_timer_entry *entry);
|
| 308 |
|
| 309 | /**
|
| 310 | * Cancel timer.
|
| 311 | */
|
| 312 | PJ_DECL(pj_status_t) pj_equeue_cancel_timer( pj_equeue_t *equeue,
|
| 313 | pj_timer_entry *entry);
|
| 314 |
|
| 315 | /**
|
| 316 | * Poll for events.
|
| 317 | */
|
| 318 | PJ_DECL(pj_status_t) pj_equeue_poll( pj_equeue_t *equeue,
|
| 319 | const pj_time_val *timeout );
|
| 320 |
|
| 321 | /**
|
| 322 | * Run.
|
| 323 | */
|
| 324 | PJ_DECL(pj_status_t) pj_equeue_run( pj_equeue_t *equeue );
|
| 325 |
|
| 326 | /**
|
| 327 | * Stop all running threads.
|
| 328 | */
|
| 329 | PJ_DECL(pj_status_t) pj_equeue_stop( pj_equeue_t *equeue );
|
| 330 |
|
| 331 |
|
| 332 | /** @} */
|
| 333 |
|
| 334 | PJ_END_DECL
|
| 335 |
|
| 336 | #endif /* __PJ_EQUEUE_H__ */
|