diff options
author | Greg Ames <gregames@apache.org> | 2013-01-17 23:46:43 +0000 |
---|---|---|
committer | Greg Ames <gregames@apache.org> | 2013-01-17 23:46:43 +0000 |
commit | ac6f26f29769b5207f72dd7291fd59bd0ca604aa (patch) | |
tree | d5baabd92362393ebc90e9878294feff5872ad64 /poll | |
parent | 9bc61714783bad05c2e8ddbe891de955dc2b6dc9 (diff) | |
download | apr-ac6f26f29769b5207f72dd7291fd59bd0ca604aa.tar.gz |
* create/set new state ASIO_COMPLETE to track when async i/o is complete
* in apr_pollset_remove, don't cancel async i/o if it has already completed
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1434971 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'poll')
-rw-r--r-- | poll/unix/z_asio.c | 41 |
1 files changed, 28 insertions, 13 deletions
diff --git a/poll/unix/z_asio.c b/poll/unix/z_asio.c index 9343f6b08..b584e37cf 100644 --- a/poll/unix/z_asio.c +++ b/poll/unix/z_asio.c @@ -77,7 +77,8 @@ struct apr_pollset_private_t typedef enum { ASIO_INIT = 0, - ASIO_REMOVED + ASIO_REMOVED, + ASIO_COMPLETE } asio_state_e; typedef struct asio_elem_t asio_elem_t; @@ -499,20 +500,24 @@ static apr_status_t asio_pollset_remove(apr_pollset_t *pollset, DBG1(5, "hash found fd %d\n", fd); /* delete this fd from the hash */ apr_hash_set(priv->elems, &(fd), sizeof(int), NULL); - /* asyncio call to cancel */ - elem->a.aio_cmd = AIO_CANCEL; - /* elem->a.aio_cflags = AIO_CANCELNONOTIFY; */ - /* we want *msgrcv to collect cancel notifications to remove races - * in garbage collection */ + if (elem->state == ASIO_INIT) { + /* asyncio call to cancel */ + elem->a.aio_cmd = AIO_CANCEL; - rv = asyncio(&elem->a); - DBG1(4, "asyncio returned %d\n", rv); + /* we want the original aiocb to show up on the pollset message queue + * to eliminate race conditions + */ - if (rv == 1) { - elem->state = ASIO_REMOVED; - rv = APR_SUCCESS; + rv = asyncio(&elem->a); + DBG1(4, "asyncio returned %d\n", rv); + +#if DEBUG + assert(rv == 1); +#endif } + elem->state = ASIO_REMOVED; + rv = APR_SUCCESS; } DBG1(2, "exiting, rv: %d\n", rv); @@ -567,16 +572,26 @@ static process_msg(apr_pollset_t *pollset, struct asio_msgbuf_t *msg) DBG_BUFF asio_elem_t *elem = msg->msg_elem; - if (elem->state == ASIO_REMOVED) { + switch(elem->state) { + case ASIO_REMOVED: DBG2(5, "for cancelled elem, recycling memory - elem %08p, fd %d\n", elem, elem->os_pfd.fd); APR_RING_INSERT_TAIL(&(pollset->p->free_ring), elem, asio_elem_t, link); - } else { + break; + case ASIO_INIT: DBG2(4, "adding to ready ring: elem %08p, fd %d\n", elem, elem->os_pfd.fd); + elem->state = ASIO_COMPLETE; APR_RING_INSERT_TAIL(&(pollset->p->ready_ring), elem, asio_elem_t, link); + break; + default: + DBG3(1, "unexpected state: elem %08p, fd %d, state %d\n", + elem, elem->os_pfd.fd, elem->state); +#if DEBUG + assert(0); +#endif } } |