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