Ignore:
Timestamp:
Nov 6, 2005 9:37:47 AM (18 years ago)
Author:
bennylp
Message:

Changed ioqueue to allow simultaneous operations on the same key

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/main/pjlib/include/pj/ioqueue.h

    r4 r11  
    11/* $Id$ 
    2  * 
    32 */ 
    43 
     
    4948 * @{ 
    5049 * 
    51  * This file provides abstraction for various event dispatching mechanisms.  
    52  * The interfaces for event dispatching vary alot, even in a single 
    53  * operating system. The abstraction here hopefully is suitable for most of 
    54  * the event dispatching available. 
    55  * 
    56  * Currently, the I/O Queue supports: 
    57  * - select(), as the common denominator, but the least efficient. 
    58  * - I/O Completion ports in Windows NT/2000/XP, which is the most efficient 
    59  *      way to dispatch events in Windows NT based OSes, and most importantly, 
    60  *      it doesn't have the limit on how many handles to monitor. And it works 
    61  *      with files (not only sockets) as well. 
     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. 
     67 * 
     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: 
     85 *  - in general, the I/O queue is thread safe (assuming the lock strategy 
     86 *    is not changed to disable mutex protection). All operations, except 
     87 *    unregistration which is described below, can be safely invoked  
     88 *    simultaneously by multiple  threads. 
     89 *  - however, <b>care must be taken when unregistering a key</b> from the 
     90 *    ioqueue. Application must take care that when one thread is issuing 
     91 *    an unregistration, other thread is not simultaneously invoking an 
     92 *    operation <b>to the same key</b>. 
     93 *\n 
     94 *    This happens because the ioqueue functions are working with a pointer 
     95 *    to the key, and there is a possible race condition where the pointer 
     96 *    has been rendered invalid by other threads before the ioqueue has a 
     97 *    chance to acquire mutex on it. 
    6298 * 
    6399 * \section pj_ioqeuue_examples_sec Examples 
     
    70106 */ 
    71107 
    72  /** 
    73   * This structure describes the callbacks to be called when I/O operation 
    74   * completes. 
    75   */ 
     108 
     109 
     110/** 
     111 * This structure describes operation specific key to be submitted to 
     112 * I/O Queue when performing the asynchronous operation. This key will 
     113 * be returned to the application when completion callback is called. 
     114 * 
     115 * Application normally wants to attach it's specific data in the 
     116 * \c user_data field so that it can keep track of which operation has 
     117 * completed when the callback is called. Alternatively, application can 
     118 * also extend this struct to include its data, because the pointer that 
     119 * is returned in the completion callback will be exactly the same as 
     120 * the pointer supplied when the asynchronous function is called. 
     121 */ 
     122typedef struct pj_ioqueue_op_key_t 
     123{  
     124    void *internal__[32];           /**< Internal I/O Queue data.   */ 
     125    void *user_data;                /**< Application data.          */ 
     126} pj_ioqueue_op_key_t; 
     127 
     128/** 
     129 * This structure describes the callbacks to be called when I/O operation 
     130 * completes. 
     131 */ 
    76132typedef struct pj_ioqueue_callback 
    77133{ 
    78134    /** 
    79      * This callback is called when #pj_ioqueue_read or #pj_ioqueue_recvfrom 
     135     * This callback is called when #pj_ioqueue_recv or #pj_ioqueue_recvfrom 
    80136     * completes. 
    81137     * 
    82138     * @param key           The key. 
    83      * @param bytes_read    The size of data that has just been read. 
     139     * @param op_key        Operation key. 
     140     * @param bytes_read    >= 0 to indicate the amount of data read,  
     141     *                      otherwise negative value containing the error 
     142     *                      code. To obtain the pj_status_t error code, use 
     143     *                      (pj_status_t code = -bytes_read). 
    84144     */ 
    85     void (*on_read_complete)(pj_ioqueue_key_t *key, pj_ssize_t bytes_read); 
     145    void (*on_read_complete)(pj_ioqueue_key_t *key,  
     146                             pj_ioqueue_op_key_t *op_key,  
     147                             pj_ssize_t bytes_read); 
    86148 
    87149    /** 
     
    90152     * 
    91153     * @param key           The key. 
    92      * @param bytes_read    The size of data that has just been read. 
     154     * @param op_key        Operation key. 
     155     * @param bytes_sent    >= 0 to indicate the amount of data written,  
     156     *                      otherwise negative value containing the error 
     157     *                      code. To obtain the pj_status_t error code, use 
     158     *                      (pj_status_t code = -bytes_sent). 
    93159     */ 
    94     void (*on_write_complete)(pj_ioqueue_key_t *key, pj_ssize_t bytes_sent); 
     160    void (*on_write_complete)(pj_ioqueue_key_t *key,  
     161                              pj_ioqueue_op_key_t *op_key,  
     162                              pj_ssize_t bytes_sent); 
    95163 
    96164    /** 
     
    98166     * 
    99167     * @param key           The key. 
     168     * @param op_key        Operation key. 
    100169     * @param sock          Newly connected socket. 
    101170     * @param status        Zero if the operation completes successfully. 
    102171     */ 
    103     void (*on_accept_complete)(pj_ioqueue_key_t *key, pj_sock_t sock,  
    104                                int status); 
     172    void (*on_accept_complete)(pj_ioqueue_key_t *key,  
     173                               pj_ioqueue_op_key_t *op_key,  
     174                               pj_sock_t sock,  
     175                               pj_status_t status); 
    105176 
    106177    /** 
     
    108179     * 
    109180     * @param key           The key. 
    110      * @param status        Zero if the operation completes successfully. 
     181     * @param status        PJ_SUCCESS if the operation completes successfully. 
    111182     */ 
    112     void (*on_connect_complete)(pj_ioqueue_key_t *key, int status); 
     183    void (*on_connect_complete)(pj_ioqueue_key_t *key,  
     184                                pj_status_t status); 
    113185} pj_ioqueue_callback; 
    114186 
    115187 
    116188/** 
    117  * Types of I/O Queue operation. 
     189 * Types of pending I/O Queue operation. This enumeration is only used 
     190 * internally within the ioqueue. 
    118191 */ 
    119192typedef enum pj_ioqueue_operation_e 
     
    139212#define PJ_IOQUEUE_DEFAULT_THREADS  0 
    140213 
    141  
    142214/** 
    143215 * Create a new I/O Queue framework. 
     
    146218 * @param max_fd        The maximum number of handles to be supported, which  
    147219 *                      should not exceed PJ_IOQUEUE_MAX_HANDLES. 
    148  * @param max_threads   The maximum number of threads that are allowed to 
    149  *                      operate on a single descriptor simultaneously. If 
    150  *                      the value is zero, the framework will set it 
    151  *                      to a reasonable value. 
    152220 * @param ioqueue       Pointer to hold the newly created I/O Queue. 
    153221 * 
     
    156224PJ_DECL(pj_status_t) pj_ioqueue_create( pj_pool_t *pool,  
    157225                                        pj_size_t max_fd, 
    158                                         int max_threads, 
    159226                                        pj_ioqueue_t **ioqueue); 
    160227 
     
    201268 *                  retrieved later. 
    202269 * @param cb        Callback to be called when I/O operation completes.  
    203  * @param key       Pointer to receive the returned key. 
     270 * @param key       Pointer to receive the key to be associated with this 
     271 *                  socket. Subsequent I/O queue operation will need this 
     272 *                  key. 
    204273 * 
    205274 * @return          PJ_SUCCESS on success, or the error code. 
     
    210279                                               void *user_data, 
    211280                                               const pj_ioqueue_callback *cb, 
    212                                                pj_ioqueue_key_t **key); 
    213  
    214 /** 
    215  * Unregister a handle from the I/O Queue framework. 
    216  * 
    217  * @param ioque     The I/O Queue. 
    218  * @param key       The key that uniquely identifies the handle, which is  
    219  *                  returned from the function #pj_ioqueue_register_sock() 
    220  *                  or other registration functions. 
     281                                               pj_ioqueue_key_t **key ); 
     282 
     283/** 
     284 * Unregister from the I/O Queue framework. Caller must make sure that 
     285 * the key doesn't have any pending operation before calling this function, 
     286 * or otherwise the behaviour is undefined (either callback will be called 
     287 * later when the data is sent/received, or the callback will not be called, 
     288 * or even something else). 
     289 * 
     290 * @param key       The key that was previously obtained from registration. 
    221291 * 
    222292 * @return          PJ_SUCCESS on success or the error code. 
    223293 */ 
    224 PJ_DECL(pj_status_t) pj_ioqueue_unregister( pj_ioqueue_t *ioque, 
    225                                             pj_ioqueue_key_t *key ); 
    226  
    227  
    228 /** 
    229  * Get user data associated with the I/O Queue key. 
    230  * 
    231  * @param key       The key previously associated with the socket/handle with 
    232  *                  #pj_ioqueue_register_sock() (or other registration  
    233  *                  functions). 
    234  * 
    235  * @return          The user data associated with the key, or NULL on error 
    236  *                  of if no data is associated with the key during  
     294PJ_DECL(pj_status_t) pj_ioqueue_unregister( pj_ioqueue_key_t *key ); 
     295 
     296 
     297/** 
     298 * Get user data associated with an ioqueue key. 
     299 * 
     300 * @param key       The key that was previously obtained from registration. 
     301 * 
     302 * @return          The user data associated with the descriptor, or NULL  
     303 *                  on error or if no data is associated with the key during 
    237304 *                  registration. 
    238305 */ 
    239306PJ_DECL(void*) pj_ioqueue_get_user_data( pj_ioqueue_key_t *key ); 
    240307 
     308/** 
     309 * Set or change the user data to be associated with the file descriptor or 
     310 * handle or socket descriptor. 
     311 * 
     312 * @param key       The key that was previously obtained from registration. 
     313 * @param user_data User data to be associated with the descriptor. 
     314 * @param old_data  Optional parameter to retrieve the old user data. 
     315 * 
     316 * @return          PJ_SUCCESS on success or the error code. 
     317 */ 
     318PJ_DECL(pj_status_t) pj_ioqueue_set_user_data( pj_ioqueue_key_t *key, 
     319                                               void *user_data, 
     320                                               void **old_data); 
     321 
    241322 
    242323#if defined(PJ_HAS_TCP) && PJ_HAS_TCP != 0 
    243324/** 
    244  * Instruct I/O Queue to wait for incoming connections on the specified  
    245  * listening socket. This function will return 
    246  * immediately (i.e. non-blocking) regardless whether some data has been  
    247  * transfered. If the function can't complete immediately, and the caller will 
    248  * be notified about the completion when it calls pj_ioqueue_poll(). 
    249  * 
    250  * @param ioqueue   The I/O Queue 
     325 * Instruct I/O Queue to accept incoming connection on the specified  
     326 * listening socket. This function will return immediately (i.e. non-blocking) 
     327 * regardless whether a connection is immediately available. If the function 
     328 * can't complete immediately, the caller will be notified about the incoming 
     329 * connection when it calls pj_ioqueue_poll(). If a new connection is 
     330 * immediately available, the function returns PJ_SUCCESS with the new 
     331 * connection; in this case, the callback WILL NOT be called. 
     332 * 
    251333 * @param key       The key which registered to the server socket. 
    252  * @param sock      Argument which contain pointer to receive  
    253  *                  the socket for the incoming connection. 
     334 * @param op_key    An operation specific key to be associated with the 
     335 *                  pending operation, so that application can keep track of 
     336 *                  which operation has been completed when the callback is 
     337 *                  called. 
     338 * @param new_sock  Argument which contain pointer to receive the new socket 
     339 *                  for the incoming connection. 
    254340 * @param local     Optional argument which contain pointer to variable to  
    255341 *                  receive local address. 
     
    260346 *                  address. This argument is optional. 
    261347 * @return 
    262  *  - PJ_SUCCESS    If there's a connection available immediately, which  
    263  *                  in this case the callback should have been called before  
    264  *                  the function returns. 
    265  *  - PJ_EPENDING   If accept is queued, or  
     348 *  - PJ_SUCCESS    When connection is available immediately, and the  
     349 *                  parameters will be updated to contain information about  
     350 *                  the new connection. In this case, a completion callback 
     351 *                  WILL NOT be called. 
     352 *  - PJ_EPENDING   If no connection is available immediately. When a new 
     353 *                  connection arrives, the callback will be called. 
    266354 *  - non-zero      which indicates the appropriate error code. 
    267355 */ 
    268 PJ_DECL(pj_status_t) pj_ioqueue_accept( pj_ioqueue_t *ioqueue, 
    269                                         pj_ioqueue_key_t *key, 
     356PJ_DECL(pj_status_t) pj_ioqueue_accept( pj_ioqueue_key_t *key, 
     357                                        pj_ioqueue_op_key_t *op_key, 
    270358                                        pj_sock_t *sock, 
    271359                                        pj_sockaddr_t *local, 
     
    275363/** 
    276364 * Initiate non-blocking socket connect. If the socket can NOT be connected 
    277  * immediately, the result will be reported during poll. 
    278  * 
    279  * @param ioqueue   The ioqueue 
     365 * immediately, asynchronous connect() will be scheduled and caller will be 
     366 * notified via completion callback when it calls pj_ioqueue_poll(). If 
     367 * socket is connected immediately, the function returns PJ_SUCCESS and 
     368 * completion callback WILL NOT be called. 
     369 * 
    280370 * @param key       The key associated with TCP socket 
    281371 * @param addr      The remote address. 
     
    283373 * 
    284374 * @return 
    285  *  - PJ_SUCCESS    If socket is connected immediately, which in this case  
    286  *                  the callback should have been called. 
     375 *  - PJ_SUCCESS    If socket is connected immediately. In this case, the 
     376 *                  completion callback WILL NOT be called. 
    287377 *  - PJ_EPENDING   If operation is queued, or  
    288378 *  - non-zero      Indicates the error code. 
    289379 */ 
    290 PJ_DECL(pj_status_t) pj_ioqueue_connect( pj_ioqueue_t *ioqueue, 
    291                                          pj_ioqueue_key_t *key, 
     380PJ_DECL(pj_status_t) pj_ioqueue_connect( pj_ioqueue_key_t *key, 
    292381                                         const pj_sockaddr_t *addr, 
    293382                                         int addrlen ); 
     
    310399                              const pj_time_val *timeout); 
    311400 
     401 
    312402/** 
    313403 * Instruct the I/O Queue to read from the specified handle. This function 
    314404 * returns immediately (i.e. non-blocking) regardless whether some data has  
    315405 * been transfered. If the operation can't complete immediately, caller will  
    316  * be notified about the completion when it calls pj_ioqueue_poll(). 
    317  * 
    318  * @param ioque     The I/O Queue. 
     406 * be notified about the completion when it calls pj_ioqueue_poll(). If data 
     407 * is immediately available, the function will return PJ_SUCCESS and the 
     408 * callback WILL NOT be called. 
     409 * 
    319410 * @param key       The key that uniquely identifies the handle. 
     411 * @param op_key    An operation specific key to be associated with the 
     412 *                  pending operation, so that application can keep track of 
     413 *                  which operation has been completed when the callback is 
     414 *                  called. Caller must make sure that this key remains  
     415 *                  valid until the function completes. 
    320416 * @param buffer    The buffer to hold the read data. The caller MUST make sure 
    321417 *                  that this buffer remain valid until the framework completes 
    322418 *                  reading the handle. 
    323  * @param buflen    The maximum size to be read. 
     419 * @param length    On input, it specifies the size of the buffer. If data is 
     420 *                  available to be read immediately, the function returns 
     421 *                  PJ_SUCCESS and this argument will be filled with the 
     422 *                  amount of data read. If the function is pending, caller 
     423 *                  will be notified about the amount of data read in the 
     424 *                  callback. This parameter can point to local variable in 
     425 *                  caller's stack and doesn't have to remain valid for the 
     426 *                  duration of pending operation. 
     427 * @param flags     Recv flag. 
     428 * 
     429 * @return 
     430 *  - PJ_SUCCESS    If immediate data has been received in the buffer. In this 
     431 *                  case, the callback WILL NOT be called. 
     432 *  - PJ_EPENDING   If the operation has been queued, and the callback will be 
     433 *                  called when data has been received. 
     434 *  - non-zero      The return value indicates the error code. 
     435 */ 
     436PJ_DECL(pj_status_t) pj_ioqueue_recv( pj_ioqueue_key_t *key, 
     437                                      pj_ioqueue_op_key_t *op_key, 
     438                                      void *buffer, 
     439                                      pj_ssize_t *length, 
     440                                      unsigned flags ); 
     441 
     442/** 
     443 * This function behaves similarly as #pj_ioqueue_recv(), except that it is 
     444 * normally called for socket, and the remote address will also be returned 
     445 * along with the data. Caller MUST make sure that both buffer and addr 
     446 * remain valid until the framework completes reading the data. 
     447 * 
     448 * @param key       The key that uniquely identifies the handle. 
     449 * @param op_key    An operation specific key to be associated with the 
     450 *                  pending operation, so that application can keep track of 
     451 *                  which operation has been completed when the callback is 
     452 *                  called. 
     453 * @param buffer    The buffer to hold the read data. The caller MUST make sure 
     454 *                  that this buffer remain valid until the framework completes 
     455 *                  reading the handle. 
     456 * @param length    On input, it specifies the size of the buffer. If data is 
     457 *                  available to be read immediately, the function returns 
     458 *                  PJ_SUCCESS and this argument will be filled with the 
     459 *                  amount of data read. If the function is pending, caller 
     460 *                  will be notified about the amount of data read in the 
     461 *                  callback. This parameter can point to local variable in 
     462 *                  caller's stack and doesn't have to remain valid for the 
     463 *                  duration of pending operation. 
     464 * @param flags     Recv flag. 
     465 * @param addr      Optional Pointer to buffer to receive the address. 
     466 * @param addrlen   On input, specifies the length of the address buffer. 
     467 *                  On output, it will be filled with the actual length of 
     468 *                  the address. This argument can be NULL if \c addr is not 
     469 *                  specified. 
    324470 * 
    325471 * @return 
     
    330476 *  - non-zero      The return value indicates the error code. 
    331477 */ 
    332 PJ_DECL(pj_status_t) pj_ioqueue_read( pj_ioqueue_t *ioque, 
    333                                       pj_ioqueue_key_t *key, 
    334                                       void *buffer, 
    335                                       pj_size_t buflen); 
    336  
    337  
    338 /** 
    339  * This function behaves similarly as #pj_ioqueue_read(), except that it is 
    340  * normally called for socket. 
    341  * 
    342  * @param ioque     The I/O Queue. 
    343  * @param key       The key that uniquely identifies the handle. 
    344  * @param buffer    The buffer to hold the read data. The caller MUST make sure 
    345  *                  that this buffer remain valid until the framework completes 
    346  *                  reading the handle. 
    347  * @param buflen    The maximum size to be read. 
    348  * @param flags     Recv flag. 
    349  * 
    350  * @return 
    351  *  - PJ_SUCCESS    If immediate data has been received. In this case, the  
    352  *                  callback must have been called before this function  
    353  *                  returns, and no pending operation is scheduled. 
    354  *  - PJ_EPENDING   If the operation has been queued. 
    355  *  - non-zero      The return value indicates the error code. 
    356  */ 
    357 PJ_DECL(pj_status_t) pj_ioqueue_recv( pj_ioqueue_t *ioque, 
    358                                       pj_ioqueue_key_t *key, 
    359                                       void *buffer, 
    360                                       pj_size_t buflen, 
    361                                       unsigned flags ); 
    362  
    363 /** 
    364  * This function behaves similarly as #pj_ioqueue_read(), except that it is 
    365  * normally called for socket, and the remote address will also be returned 
    366  * along with the data. Caller MUST make sure that both buffer and addr 
    367  * remain valid until the framework completes reading the data. 
    368  * 
    369  * @param ioque     The I/O Queue. 
    370  * @param key       The key that uniquely identifies the handle. 
    371  * @param buffer    The buffer to hold the read data. The caller MUST make sure 
    372  *                  that this buffer remain valid until the framework completes 
    373  *                  reading the handle. 
    374  * @param buflen    The maximum size to be read. 
    375  * @param flags     Recv flag. 
    376  * @param addr      Pointer to buffer to receive the address, or NULL. 
    377  * @param addrlen   On input, specifies the length of the address buffer. 
    378  *                  On output, it will be filled with the actual length of 
    379  *                  the address. 
    380  * 
    381  * @return 
    382  *  - PJ_SUCCESS    If immediate data has been received. In this case, the  
    383  *                  callback must have been called before this function  
    384  *                  returns, and no pending operation is scheduled. 
    385  *  - PJ_EPENDING   If the operation has been queued. 
    386  *  - non-zero      The return value indicates the error code. 
    387  */ 
    388 PJ_DECL(pj_status_t) pj_ioqueue_recvfrom( pj_ioqueue_t *ioque, 
    389                                           pj_ioqueue_key_t *key, 
     478PJ_DECL(pj_status_t) pj_ioqueue_recvfrom( pj_ioqueue_key_t *key, 
     479                                          pj_ioqueue_op_key_t *op_key, 
    390480                                          void *buffer, 
    391                                           pj_size_t buflen, 
     481                                          pj_ssize_t *length, 
    392482                                          unsigned flags, 
    393483                                          pj_sockaddr_t *addr, 
    394484                                          int *addrlen); 
    395485 
     486 
    396487/** 
    397488 * Instruct the I/O Queue to write to the handle. This function will return 
    398489 * immediately (i.e. non-blocking) regardless whether some data has been  
    399  * transfered. If the function can't complete immediately, and the caller will 
    400  * be notified about the completion when it calls pj_ioqueue_poll(). 
    401  * 
    402  * @param ioque     the I/O Queue. 
     490 * transfered. If the function can't complete immediately, the caller will 
     491 * be notified about the completion when it calls pj_ioqueue_poll(). If  
     492 * operation completes immediately and data has been transfered, the function 
     493 * returns PJ_SUCCESS and the callback will NOT be called. 
     494 * 
     495 * @param key       The key that identifies the handle. 
     496 * @param op_key    An operation specific key to be associated with the 
     497 *                  pending operation, so that application can keep track of 
     498 *                  which operation has been completed when the callback is 
     499 *                  called. 
     500 * @param data      The data to send. Caller MUST make sure that this buffer  
     501 *                  remains valid until the write operation completes. 
     502 * @param length    On input, it specifies the length of data to send. When 
     503 *                  data was sent immediately, this function returns PJ_SUCCESS 
     504 *                  and this parameter contains the length of data sent. If 
     505 *                  data can not be sent immediately, an asynchronous operation 
     506 *                  is scheduled and caller will be notified via callback the 
     507 *                  number of bytes sent. This parameter can point to local  
     508 *                  variable on caller's stack and doesn't have to remain  
     509 *                  valid until the operation has completed. 
     510 * @param flags     Send flags. 
     511 * 
     512 * @return 
     513 *  - PJ_SUCCESS    If data was immediately transfered. In this case, no 
     514 *                  pending operation has been scheduled and the callback 
     515 *                  WILL NOT be called. 
     516 *  - PJ_EPENDING   If the operation has been queued. Once data base been 
     517 *                  transfered, the callback will be called. 
     518 *  - non-zero      The return value indicates the error code. 
     519 */ 
     520PJ_DECL(pj_status_t) pj_ioqueue_send( pj_ioqueue_key_t *key, 
     521                                      pj_ioqueue_op_key_t *op_key, 
     522                                      const void *data, 
     523                                      pj_ssize_t *length, 
     524                                      unsigned flags ); 
     525 
     526 
     527/** 
     528 * This function behaves similarly as #pj_ioqueue_write(), except that 
     529 * pj_sock_sendto() (or equivalent) will be called to send the data. 
     530 * 
    403531 * @param key       the key that identifies the handle. 
     532 * @param op_key    An operation specific key to be associated with the 
     533 *                  pending operation, so that application can keep track of 
     534 *                  which operation has been completed when the callback is 
     535 *                  called. 
    404536 * @param data      the data to send. Caller MUST make sure that this buffer  
    405537 *                  remains valid until the write operation completes. 
    406  * @param datalen   the length of the data. 
     538 * @param length    On input, it specifies the length of data to send. When 
     539 *                  data was sent immediately, this function returns PJ_SUCCESS 
     540 *                  and this parameter contains the length of data sent. If 
     541 *                  data can not be sent immediately, an asynchronous operation 
     542 *                  is scheduled and caller will be notified via callback the 
     543 *                  number of bytes sent. This parameter can point to local  
     544 *                  variable on caller's stack and doesn't have to remain  
     545 *                  valid until the operation has completed. 
     546 * @param flags     send flags. 
     547 * @param addr      Optional remote address. 
     548 * @param addrlen   Remote address length, \c addr is specified. 
    407549 * 
    408550 * @return 
     
    411553 *  - non-zero      The return value indicates the error code. 
    412554 */ 
    413 PJ_DECL(pj_status_t) pj_ioqueue_write( pj_ioqueue_t *ioque, 
    414                                        pj_ioqueue_key_t *key, 
    415                                        const void *data, 
    416                                        pj_size_t datalen); 
    417  
    418 /** 
    419  * This function behaves similarly as #pj_ioqueue_write(), except that 
    420  * pj_sock_send() (or equivalent) will be called to send the data. 
    421  * 
    422  * @param ioque     the I/O Queue. 
    423  * @param key       the key that identifies the handle. 
    424  * @param data      the data to send. Caller MUST make sure that this buffer  
    425  *                  remains valid until the write operation completes. 
    426  * @param datalen   the length of the data. 
    427  * @param flags     send flags. 
    428  * 
    429  * @return 
    430  *  - PJ_SUCCESS    If data was immediately written. 
    431  *  - PJ_EPENDING   If the operation has been queued. 
    432  *  - non-zero      The return value indicates the error code. 
    433  */ 
    434 PJ_DECL(pj_status_t) pj_ioqueue_send( pj_ioqueue_t *ioque, 
    435                                       pj_ioqueue_key_t *key, 
    436                                       const void *data, 
    437                                       pj_size_t datalen, 
    438                                       unsigned flags ); 
    439  
    440  
    441 /** 
    442  * This function behaves similarly as #pj_ioqueue_write(), except that 
    443  * pj_sock_sendto() (or equivalent) will be called to send the data. 
    444  * 
    445  * @param ioque     the I/O Queue. 
    446  * @param key       the key that identifies the handle. 
    447  * @param data      the data to send. Caller MUST make sure that this buffer  
    448  *                  remains valid until the write operation completes. 
    449  * @param datalen   the length of the data. 
    450  * @param flags     send flags. 
    451  * @param addr      remote address. 
    452  * @param addrlen   remote address length. 
    453  * 
    454  * @return 
    455  *  - PJ_SUCCESS    If data was immediately written. 
    456  *  - PJ_EPENDING   If the operation has been queued. 
    457  *  - non-zero      The return value indicates the error code. 
    458  */ 
    459 PJ_DECL(pj_status_t) pj_ioqueue_sendto( pj_ioqueue_t *ioque, 
    460                                         pj_ioqueue_key_t *key, 
     555PJ_DECL(pj_status_t) pj_ioqueue_sendto( pj_ioqueue_key_t *key, 
     556                                        pj_ioqueue_op_key_t *op_key, 
    461557                                        const void *data, 
    462                                         pj_size_t datalen, 
     558                                        pj_ssize_t *length, 
    463559                                        unsigned flags, 
    464560                                        const pj_sockaddr_t *addr, 
Note: See TracChangeset for help on using the changeset viewer.