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 2015/09/28 20:09:36 UTC
[10/50] [abbrv] qpid-proton git commit: PROTON-998: [C++ binding]
restore lost performance
PROTON-998: [C++ binding] restore lost performance
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/05beb218
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/05beb218
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/05beb218
Branch: refs/heads/proton-go
Commit: 05beb2183dc0c0232284f045007f8d3af2ed73e7
Parents: f17cc97
Author: Clifford Jansen <cl...@apache.org>
Authored: Wed Sep 16 10:56:30 2015 -0700
Committer: Clifford Jansen <cl...@apache.org>
Committed: Wed Sep 16 10:56:30 2015 -0700
----------------------------------------------------------------------
proton-c/bindings/cpp/include/proton/messaging_event.hpp | 3 ++-
proton-c/bindings/cpp/src/container_impl.cpp | 8 ++++++++
proton-c/bindings/cpp/src/contexts.hpp | 1 +
proton-c/bindings/cpp/src/messaging_adapter.cpp | 11 ++++++++++-
proton-c/bindings/cpp/src/messaging_event.cpp | 11 ++++++++---
5 files changed, 29 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/05beb218/proton-c/bindings/cpp/include/proton/messaging_event.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/include/proton/messaging_event.hpp b/proton-c/bindings/cpp/include/proton/messaging_event.hpp
index af22b41..5553faf 100644
--- a/proton-c/bindings/cpp/include/proton/messaging_event.hpp
+++ b/proton-c/bindings/cpp/include/proton/messaging_event.hpp
@@ -23,6 +23,7 @@
*/
#include "proton/proton_event.hpp"
#include "proton/link.hpp"
+#include "proton/message.hpp"
namespace proton {
@@ -98,7 +99,7 @@ class messaging_event : public proton_event
friend class messaging_adapter;
event_type type_;
proton_event *parent_event_;
- message_value message_;
+ class message *message_;
messaging_event operator=(const messaging_event&);
messaging_event(const messaging_event&);
};
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/05beb218/proton-c/bindings/cpp/src/container_impl.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/container_impl.cpp b/proton-c/bindings/cpp/src/container_impl.cpp
index a13d961..ca864a7 100644
--- a/proton-c/bindings/cpp/src/container_impl.cpp
+++ b/proton-c/bindings/cpp/src/container_impl.cpp
@@ -51,6 +51,14 @@ struct handler_context {
}
static void cleanup(pn_handler_t*) {}
+ /*
+ * NOTE: this call, at the transition from C to C++ is possibly
+ * the biggest performance bottleneck. "Average" clients ignore
+ * 90% of these events. Current strategy is to create the
+ * messaging_event on the stack. For success, the messaging_event
+ * should be small and free of indirect malloc/free/new/delete.
+ */
+
static void dispatch(pn_handler_t *c_handler, pn_event_t *c_event, pn_event_type_t type)
{
handler_context& hc(handler_context::get(c_handler));
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/05beb218/proton-c/bindings/cpp/src/contexts.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/contexts.hpp b/proton-c/bindings/cpp/src/contexts.hpp
index 80e3d00..1a11259 100644
--- a/proton-c/bindings/cpp/src/contexts.hpp
+++ b/proton-c/bindings/cpp/src/contexts.hpp
@@ -47,6 +47,7 @@ struct connection_context : public counted {
pn_unique_ptr<class handler> handler;
session* default_session; // Owned by connection
class container_impl* container_impl;
+ class message_value event_message; // re-used by messaging_adapter for performance
};
class container;
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/05beb218/proton-c/bindings/cpp/src/messaging_adapter.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/messaging_adapter.cpp b/proton-c/bindings/cpp/src/messaging_adapter.cpp
index 39d80b8..27dcc34 100644
--- a/proton-c/bindings/cpp/src/messaging_adapter.cpp
+++ b/proton-c/bindings/cpp/src/messaging_adapter.cpp
@@ -23,12 +23,14 @@
#include "proton/sender.hpp"
#include "proton/error.hpp"
#include "msg.hpp"
+#include "contexts.hpp"
#include "proton/link.h"
#include "proton/handlers.h"
#include "proton/delivery.h"
#include "proton/connection.h"
#include "proton/session.h"
+#include "proton/message.h"
namespace proton {
messaging_adapter::messaging_adapter(messaging_handler &delegate_) :
@@ -72,7 +74,14 @@ void messaging_adapter::on_delivery(event &e) {
if (!pn_delivery_partial(dlv) && pn_delivery_readable(dlv)) {
// generate on_message
messaging_event mevent(messaging_event::MESSAGE, *pe);
- mevent.message_.decode(*reinterpret_cast<link*>(lnk), *reinterpret_cast<delivery*>(dlv));
+ pn_connection_t *pnc = pn_session_connection(pn_link_session(lnk));
+ struct connection_context& ctx = connection_context::get(pnc);
+ // Reusable per-connection message. Avoid expensive heap malloc/free overhead.
+ // See PROTON-998
+ class message &msg(ctx.event_message);
+ mevent.message_ = &msg;
+
+ mevent.message_->decode(*reinterpret_cast<link*>(lnk), *reinterpret_cast<delivery*>(dlv));
if (pn_link_state(lnk) & PN_LOCAL_CLOSED) {
if (auto_accept_) {
pn_delivery_update(dlv, PN_RELEASED);
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/05beb218/proton-c/bindings/cpp/src/messaging_event.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/messaging_event.cpp b/proton-c/bindings/cpp/src/messaging_event.cpp
index ece1c4e..82f9159 100644
--- a/proton-c/bindings/cpp/src/messaging_event.cpp
+++ b/proton-c/bindings/cpp/src/messaging_event.cpp
@@ -33,14 +33,19 @@
#include "msg.hpp"
#include "contexts.hpp"
+/*
+ * Performance note:
+ * See comments for handler_context::dispatch() in container_impl.cpp.
+ */
+
namespace proton {
messaging_event::messaging_event(pn_event_t *ce, proton_event::event_type t, class container &c) :
- proton_event(ce, t, c), type_(messaging_event::PROTON), parent_event_(0)
+ proton_event(ce, t, c), type_(messaging_event::PROTON), parent_event_(0), message_(0)
{}
messaging_event::messaging_event(event_type t, proton_event &p) :
- proton_event(NULL, PN_EVENT_NONE, p.container()), type_(t), parent_event_(&p)
+ proton_event(NULL, PN_EVENT_NONE, p.container()), type_(t), parent_event_(&p), message_(0)
{
if (type_ == messaging_event::PROTON)
throw error(MSG("invalid messaging event type"));
@@ -93,7 +98,7 @@ delivery& messaging_event::delivery() {
message &messaging_event::message() {
if (type_ != messaging_event::MESSAGE || !parent_event_)
throw error(MSG("event type does not provide message"));
- return message_;
+ return *message_;
}
void messaging_event::dispatch(handler &h) {
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org