You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ac...@apache.org on 2017/06/09 01:25:25 UTC
[02/50] [abbrv] qpid-proton git commit: PROTON-1460: epoll - don't
issue wake events after transport closed
PROTON-1460: epoll - don't issue wake events after transport closed
The application may have deleted resources associated with the connection
after PN_TRANSPORT_CLOSED, so we should not issue PN_CONNECTION_WAKE even
if there is a wake call concurrently with closing the connection.
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/941c7d66
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/941c7d66
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/941c7d66
Branch: refs/heads/go1
Commit: 941c7d66be683217593d998be7c1dd91b46886a9
Parents: 4b33c42
Author: Alan Conway <ac...@redhat.com>
Authored: Mon May 8 20:20:57 2017 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Mon May 8 20:20:57 2017 -0400
----------------------------------------------------------------------
proton-c/src/proactor/epoll.c | 13 ++++++-------
proton-c/src/tests/proactor.c | 18 ++++++++++++++++--
2 files changed, 22 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/941c7d66/proton-c/src/proactor/epoll.c
----------------------------------------------------------------------
diff --git a/proton-c/src/proactor/epoll.c b/proton-c/src/proactor/epoll.c
index 3b71eac..9867cf8 100644
--- a/proton-c/src/proactor/epoll.c
+++ b/proton-c/src/proactor/epoll.c
@@ -634,7 +634,7 @@ static void pconnection_cleanup(pconnection_t *pc) {
}
// Call with lock held or from forced_shutdown
-void pconnection_begin_close(pconnection_t *pc) {
+static void pconnection_begin_close(pconnection_t *pc) {
if (!pc->context.closing) {
pc->context.closing = true;
stop_polling(&pc->psocket.epoll_io, pc->psocket.proactor->epollfd);
@@ -736,7 +736,7 @@ static void pconnection_done(pconnection_t *pc) {
pc->hog_count = 0;
if (pconnection_has_event(pc) || pconnection_work_pending(pc)) {
notify = wake(&pc->context);
- } else if (pconnection_rclosed(pc) && pn_connection_driver_finished(&pc->driver)) {
+ } else if (pn_connection_driver_finished(&pc->driver)) {
pconnection_begin_close(pc);
if (pconnection_is_final(pc)) {
unlock(&pc->context.mutex);
@@ -840,15 +840,14 @@ static pn_event_batch_t *pconnection_process(pconnection_t *pc, uint32_t events,
unlock(&pc->context.mutex);
return &pc->batch;
}
-
+ bool closed = pconnection_rclosed(pc) && pconnection_wclosed(pc);
if (pc->wake_count) {
- waking = true;
+ waking = !closed;
pc->wake_count = 0;
}
if (pc->tick_pending) {
pc->tick_pending = false;
- if (!(pconnection_rclosed(pc) && pconnection_wclosed(pc)))
- tick_required = true;
+ tick_required = !closed;
}
if (pc->new_events) {
@@ -956,7 +955,7 @@ static pn_event_batch_t *pconnection_process(pconnection_t *pc, uint32_t events,
pc->context.working = false;
pc->hog_count = 0;
- if (pconnection_rclosed(pc) && pn_connection_driver_finished(&pc->driver)) {
+ if (pn_connection_driver_finished(&pc->driver)) {
pconnection_begin_close(pc);
if (pconnection_is_final(pc)) {
unlock(&pc->context.mutex);
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/941c7d66/proton-c/src/tests/proactor.c
----------------------------------------------------------------------
diff --git a/proton-c/src/tests/proactor.c b/proton-c/src/tests/proactor.c
index 892ab2d..0a6df71 100644
--- a/proton-c/src/tests/proactor.c
+++ b/proton-c/src/tests/proactor.c
@@ -294,7 +294,7 @@ static pn_event_type_t open_wake_handler(test_t *t, pn_event_t *e) {
/* Test waking up a connection that is idle */
static void test_connection_wake(test_t *t) {
- proactor_test_t pts[] = { { open_wake_handler }, { common_handler } };
+ proactor_test_t pts[] = { { open_wake_handler }, { listen_handler } };
PROACTOR_TEST_INIT(pts, t);
pn_proactor_t *client = pts[0].proactor, *server = pts[1].proactor;
test_port_t port = test_port(localhost); /* Hold a port */
@@ -310,8 +310,22 @@ static void test_connection_wake(test_t *t) {
pn_connection_wake(c);
TEST_ETYPE_EQUAL(t, PN_CONNECTION_WAKE, PROACTOR_TEST_RUN(pts));
TEST_ETYPE_EQUAL(t, PN_TRANSPORT_CLOSED, PROACTOR_TEST_RUN(pts));
+ TEST_ETYPE_EQUAL(t, PN_TRANSPORT_CLOSED, PROACTOR_TEST_RUN(pts)); /* Both ends */
/* The pn_connection_t is still valid so wake is legal but a no-op */
- pn_connection_wake(c);
+ TEST_ETYPE_EQUAL(t, PN_PROACTOR_INACTIVE, PROACTOR_TEST_RUN(pts));
+ TEST_ETYPE_EQUAL(t, PN_EVENT_NONE, PROACTOR_TEST_GET(pts)); /* No more wake */
+
+ /* Verify we don't get a wake after close even if they happen together */
+ pn_connection_t *c2 = pn_connection();
+ pn_proactor_connect(client, c2, port.host_port);
+ TEST_ETYPE_EQUAL(t, PN_CONNECTION_REMOTE_OPEN, PROACTOR_TEST_RUN(pts));
+ pn_connection_wake(c2);
+ pn_proactor_disconnect(client, NULL);
+ pn_connection_wake(c2);
+
+ TEST_ETYPE_EQUAL(t, PN_TRANSPORT_CLOSED, proactor_test_run(&pts[0], 1));
+ TEST_ETYPE_EQUAL(t, PN_PROACTOR_INACTIVE, proactor_test_run(&pts[0], 1));
+ TEST_ETYPE_EQUAL(t, PN_EVENT_NONE, proactor_test_get(&pts[0], 1)); /* No late wake */
PROACTOR_TEST_FREE(pts);
/* The pn_connection_t is still valid so wake is legal but a no-op */
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org