You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by as...@apache.org on 2021/03/05 04:01:15 UTC

[qpid-proton] branch master updated: PROTON-2340: Fix some TSAN issues in proactor raw connection

This is an automated email from the ASF dual-hosted git repository.

astitcher pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/qpid-proton.git


The following commit(s) were added to refs/heads/master by this push:
     new 80cc627  PROTON-2340: Fix some TSAN issues in proactor raw connection
80cc627 is described below

commit 80cc627d10bb0e5b1ebc46ed57de681c01fdfc34
Author: Andrew Stitcher <as...@apache.org>
AuthorDate: Thu Mar 4 22:47:06 2021 -0500

    PROTON-2340: Fix some TSAN issues in proactor raw connection
---
 c/examples/raw_echo.c                 | 15 ++++++++-------
 c/src/proactor/epoll_raw_connection.c |  4 ++++
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/c/examples/raw_echo.c b/c/examples/raw_echo.c
index 7c296e9..0f6515a 100644
--- a/c/examples/raw_echo.c
+++ b/c/examples/raw_echo.c
@@ -38,7 +38,6 @@ typedef struct app_data_t {
   pn_listener_t *listener;
 
   int64_t first_idle_time;
-  int64_t try_accept_time;
   int64_t wake_conn_time;
   int connects;
   int disconnects;
@@ -153,7 +152,8 @@ static void handle_receive(app_data_t *app, pn_event_t* event) {
         }
         pn_raw_connection_give_read_buffers(c, buffers, READ_BUFFERS);
       } else {
-        printf("**raw connection connected: not connected\n");
+        printf("**too many raw connections connected: closing\n");
+        pn_raw_connection_close(c);
       }
     } break;
 
@@ -167,11 +167,11 @@ static void handle_receive(app_data_t *app, pn_event_t* event) {
       pn_raw_connection_t *c = pn_event_raw_connection(event);
       conn_data_t *cd = (conn_data_t *) pn_raw_connection_get_context(c);
       if (cd) {
+        app->disconnects++;
         printf("**raw connection %tu disconnected: bytes: %d, buffers: %d\n", cd-conn_data, cd->bytes, cd->buffers);
       } else {
         printf("**raw connection disconnected: not connected\n");
       }
-      app->disconnects++;
       check_condition(event, pn_raw_connection_condition(c), app);
       pn_raw_connection_wake(c);
       free_conn_data(cd);
@@ -219,7 +219,9 @@ static void handle_receive(app_data_t *app, pn_event_t* event) {
 
     case PN_RAW_CONNECTION_CLOSED_READ: {
       pn_raw_connection_t *c = pn_event_raw_connection(event);
-      send_message(c, "** Goodbye **");
+      if (!pn_raw_connection_is_write_closed(c)) {
+        send_message(c, "** Goodbye **");
+      }
     }
     case PN_RAW_CONNECTION_CLOSED_WRITE:{
       pn_raw_connection_t *c = pn_event_raw_connection(event);
@@ -265,7 +267,6 @@ static bool handle(app_data_t* app, pn_event_t* event) {
 
       if (cd) {
         app->first_idle_time = 0;
-        app->try_accept_time = 0;
         if (app->wake_conn_time < now) {
           app->wake_conn_time = now + 5000;
           pn_proactor_set_timeout(pn_listener_proactor(listener), 5000);
@@ -276,9 +277,9 @@ static bool handle(app_data_t* app, pn_event_t* event) {
       } else {
         printf("**too many connections, trying again later...\n");
 
-        /* No other way to reject connection */
+        /* No other sensible/correct way to reject connection - have to defer closing to event handler */
+        pn_raw_connection_set_context(c, 0);
         pn_listener_raw_accept(listener, c);
-        pn_raw_connection_close(c);
       }
 
     } break;
diff --git a/c/src/proactor/epoll_raw_connection.c b/c/src/proactor/epoll_raw_connection.c
index 88410e3..99c5dd9 100644
--- a/c/src/proactor/epoll_raw_connection.c
+++ b/c/src/proactor/epoll_raw_connection.c
@@ -351,6 +351,7 @@ static void  set_error(pn_raw_connection_t *conn, const char *msg, int err) {
 
 pn_event_batch_t *pni_raw_connection_process(task_t *t, bool sched_ready) {
   praw_connection_t *rc = containerof(t, praw_connection_t, task);
+  lock(&rc->task.mutex);
   int events = rc->psocket.sched_io_events;
   int fd = rc->psocket.epoll_io.fd;
   if (!rc->connected) {
@@ -359,13 +360,16 @@ pn_event_batch_t *pni_raw_connection_process(task_t *t, bool sched_ready) {
     }
     if (rc->disconnected) {
       pni_raw_connect_failed(&rc->raw_connection);
+      unlock(&rc->task.mutex);
       return &rc->batch;
     }
     if (events & (EPOLLHUP | EPOLLERR)) {
+      unlock(&rc->task.mutex);
       return NULL;
     }
     praw_connection_connected_lh(rc);
   }
+  unlock(&rc->task.mutex);
 
   bool wake = false;
   lock(&t->mutex);


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org