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