PROTON-1618: c proactor: unambiguous listen success/fail indicator Changed the use of events in all 3 proactor implementations as follows:
After a call to pn_proactor_listen(): - on success, dispatch PN_LISTENER_OPEN before any PN_PROACTOR_ACCEPT - on failure, set the pn_listener_condition() and dispatch PN_LISTENER_CLOSE An application can tell from the first event received (OPEN vs. CLOSE) if the OS listen call succeeded or failed. Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/d0b641b7 Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/d0b641b7 Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/d0b641b7 Branch: refs/heads/go1 Commit: d0b641b75eb235d9959bab2792c0264522396321 Parents: 198664f Author: Alan Conway <acon...@redhat.com> Authored: Tue Oct 10 14:19:53 2017 -0400 Committer: Alan Conway <acon...@redhat.com> Committed: Wed Oct 11 22:04:42 2017 -0400 ---------------------------------------------------------------------- proton-c/include/proton/proactor.h | 7 ++++--- proton-c/src/proactor/epoll.c | 4 ++-- proton-c/src/proactor/libuv.c | 4 ++-- proton-c/src/proactor/win_iocp.c | 5 ++--- proton-c/src/tests/proactor.c | 3 --- 5 files changed, 10 insertions(+), 13 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d0b641b7/proton-c/include/proton/proactor.h ---------------------------------------------------------------------- diff --git a/proton-c/include/proton/proactor.h b/proton-c/include/proton/proactor.h index 414883a..52d3891 100644 --- a/proton-c/include/proton/proactor.h +++ b/proton-c/include/proton/proactor.h @@ -122,11 +122,12 @@ PNP_EXTERN void pn_proactor_connect(pn_proactor_t *proactor, pn_connection_t *co * Start listening for incoming connections. * * pn_proactor_wait() will return a @ref PN_LISTENER_OPEN event when the - * listener is ready to accept connections, or if the listen operation fails. - * If the listen operation failed, then pn_listener_condition() will be set. + * listener is ready to accept connections, or a PN_LISTENER_CLOSE if the listen + * operation fails. If the listen failed, pn_listener_condition() will be set. * * When the listener is closed by pn_listener_close(), or because of an error, a - * PN_LISTENER_CLOSE event will be returned and pn_listener_condition() will be set. + * PN_LISTENER_CLOSE event will be returned and pn_listener_condition() will be set + * for an error. * * @note Thread-safe * http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d0b641b7/proton-c/src/proactor/epoll.c ---------------------------------------------------------------------- diff --git a/proton-c/src/proactor/epoll.c b/proton-c/src/proactor/epoll.c index d739ab1..3cec04c 100644 --- a/proton-c/src/proactor/epoll.c +++ b/proton-c/src/proactor/epoll.c @@ -1401,8 +1401,6 @@ void pn_proactor_listen(pn_proactor_t *p, pn_listener_t *l, const char *addr, in if (addrinfo) { freeaddrinfo(addrinfo); } - /* Always put an OPEN event for symmetry, even if we immediately close with err */ - pn_collector_put(l->collector, pn_listener__class(), l, PN_LISTENER_OPEN); bool notify = wake(&l->context); if (l->psockets_size == 0) { /* All failed, create dummy socket with an error */ @@ -1414,6 +1412,8 @@ void pn_proactor_listen(pn_proactor_t *p, pn_listener_t *l, const char *addr, in } else { psocket_error(l->psockets, errno, "listen on"); } + } else { + pn_collector_put(l->collector, pn_listener__class(), l, PN_LISTENER_OPEN); } proactor_add(&l->context); unlock(&l->context.mutex); http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d0b641b7/proton-c/src/proactor/libuv.c ---------------------------------------------------------------------- diff --git a/proton-c/src/proactor/libuv.c b/proton-c/src/proactor/libuv.c index 5effbfe..4088b07 100644 --- a/proton-c/src/proactor/libuv.c +++ b/proton-c/src/proactor/libuv.c @@ -641,9 +641,9 @@ static void leader_listen_lh(pn_listener_t *l) { } if (err) { listener_error_lh(l, err, "listening on"); + } else { + pn_collector_put(l->collector, pn_listener__class(), l, PN_LISTENER_OPEN); } - /* Always put an OPEN event for symmetry, even if we have an error. */ - pn_collector_put(l->collector, pn_listener__class(), l, PN_LISTENER_OPEN); } void pn_listener_free(pn_listener_t *l) { http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d0b641b7/proton-c/src/proactor/win_iocp.c ---------------------------------------------------------------------- diff --git a/proton-c/src/proactor/win_iocp.c b/proton-c/src/proactor/win_iocp.c index 9a27ae6..09d39cf 100644 --- a/proton-c/src/proactor/win_iocp.c +++ b/proton-c/src/proactor/win_iocp.c @@ -2810,9 +2810,6 @@ void pn_proactor_listen(pn_proactor_t *p, pn_listener_t *l, const char *addr, in if (addrinfo) { freeaddrinfo(addrinfo); } - /* Always put an OPEN event for symmetry, even if we immediately close with err */ - pn_collector_put(l->collector, pn_listener__class(), l, PN_LISTENER_OPEN); - if (l->psockets_size == 0) { /* All failed, create dummy socket with an error */ l->psockets = (psocket_t*)calloc(sizeof(psocket_t), 1); psocket_init(l->psockets, l, false, addr); @@ -2821,6 +2818,8 @@ void pn_proactor_listen(pn_proactor_t *p, pn_listener_t *l, const char *addr, in } else { psocket_error(l->psockets, wsa_err, "listen on"); } + } else { + pn_collector_put(l->collector, pn_listener__class(), l, PN_LISTENER_OPEN); } wakeup(l->psockets); } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d0b641b7/proton-c/src/tests/proactor.c ---------------------------------------------------------------------- diff --git a/proton-c/src/tests/proactor.c b/proton-c/src/tests/proactor.c index 2a71f6f..5296802 100644 --- a/proton-c/src/tests/proactor.c +++ b/proton-c/src/tests/proactor.c @@ -584,7 +584,6 @@ static void test_errors(test_t *t) { TEST_ETYPE_EQUAL(t, PN_PROACTOR_INACTIVE, TEST_PROACTORS_RUN(tps)); pn_proactor_listen(server, pn_listener(), "127.0.0.1:xxx", 1); - TEST_ETYPE_EQUAL(t, PN_LISTENER_OPEN, TEST_PROACTORS_RUN(tps)); TEST_ETYPE_EQUAL(t, PN_LISTENER_CLOSE, TEST_PROACTORS_RUN(tps)); TEST_COND_DESC(t, "xxx", last_condition); TEST_ETYPE_EQUAL(t, PN_PROACTOR_INACTIVE, TEST_PROACTORS_RUN(tps)); @@ -597,7 +596,6 @@ static void test_errors(test_t *t) { TEST_ETYPE_EQUAL(t, PN_PROACTOR_INACTIVE, TEST_PROACTORS_RUN(tps)); pn_proactor_listen(server, pn_listener(), "nosuch.example.com:", 1); - TEST_ETYPE_EQUAL(t, PN_LISTENER_OPEN, TEST_PROACTORS_RUN(tps)); TEST_ETYPE_EQUAL(t, PN_LISTENER_CLOSE, TEST_PROACTORS_RUN(tps)); TEST_COND_DESC(t, "nosuch", last_condition); TEST_ETYPE_EQUAL(t, PN_PROACTOR_INACTIVE, TEST_PROACTORS_RUN(tps)); @@ -608,7 +606,6 @@ static void test_errors(test_t *t) { pn_proactor_listen(server, l, port.host_port, 1); TEST_ETYPE_EQUAL(t, PN_LISTENER_OPEN, TEST_PROACTORS_RUN(tps)); pn_proactor_listen(server, pn_listener(), port.host_port, 1); /* Busy */ - TEST_ETYPE_EQUAL(t, PN_LISTENER_OPEN, TEST_PROACTORS_RUN(tps)); TEST_ETYPE_EQUAL(t, PN_LISTENER_CLOSE, TEST_PROACTORS_RUN(tps)); TEST_COND_NAME(t, "proton:io", last_condition); pn_listener_close(l); --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org