diff options
-rw-r--r-- | pjlib/include/pj/activesock.h | 40 | ||||
-rw-r--r-- | pjlib/src/pj/activesock.c | 57 |
2 files changed, 93 insertions, 4 deletions
diff --git a/pjlib/include/pj/activesock.h b/pjlib/include/pj/activesock.h index f465de83..71662190 100644 --- a/pjlib/include/pj/activesock.h +++ b/pjlib/include/pj/activesock.h @@ -356,6 +356,26 @@ PJ_DECL(pj_status_t) pj_activesock_start_read(pj_activesock_t *asock, pj_uint32_t flags); /** + * Same as #pj_activesock_start_read(), except that the application + * supplies the buffers for the read operation so that the acive socket + * does not have to allocate the buffers. + * + * @param asock The active socket. + * @param pool Pool used to allocate buffers for incoming data. + * @param buff_size The size of each buffer, in bytes. + * @param readbuf Array of packet buffers, each has buff_size size. + * @param flags Flags to be given to pj_ioqueue_recv(). + * + * @return PJ_SUCCESS if the operation has been successful, + * or the appropriate error code on failure. + */ +PJ_DECL(pj_status_t) pj_activesock_start_read2(pj_activesock_t *asock, + pj_pool_t *pool, + unsigned buff_size, + void *readbuf[], + pj_uint32_t flags); + +/** * Same as pj_activesock_start_read(), except that this function is used * only for datagram sockets, and it will trigger \a on_data_recvfrom() * callback instead. @@ -374,6 +394,26 @@ PJ_DECL(pj_status_t) pj_activesock_start_recvfrom(pj_activesock_t *asock, pj_uint32_t flags); /** + * Same as #pj_activesock_start_recvfrom() except that the recvfrom() + * operation takes the buffer from the argument rather than creating + * new ones. + * + * @param asock The active socket. + * @param pool Pool used to allocate buffers for incoming data. + * @param buff_size The size of each buffer, in bytes. + * @param readbuf Array of packet buffers, each has buff_size size. + * @param flags Flags to be given to pj_ioqueue_recvfrom(). + * + * @return PJ_SUCCESS if the operation has been successful, + * or the appropriate error code on failure. + */ +PJ_DECL(pj_status_t) pj_activesock_start_recvfrom2(pj_activesock_t *asock, + pj_pool_t *pool, + unsigned buff_size, + void *readbuf[], + pj_uint32_t flags); + +/** * Send data using the socket. * * @param asock The active socket. diff --git a/pjlib/src/pj/activesock.c b/pjlib/src/pj/activesock.c index 4c3985db..9e53aef1 100644 --- a/pjlib/src/pj/activesock.c +++ b/pjlib/src/pj/activesock.c @@ -17,6 +17,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <pj/activesock.h> +#include <pj/compat/socket.h> #include <pj/assert.h> #include <pj/errno.h> #include <pj/pool.h> @@ -241,6 +242,28 @@ PJ_DEF(pj_status_t) pj_activesock_start_read(pj_activesock_t *asock, unsigned buff_size, pj_uint32_t flags) { + void **readbuf; + unsigned i; + + PJ_ASSERT_RETURN(asock && pool && buff_size, PJ_EINVAL); + + readbuf = (void**) pj_pool_calloc(pool, asock->async_count, + sizeof(void*)); + + for (i=0; i<asock->async_count; ++i) { + readbuf[i] = pj_pool_alloc(pool, buff_size); + } + + return pj_activesock_start_read2(asock, pool, buff_size, readbuf, flags); +} + + +PJ_DEF(pj_status_t) pj_activesock_start_read2( pj_activesock_t *asock, + pj_pool_t *pool, + unsigned buff_size, + void *readbuf[], + pj_uint32_t flags) +{ unsigned i; pj_status_t status; @@ -258,7 +281,7 @@ PJ_DEF(pj_status_t) pj_activesock_start_read(pj_activesock_t *asock, struct read_op *r = &asock->read_op[i]; pj_ssize_t size_to_read; - r->pkt = (pj_uint8_t*)pj_pool_alloc(pool, buff_size); + r->pkt = (pj_uint8_t*)readbuf[i]; r->max_size = size_to_read = buff_size; status = pj_ioqueue_recv(asock->key, &r->op_key, r->pkt, &size_to_read, @@ -278,6 +301,29 @@ PJ_DEF(pj_status_t) pj_activesock_start_recvfrom(pj_activesock_t *asock, unsigned buff_size, pj_uint32_t flags) { + void **readbuf; + unsigned i; + + PJ_ASSERT_RETURN(asock && pool && buff_size, PJ_EINVAL); + + readbuf = (void**) pj_pool_calloc(pool, asock->async_count, + sizeof(void*)); + + for (i=0; i<asock->async_count; ++i) { + readbuf[i] = pj_pool_alloc(pool, buff_size); + } + + return pj_activesock_start_recvfrom2(asock, pool, buff_size, + readbuf, flags); +} + + +PJ_DEF(pj_status_t) pj_activesock_start_recvfrom2( pj_activesock_t *asock, + pj_pool_t *pool, + unsigned buff_size, + void *readbuf[], + pj_uint32_t flags) +{ unsigned i; pj_status_t status; @@ -294,7 +340,7 @@ PJ_DEF(pj_status_t) pj_activesock_start_recvfrom(pj_activesock_t *asock, struct read_op *r = &asock->read_op[i]; pj_ssize_t size_to_read; - r->pkt = (pj_uint8_t*) pj_pool_alloc(pool, buff_size); + r->pkt = (pj_uint8_t*) readbuf[i]; r->max_size = size_to_read = buff_size; r->src_addr_len = sizeof(r->src_addr); @@ -371,8 +417,11 @@ static void ioqueue_on_read_complete(pj_ioqueue_key_t *key, r->size = 0; } - } else if (bytes_read <= 0) { - + } else if (bytes_read <= 0 && + -bytes_read != PJ_STATUS_FROM_OS(OSERR_EWOULDBLOCK) && + -bytes_read != PJ_STATUS_FROM_OS(OSERR_EINPROGRESS) && + -bytes_read != PJ_STATUS_FROM_OS(OSERR_ECONNRESET)) + { pj_size_t remainder; pj_bool_t ret; |