Benny Prijono | 4766ffe | 2005-11-01 17:56:59 +0000 | [diff] [blame] | 1 | /* $Id$ |
Benny Prijono | 4766ffe | 2005-11-01 17:56:59 +0000 | [diff] [blame] | 2 | */ |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 3 | |
| 4 | #ifndef __PJ_IOQUEUE_H__ |
| 5 | #define __PJ_IOQUEUE_H__ |
| 6 | |
| 7 | /** |
| 8 | * @file ioqueue.h |
| 9 | * @brief I/O Dispatching Mechanism |
| 10 | */ |
| 11 | |
| 12 | #include <pj/types.h> |
| 13 | |
| 14 | PJ_BEGIN_DECL |
| 15 | |
| 16 | /** |
| 17 | * @defgroup PJ_IO Network I/O |
| 18 | * @brief Network I/O |
| 19 | * @ingroup PJ_OS |
| 20 | * |
| 21 | * This section contains API building blocks to perform network I/O and |
| 22 | * communications. If provides: |
| 23 | * - @ref PJ_SOCK |
| 24 | *\n |
| 25 | * A highly portable socket abstraction, runs on all kind of |
| 26 | * network APIs such as standard BSD socket, Windows socket, Linux |
| 27 | * \b kernel socket, PalmOS networking API, etc. |
| 28 | * |
| 29 | * - @ref pj_addr_resolve |
| 30 | *\n |
| 31 | * Portable address resolution, which implements #pj_gethostbyname(). |
| 32 | * |
| 33 | * - @ref PJ_SOCK_SELECT |
| 34 | *\n |
| 35 | * A portable \a select() like API (#pj_sock_select()) which can be |
| 36 | * implemented with various back-ends. |
| 37 | * |
| 38 | * - @ref PJ_IOQUEUE |
| 39 | *\n |
| 40 | * Framework for dispatching network events. |
| 41 | * |
| 42 | * For more information see the modules below. |
| 43 | */ |
| 44 | |
| 45 | /** |
| 46 | * @defgroup PJ_IOQUEUE I/O Event Dispatching Queue |
| 47 | * @ingroup PJ_IO |
| 48 | * @{ |
| 49 | * |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 50 | * I/O Queue provides API for performing asynchronous I/O operations. It
|
| 51 | * conforms to proactor pattern, which allows application to submit an
|
| 52 | * asynchronous operation and to be notified later when the operation has
|
| 53 | * completed. |
| 54 | *
|
| 55 | * The framework works natively in platforms where asynchronous operation API
|
| 56 | * exists, such as in Windows NT with IoCompletionPort/IOCP. In other
|
| 57 | * platforms, the I/O queue abstracts the operating system's event poll API
|
| 58 | * to provide semantics similar to IoCompletionPort with minimal penalties
|
| 59 | * (i.e. per ioqueue and per handle mutex protection).
|
| 60 | *
|
| 61 | * The I/O queue provides more than just unified abstraction. It also:
|
| 62 | * - makes sure that the operation uses the most effective way to utilize
|
| 63 | * the underlying mechanism, to provide the maximum theoritical
|
| 64 | * throughput possible on a given platform.
|
| 65 | * - choose the most efficient mechanism for event polling on a given
|
| 66 | * platform.
|
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 67 | * |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 68 | * Currently, the I/O Queue is implemented using: |
| 69 | * - <tt><b>select()</b></tt>, as the common denominator, but the least
|
| 70 | * efficient. Also the number of descriptor is limited to
|
| 71 | * \c PJ_IOQUEUE_MAX_HANDLES (which by default is 64).
|
| 72 | * - <tt><b>/dev/epoll</b></tt> on Linux (user mode and kernel mode),
|
| 73 | * a much faster replacement for select() on Linux (and more importantly
|
| 74 | * doesn't have limitation on number of descriptors). |
| 75 | * - <b>I/O Completion ports</b> on Windows NT/2000/XP, which is the most
|
| 76 | * efficient way to dispatch events in Windows NT based OSes, and most
|
| 77 | * importantly, it doesn't have the limit on how many handles to monitor.
|
| 78 | * And it works with files (not only sockets) as well. |
| 79 | *
|
| 80 | *
|
| 81 | * \section pj_ioqueue_concurrency_sec Concurrency Rules
|
| 82 | *
|
| 83 | * The items below describe rules that must be obeyed when using the I/O
|
| 84 | * queue, with regard to concurrency:
|
Benny Prijono | 4d974f3 | 2005-11-06 13:32:11 +0000 | [diff] [blame] | 85 | * - simultaneous operations (by different threads) to different key is safe.
|
| 86 | * - simultaneous operations to the same key is also safe, except
|
| 87 | * <b>unregistration</b>, which is described below.
|
| 88 | * - <b>care must be taken when unregistering a key</b> from the
|
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 89 | * ioqueue. Application must take care that when one thread is issuing
|
| 90 | * an unregistration, other thread is not simultaneously invoking an
|
| 91 | * operation <b>to the same key</b>.
|
| 92 | *\n
|
| 93 | * This happens because the ioqueue functions are working with a pointer
|
| 94 | * to the key, and there is a possible race condition where the pointer
|
| 95 | * has been rendered invalid by other threads before the ioqueue has a
|
| 96 | * chance to acquire mutex on it.
|
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 97 | * |
| 98 | * \section pj_ioqeuue_examples_sec Examples |
| 99 | * |
| 100 | * For some examples on how to use the I/O Queue, please see: |
| 101 | * |
| 102 | * - \ref page_pjlib_ioqueue_tcp_test |
| 103 | * - \ref page_pjlib_ioqueue_udp_test |
| 104 | * - \ref page_pjlib_ioqueue_perf_test |
| 105 | */ |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 106 |
|
| 107 |
|
| 108 |
|
| 109 | /**
|
| 110 | * This structure describes operation specific key to be submitted to
|
| 111 | * I/O Queue when performing the asynchronous operation. This key will
|
| 112 | * be returned to the application when completion callback is called.
|
| 113 | *
|
| 114 | * Application normally wants to attach it's specific data in the
|
| 115 | * \c user_data field so that it can keep track of which operation has
|
| 116 | * completed when the callback is called. Alternatively, application can
|
| 117 | * also extend this struct to include its data, because the pointer that
|
| 118 | * is returned in the completion callback will be exactly the same as
|
| 119 | * the pointer supplied when the asynchronous function is called.
|
| 120 | */
|
| 121 | typedef struct pj_ioqueue_op_key_t
|
| 122 | {
|
| 123 | void *internal__[32]; /**< Internal I/O Queue data. */
|
| 124 | void *user_data; /**< Application data. */
|
| 125 | } pj_ioqueue_op_key_t;
|
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 126 | |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 127 | /** |
| 128 | * This structure describes the callbacks to be called when I/O operation |
| 129 | * completes. |
| 130 | */ |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 131 | typedef struct pj_ioqueue_callback |
| 132 | { |
| 133 | /** |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 134 | * This callback is called when #pj_ioqueue_recv or #pj_ioqueue_recvfrom |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 135 | * completes. |
| 136 | * |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 137 | * @param key The key.
|
| 138 | * @param op_key Operation key. |
| 139 | * @param bytes_read >= 0 to indicate the amount of data read,
|
| 140 | * otherwise negative value containing the error
|
| 141 | * code. To obtain the pj_status_t error code, use
|
| 142 | * (pj_status_t code = -bytes_read). |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 143 | */ |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 144 | void (*on_read_complete)(pj_ioqueue_key_t *key,
|
| 145 | pj_ioqueue_op_key_t *op_key,
|
| 146 | pj_ssize_t bytes_read); |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 147 | |
| 148 | /** |
| 149 | * This callback is called when #pj_ioqueue_write or #pj_ioqueue_sendto |
| 150 | * completes. |
| 151 | * |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 152 | * @param key The key.
|
| 153 | * @param op_key Operation key. |
| 154 | * @param bytes_sent >= 0 to indicate the amount of data written,
|
| 155 | * otherwise negative value containing the error
|
| 156 | * code. To obtain the pj_status_t error code, use
|
| 157 | * (pj_status_t code = -bytes_sent).
|
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 158 | */ |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 159 | void (*on_write_complete)(pj_ioqueue_key_t *key,
|
| 160 | pj_ioqueue_op_key_t *op_key,
|
| 161 | pj_ssize_t bytes_sent); |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 162 | |
| 163 | /** |
| 164 | * This callback is called when #pj_ioqueue_accept completes. |
| 165 | * |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 166 | * @param key The key.
|
| 167 | * @param op_key Operation key. |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 168 | * @param sock Newly connected socket. |
| 169 | * @param status Zero if the operation completes successfully. |
| 170 | */ |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 171 | void (*on_accept_complete)(pj_ioqueue_key_t *key,
|
| 172 | pj_ioqueue_op_key_t *op_key,
|
| 173 | pj_sock_t sock, |
| 174 | pj_status_t status); |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 175 | |
| 176 | /** |
| 177 | * This callback is called when #pj_ioqueue_connect completes. |
| 178 | * |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 179 | * @param key The key.
|
| 180 | * @param status PJ_SUCCESS if the operation completes successfully. |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 181 | */ |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 182 | void (*on_connect_complete)(pj_ioqueue_key_t *key,
|
| 183 | pj_status_t status); |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 184 | } pj_ioqueue_callback; |
| 185 | |
| 186 | |
| 187 | /** |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 188 | * Types of pending I/O Queue operation. This enumeration is only used
|
| 189 | * internally within the ioqueue. |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 190 | */ |
| 191 | typedef enum pj_ioqueue_operation_e |
| 192 | { |
| 193 | PJ_IOQUEUE_OP_NONE = 0, /**< No operation. */ |
| 194 | PJ_IOQUEUE_OP_READ = 1, /**< read() operation. */ |
| 195 | PJ_IOQUEUE_OP_RECV = 2, /**< recv() operation. */ |
| 196 | PJ_IOQUEUE_OP_RECV_FROM = 4, /**< recvfrom() operation. */ |
| 197 | PJ_IOQUEUE_OP_WRITE = 8, /**< write() operation. */ |
| 198 | PJ_IOQUEUE_OP_SEND = 16, /**< send() operation. */ |
| 199 | PJ_IOQUEUE_OP_SEND_TO = 32, /**< sendto() operation. */ |
| 200 | #if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0 |
| 201 | PJ_IOQUEUE_OP_ACCEPT = 64, /**< accept() operation. */ |
| 202 | PJ_IOQUEUE_OP_CONNECT = 128, /**< connect() operation. */ |
| 203 | #endif /* PJ_HAS_TCP */ |
| 204 | } pj_ioqueue_operation_e; |
| 205 | |
| 206 | |
Benny Prijono | 4d974f3 | 2005-11-06 13:32:11 +0000 | [diff] [blame] | 207 | /**
|
| 208 | * This macro specifies the maximum number of events that can be
|
| 209 | * processed by the ioqueue on a single poll cycle, on implementation
|
| 210 | * that supports it. The value is only meaningfull when specified
|
| 211 | * during PJLIB build.
|
| 212 | */
|
| 213 | #ifndef PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL
|
| 214 | # define PJ_IOQUEUE_MAX_EVENTS_IN_SINGLE_POLL (16)
|
| 215 | #endif
|
| 216 | |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 217 |
|
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 218 | /** |
| 219 | * Create a new I/O Queue framework. |
| 220 | * |
| 221 | * @param pool The pool to allocate the I/O queue structure. |
| 222 | * @param max_fd The maximum number of handles to be supported, which |
| 223 | * should not exceed PJ_IOQUEUE_MAX_HANDLES. |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 224 | * @param ioqueue Pointer to hold the newly created I/O Queue. |
| 225 | * |
| 226 | * @return PJ_SUCCESS on success. |
| 227 | */ |
| 228 | PJ_DECL(pj_status_t) pj_ioqueue_create( pj_pool_t *pool, |
| 229 | pj_size_t max_fd, |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 230 | pj_ioqueue_t **ioqueue); |
| 231 | |
| 232 | /** |
| 233 | * Destroy the I/O queue. |
| 234 | * |
| 235 | * @param ioque The I/O Queue to be destroyed. |
| 236 | * |
| 237 | * @return PJ_SUCCESS if success. |
| 238 | */ |
| 239 | PJ_DECL(pj_status_t) pj_ioqueue_destroy( pj_ioqueue_t *ioque ); |
| 240 | |
| 241 | /** |
| 242 | * Set the lock object to be used by the I/O Queue. This function can only |
| 243 | * be called right after the I/O queue is created, before any handle is |
| 244 | * registered to the I/O queue. |
| 245 | * |
| 246 | * Initially the I/O queue is created with non-recursive mutex protection. |
| 247 | * Applications can supply alternative lock to be used by calling this |
| 248 | * function. |
| 249 | * |
| 250 | * @param ioque The ioqueue instance. |
| 251 | * @param lock The lock to be used by the ioqueue. |
| 252 | * @param auto_delete In non-zero, the lock will be deleted by the ioqueue. |
| 253 | * |
| 254 | * @return PJ_SUCCESS or the appropriate error code. |
| 255 | */ |
| 256 | PJ_DECL(pj_status_t) pj_ioqueue_set_lock( pj_ioqueue_t *ioque, |
| 257 | pj_lock_t *lock, |
| 258 | pj_bool_t auto_delete ); |
| 259 | |
| 260 | /** |
| 261 | * Register a socket to the I/O queue framework. |
| 262 | * When a socket is registered to the IOQueue, it may be modified to use |
| 263 | * non-blocking IO. If it is modified, there is no guarantee that this |
| 264 | * modification will be restored after the socket is unregistered. |
| 265 | * |
| 266 | * @param pool To allocate the resource for the specified handle, |
| 267 | * which must be valid until the handle/key is unregistered |
| 268 | * from I/O Queue. |
| 269 | * @param ioque The I/O Queue. |
| 270 | * @param sock The socket. |
| 271 | * @param user_data User data to be associated with the key, which can be |
| 272 | * retrieved later. |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 273 | * @param cb Callback to be called when I/O operation completes.
|
| 274 | * @param key Pointer to receive the key to be associated with this
|
| 275 | * socket. Subsequent I/O queue operation will need this
|
| 276 | * key. |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 277 | * |
| 278 | * @return PJ_SUCCESS on success, or the error code. |
| 279 | */ |
| 280 | PJ_DECL(pj_status_t) pj_ioqueue_register_sock( pj_pool_t *pool, |
| 281 | pj_ioqueue_t *ioque, |
| 282 | pj_sock_t sock, |
| 283 | void *user_data, |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 284 | const pj_ioqueue_callback *cb,
|
| 285 | pj_ioqueue_key_t **key ); |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 286 | |
| 287 | /** |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 288 | * Unregister from the I/O Queue framework. Caller must make sure that
|
| 289 | * the key doesn't have any pending operation before calling this function,
|
| 290 | * or otherwise the behaviour is undefined (either callback will be called
|
| 291 | * later when the data is sent/received, or the callback will not be called,
|
| 292 | * or even something else). |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 293 | * |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 294 | * @param key The key that was previously obtained from registration.
|
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 295 | * |
| 296 | * @return PJ_SUCCESS on success or the error code. |
| 297 | */ |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 298 | PJ_DECL(pj_status_t) pj_ioqueue_unregister( pj_ioqueue_key_t *key ); |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 299 | |
| 300 | |
| 301 | /** |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 302 | * Get user data associated with an ioqueue key. |
| 303 | *
|
| 304 | * @param key The key that was previously obtained from registration.
|
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 305 | * |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 306 | * @return The user data associated with the descriptor, or NULL
|
| 307 | * on error or if no data is associated with the key during |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 308 | * registration. |
| 309 | */ |
| 310 | PJ_DECL(void*) pj_ioqueue_get_user_data( pj_ioqueue_key_t *key ); |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 311 |
|
| 312 | /**
|
| 313 | * Set or change the user data to be associated with the file descriptor or
|
| 314 | * handle or socket descriptor.
|
| 315 | *
|
| 316 | * @param key The key that was previously obtained from registration.
|
| 317 | * @param user_data User data to be associated with the descriptor.
|
| 318 | * @param old_data Optional parameter to retrieve the old user data.
|
| 319 | *
|
| 320 | * @return PJ_SUCCESS on success or the error code.
|
| 321 | */
|
| 322 | PJ_DECL(pj_status_t) pj_ioqueue_set_user_data( pj_ioqueue_key_t *key,
|
| 323 | void *user_data,
|
| 324 | void **old_data);
|
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 325 | |
| 326 | |
| 327 | #if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0 |
| 328 | /** |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 329 | * Instruct I/O Queue to accept incoming connection on the specified |
| 330 | * listening socket. This function will return immediately (i.e. non-blocking)
|
| 331 | * regardless whether a connection is immediately available. If the function
|
| 332 | * can't complete immediately, the caller will be notified about the incoming
|
| 333 | * connection when it calls pj_ioqueue_poll(). If a new connection is
|
| 334 | * immediately available, the function returns PJ_SUCCESS with the new
|
| 335 | * connection; in this case, the callback WILL NOT be called. |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 336 | * |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 337 | * @param key The key which registered to the server socket.
|
| 338 | * @param op_key An operation specific key to be associated with the
|
| 339 | * pending operation, so that application can keep track of
|
| 340 | * which operation has been completed when the callback is
|
| 341 | * called. |
| 342 | * @param new_sock Argument which contain pointer to receive the new socket |
| 343 | * for the incoming connection. |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 344 | * @param local Optional argument which contain pointer to variable to |
| 345 | * receive local address. |
| 346 | * @param remote Optional argument which contain pointer to variable to |
| 347 | * receive the remote address. |
| 348 | * @param addrlen On input, contains the length of the buffer for the |
| 349 | * address, and on output, contains the actual length of the |
| 350 | * address. This argument is optional. |
| 351 | * @return |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 352 | * - PJ_SUCCESS When connection is available immediately, and the
|
| 353 | * parameters will be updated to contain information about
|
| 354 | * the new connection. In this case, a completion callback
|
| 355 | * WILL NOT be called. |
| 356 | * - PJ_EPENDING If no connection is available immediately. When a new
|
| 357 | * connection arrives, the callback will be called. |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 358 | * - non-zero which indicates the appropriate error code. |
| 359 | */ |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 360 | PJ_DECL(pj_status_t) pj_ioqueue_accept( pj_ioqueue_key_t *key,
|
| 361 | pj_ioqueue_op_key_t *op_key, |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 362 | pj_sock_t *sock, |
| 363 | pj_sockaddr_t *local, |
| 364 | pj_sockaddr_t *remote, |
| 365 | int *addrlen ); |
| 366 | |
| 367 | /** |
| 368 | * Initiate non-blocking socket connect. If the socket can NOT be connected |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 369 | * immediately, asynchronous connect() will be scheduled and caller will be
|
| 370 | * notified via completion callback when it calls pj_ioqueue_poll(). If
|
| 371 | * socket is connected immediately, the function returns PJ_SUCCESS and
|
| 372 | * completion callback WILL NOT be called. |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 373 | * |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 374 | * @param key The key associated with TCP socket |
| 375 | * @param addr The remote address. |
| 376 | * @param addrlen The remote address length. |
| 377 | * |
| 378 | * @return |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 379 | * - PJ_SUCCESS If socket is connected immediately. In this case, the
|
| 380 | * completion callback WILL NOT be called. |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 381 | * - PJ_EPENDING If operation is queued, or |
| 382 | * - non-zero Indicates the error code. |
| 383 | */ |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 384 | PJ_DECL(pj_status_t) pj_ioqueue_connect( pj_ioqueue_key_t *key, |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 385 | const pj_sockaddr_t *addr, |
| 386 | int addrlen ); |
| 387 | |
| 388 | #endif /* PJ_HAS_TCP */ |
| 389 | |
| 390 | /** |
| 391 | * Poll the I/O Queue for completed events. |
| 392 | * |
| 393 | * @param ioque the I/O Queue. |
| 394 | * @param timeout polling timeout, or NULL if the thread wishes to wait |
| 395 | * indefinetely for the event. |
| 396 | * |
| 397 | * @return |
| 398 | * - zero if timed out (no event). |
| 399 | * - (<0) if error occured during polling. Callback will NOT be called. |
| 400 | * - (>1) to indicate numbers of events. Callbacks have been called. |
| 401 | */ |
| 402 | PJ_DECL(int) pj_ioqueue_poll( pj_ioqueue_t *ioque, |
| 403 | const pj_time_val *timeout); |
| 404 | |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 405 | |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 406 | /** |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 407 | * Instruct the I/O Queue to read from the specified handle. This function
|
| 408 | * returns immediately (i.e. non-blocking) regardless whether some data has
|
| 409 | * been transfered. If the operation can't complete immediately, caller will
|
| 410 | * be notified about the completion when it calls pj_ioqueue_poll(). If data
|
| 411 | * is immediately available, the function will return PJ_SUCCESS and the
|
| 412 | * callback WILL NOT be called.
|
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 413 | * |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 414 | * @param key The key that uniquely identifies the handle. |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 415 | * @param op_key An operation specific key to be associated with the
|
| 416 | * pending operation, so that application can keep track of
|
| 417 | * which operation has been completed when the callback is
|
| 418 | * called. Caller must make sure that this key remains
|
| 419 | * valid until the function completes.
|
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 420 | * @param buffer The buffer to hold the read data. The caller MUST make sure |
| 421 | * that this buffer remain valid until the framework completes |
| 422 | * reading the handle. |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 423 | * @param length On input, it specifies the size of the buffer. If data is
|
| 424 | * available to be read immediately, the function returns
|
| 425 | * PJ_SUCCESS and this argument will be filled with the
|
| 426 | * amount of data read. If the function is pending, caller
|
| 427 | * will be notified about the amount of data read in the
|
| 428 | * callback. This parameter can point to local variable in
|
| 429 | * caller's stack and doesn't have to remain valid for the
|
| 430 | * duration of pending operation. |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 431 | * @param flags Recv flag. |
| 432 | * |
| 433 | * @return |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 434 | * - PJ_SUCCESS If immediate data has been received in the buffer. In this
|
| 435 | * case, the callback WILL NOT be called. |
| 436 | * - PJ_EPENDING If the operation has been queued, and the callback will be
|
| 437 | * called when data has been received. |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 438 | * - non-zero The return value indicates the error code. |
| 439 | */ |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 440 | PJ_DECL(pj_status_t) pj_ioqueue_recv( pj_ioqueue_key_t *key,
|
| 441 | pj_ioqueue_op_key_t *op_key, |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 442 | void *buffer, |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 443 | pj_ssize_t *length, |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 444 | unsigned flags ); |
| 445 | |
| 446 | /** |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 447 | * This function behaves similarly as #pj_ioqueue_recv(), except that it is |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 448 | * normally called for socket, and the remote address will also be returned |
| 449 | * along with the data. Caller MUST make sure that both buffer and addr |
| 450 | * remain valid until the framework completes reading the data. |
| 451 | * |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 452 | * @param key The key that uniquely identifies the handle. |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 453 | * @param op_key An operation specific key to be associated with the
|
| 454 | * pending operation, so that application can keep track of
|
| 455 | * which operation has been completed when the callback is
|
| 456 | * called.
|
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 457 | * @param buffer The buffer to hold the read data. The caller MUST make sure |
| 458 | * that this buffer remain valid until the framework completes |
| 459 | * reading the handle. |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 460 | * @param length On input, it specifies the size of the buffer. If data is
|
| 461 | * available to be read immediately, the function returns
|
| 462 | * PJ_SUCCESS and this argument will be filled with the
|
| 463 | * amount of data read. If the function is pending, caller
|
| 464 | * will be notified about the amount of data read in the
|
| 465 | * callback. This parameter can point to local variable in
|
| 466 | * caller's stack and doesn't have to remain valid for the
|
| 467 | * duration of pending operation.
|
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 468 | * @param flags Recv flag. |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 469 | * @param addr Optional Pointer to buffer to receive the address. |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 470 | * @param addrlen On input, specifies the length of the address buffer. |
| 471 | * On output, it will be filled with the actual length of |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 472 | * the address. This argument can be NULL if \c addr is not
|
| 473 | * specified. |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 474 | * |
| 475 | * @return |
| 476 | * - PJ_SUCCESS If immediate data has been received. In this case, the |
| 477 | * callback must have been called before this function |
| 478 | * returns, and no pending operation is scheduled. |
| 479 | * - PJ_EPENDING If the operation has been queued. |
| 480 | * - non-zero The return value indicates the error code. |
| 481 | */ |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 482 | PJ_DECL(pj_status_t) pj_ioqueue_recvfrom( pj_ioqueue_key_t *key,
|
| 483 | pj_ioqueue_op_key_t *op_key, |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 484 | void *buffer, |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 485 | pj_ssize_t *length, |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 486 | unsigned flags, |
| 487 | pj_sockaddr_t *addr, |
| 488 | int *addrlen); |
| 489 | |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 490 | |
| 491 | /** |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 492 | * Instruct the I/O Queue to write to the handle. This function will return
|
| 493 | * immediately (i.e. non-blocking) regardless whether some data has been
|
| 494 | * transfered. If the function can't complete immediately, the caller will
|
| 495 | * be notified about the completion when it calls pj_ioqueue_poll(). If
|
| 496 | * operation completes immediately and data has been transfered, the function
|
| 497 | * returns PJ_SUCCESS and the callback will NOT be called.
|
| 498 | *
|
| 499 | * @param key The key that identifies the handle. |
| 500 | * @param op_key An operation specific key to be associated with the
|
| 501 | * pending operation, so that application can keep track of
|
| 502 | * which operation has been completed when the callback is
|
| 503 | * called.
|
| 504 | * @param data The data to send. Caller MUST make sure that this buffer |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 505 | * remains valid until the write operation completes. |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 506 | * @param length On input, it specifies the length of data to send. When
|
| 507 | * data was sent immediately, this function returns PJ_SUCCESS
|
| 508 | * and this parameter contains the length of data sent. If
|
| 509 | * data can not be sent immediately, an asynchronous operation
|
| 510 | * is scheduled and caller will be notified via callback the
|
| 511 | * number of bytes sent. This parameter can point to local
|
| 512 | * variable on caller's stack and doesn't have to remain
|
| 513 | * valid until the operation has completed. |
| 514 | * @param flags Send flags. |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 515 | * |
| 516 | * @return |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 517 | * - PJ_SUCCESS If data was immediately transfered. In this case, no
|
| 518 | * pending operation has been scheduled and the callback
|
| 519 | * WILL NOT be called. |
| 520 | * - PJ_EPENDING If the operation has been queued. Once data base been
|
| 521 | * transfered, the callback will be called. |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 522 | * - non-zero The return value indicates the error code. |
| 523 | */ |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 524 | PJ_DECL(pj_status_t) pj_ioqueue_send( pj_ioqueue_key_t *key,
|
| 525 | pj_ioqueue_op_key_t *op_key, |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 526 | const void *data, |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 527 | pj_ssize_t *length, |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 528 | unsigned flags ); |
| 529 | |
| 530 | |
| 531 | /** |
| 532 | * This function behaves similarly as #pj_ioqueue_write(), except that |
| 533 | * pj_sock_sendto() (or equivalent) will be called to send the data. |
| 534 | * |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 535 | * @param key the key that identifies the handle. |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 536 | * @param op_key An operation specific key to be associated with the
|
| 537 | * pending operation, so that application can keep track of
|
| 538 | * which operation has been completed when the callback is
|
| 539 | * called.
|
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 540 | * @param data the data to send. Caller MUST make sure that this buffer |
| 541 | * remains valid until the write operation completes. |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 542 | * @param length On input, it specifies the length of data to send. When
|
| 543 | * data was sent immediately, this function returns PJ_SUCCESS
|
| 544 | * and this parameter contains the length of data sent. If
|
| 545 | * data can not be sent immediately, an asynchronous operation
|
| 546 | * is scheduled and caller will be notified via callback the
|
| 547 | * number of bytes sent. This parameter can point to local
|
| 548 | * variable on caller's stack and doesn't have to remain
|
| 549 | * valid until the operation has completed.
|
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 550 | * @param flags send flags. |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 551 | * @param addr Optional remote address. |
| 552 | * @param addrlen Remote address length, \c addr is specified. |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 553 | * |
| 554 | * @return |
| 555 | * - PJ_SUCCESS If data was immediately written. |
| 556 | * - PJ_EPENDING If the operation has been queued. |
| 557 | * - non-zero The return value indicates the error code. |
| 558 | */ |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 559 | PJ_DECL(pj_status_t) pj_ioqueue_sendto( pj_ioqueue_key_t *key,
|
| 560 | pj_ioqueue_op_key_t *op_key, |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 561 | const void *data, |
Benny Prijono | a9946d5 | 2005-11-06 09:37:47 +0000 | [diff] [blame] | 562 | pj_ssize_t *length, |
Benny Prijono | dd859a6 | 2005-11-01 16:42:51 +0000 | [diff] [blame] | 563 | unsigned flags, |
| 564 | const pj_sockaddr_t *addr, |
| 565 | int addrlen); |
| 566 | |
| 567 | |
| 568 | /** |
| 569 | * !} |
| 570 | */ |
| 571 | |
| 572 | PJ_END_DECL |
| 573 | |
| 574 | #endif /* __PJ_IOQUEUE_H__ */ |
| 575 | |