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 2018/02/22 20:12:07 UTC

[2/4] qpid-proton git commit: PROTON-1734: Fix the semantics of pn_proactor_disconnect() - Make sure that an PN_PROACTOR_INACTIVE event is always generated even if the proactor was inactive before. This ensures that we can use disconnect effectively

PROTON-1734: Fix the semantics of pn_proactor_disconnect()
- Make sure that an PN_PROACTOR_INACTIVE event is always generated
  even if the proactor was inactive before. This ensures that we
  can use disconnect effectively even before making connections


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/5d47e615
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/5d47e615
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/5d47e615

Branch: refs/heads/master
Commit: 5d47e615a8ba322a65fd41735c0c6adb36828bed
Parents: 093355f
Author: Andrew Stitcher <as...@apache.org>
Authored: Thu Feb 22 01:58:55 2018 -0500
Committer: Andrew Stitcher <as...@apache.org>
Committed: Thu Feb 22 10:40:15 2018 -0500

----------------------------------------------------------------------
 proton-c/bindings/cpp/src/proactor_container_impl.cpp | 14 +++++++++++++-
 proton-c/bindings/cpp/src/proactor_container_impl.hpp |  1 +
 proton-c/src/proactor/epoll.c                         |  8 ++++++--
 proton-c/src/proactor/libuv.c                         | 10 +++++++---
 4 files changed, 27 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5d47e615/proton-c/bindings/cpp/src/proactor_container_impl.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/proactor_container_impl.cpp b/proton-c/bindings/cpp/src/proactor_container_impl.cpp
index 988521c..15eff0a 100644
--- a/proton-c/bindings/cpp/src/proactor_container_impl.cpp
+++ b/proton-c/bindings/cpp/src/proactor_container_impl.cpp
@@ -143,7 +143,7 @@ class work_queue::impl* container::impl::make_work_queue(container& c) {
 
 container::impl::impl(container& c, const std::string& id, messaging_handler* mh)
     : threads_(0), container_(c), proactor_(pn_proactor()), handler_(mh), id_(id),
-      auto_stop_(true), stopping_(false)
+      reconnecting_(0), auto_stop_(true), stopping_(false)
 {}
 
 container::impl::~impl() {
@@ -217,6 +217,15 @@ void container::impl::start_connection(const url& url, pn_connection_t *pnc) {
 }
 
 void container::impl::reconnect(pn_connection_t* pnc) {
+    --reconnecting_;
+
+    if (stopping_ && reconnecting_==0) {
+        pn_connection_free(pnc);
+        //TODO: We've lost the error - we should really propagate it here
+        pn_proactor_disconnect(proactor_, NULL);
+        return;
+    }
+
     connection_context& cc = connection_context::get(pnc);
     reconnect_context& rc = *cc.reconnect_context_.get();
     const reconnect_options::impl& roi = *rc.reconnect_options_->impl_;
@@ -318,6 +327,7 @@ bool container::impl::setup_reconnect(pn_connection_t* pnc) {
     // Schedule reconnect - can do this on container work queue as no one can have the connection
     // now anyway
     schedule(delay, make_work(&container::impl::reconnect, this, pnc));
+    ++reconnecting_;
 
     return true;
 }
@@ -727,6 +737,8 @@ void container::impl::stop(const proton::error_condition& err) {
         if (stopping_) return;  // Already stopping
         auto_stop_ = true;
         stopping_ = true;
+        // Have to wait until actual reconnect to stop or we leak the connection
+        if (reconnecting_>0) return;
     }
     pn_condition_t* error_condition = pn_condition();
     set_error_condition(err, error_condition);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5d47e615/proton-c/bindings/cpp/src/proactor_container_impl.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/proactor_container_impl.hpp b/proton-c/bindings/cpp/src/proactor_container_impl.hpp
index 06dbcb5..43b695f 100644
--- a/proton-c/bindings/cpp/src/proactor_container_impl.hpp
+++ b/proton-c/bindings/cpp/src/proactor_container_impl.hpp
@@ -147,6 +147,7 @@ class container::impl {
     proton::receiver_options receiver_options_;
     error_condition disconnect_error_;
 
+    unsigned reconnecting_;
     bool auto_stop_;
     bool stopping_;
     friend class connector;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5d47e615/proton-c/src/proactor/epoll.c
----------------------------------------------------------------------
diff --git a/proton-c/src/proactor/epoll.c b/proton-c/src/proactor/epoll.c
index 5f8c495..4ad2506 100644
--- a/proton-c/src/proactor/epoll.c
+++ b/proton-c/src/proactor/epoll.c
@@ -2103,6 +2103,8 @@ pn_proactor_t *pn_connection_proactor(pn_connection_t* c) {
 }
 
 void pn_proactor_disconnect(pn_proactor_t *p, pn_condition_t *cond) {
+  bool notify = false;
+
   lock(&p->context.mutex);
   // Move the whole contexts list into a disconnecting state
   pcontext_t *disconnecting_pcontexts = p->contexts;
@@ -2115,12 +2117,14 @@ void pn_proactor_disconnect(pn_proactor_t *p, pn_condition_t *cond) {
     p->disconnects_pending++;
     ctx = ctx->next;
   }
+  notify = wake_if_inactive(p);
   unlock(&p->context.mutex);
-  if (!disconnecting_pcontexts)
+  if (!disconnecting_pcontexts) {
+    if (notify) wake_notify(&p->context);
     return;
+  }
 
   // Second pass: different locking, close the pcontexts, free them if !disconnect_ops
-  bool notify = false;
   for (ctx = disconnecting_pcontexts; ctx; ctx = ctx->next) {
     bool do_free = false;
     bool ctx_notify = true;

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/5d47e615/proton-c/src/proactor/libuv.c
----------------------------------------------------------------------
diff --git a/proton-c/src/proactor/libuv.c b/proton-c/src/proactor/libuv.c
index 5e3c7c2..9329967 100644
--- a/proton-c/src/proactor/libuv.c
+++ b/proton-c/src/proactor/libuv.c
@@ -989,9 +989,13 @@ static pn_event_batch_t *leader_lead_lh(pn_proactor_t *p, uv_run_mode mode) {
   /* If disconnect was requested, walk the socket list */
   if (p->disconnect) {
     p->disconnect = false;
-    uv_mutex_unlock(&p->lock);
-    uv_walk(&p->loop, on_proactor_disconnect, NULL);
-    uv_mutex_lock(&p->lock);
+    if (p->active) {
+      uv_mutex_unlock(&p->lock);
+      uv_walk(&p->loop, on_proactor_disconnect, NULL);
+      uv_mutex_lock(&p->lock);
+    } else {
+      p->need_inactive = true;  /* Send INACTIVE right away, nothing to do. */
+    }
   }
   pn_event_batch_t *batch = NULL;
   for (work_t *w = work_pop(&p->leader_q); w; w = work_pop(&p->leader_q)) {


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