From 40caf8dbdb9d82c13af800341b2dac4ccbc39fe2 Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Mon, 22 Oct 2018 20:00:00 +0200 Subject: [PATCH] lazy unmarshalling for COM interface on sync thread --- CpEpEngine.cpp | 20 ++++++++++++++------ CpEpEngine.h | 17 ++++++++++------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/CpEpEngine.cpp b/CpEpEngine.cpp index 859a613..448eb3f 100644 --- a/CpEpEngine.cpp +++ b/CpEpEngine.cpp @@ -12,7 +12,7 @@ using namespace pEp::Adapter; // CpEpEngine -pEp::pc_container< CpEpEngine::MarshaledCallbacks, IpEpEngineCallbacks > CpEpEngine::sync_callbacks; +CpEpEngine::callback_container CpEpEngine::sync_callbacks; // the init_mutex protects our initialization and destruction // against a running keysync thread, and it ensures that the @@ -736,6 +736,18 @@ int CpEpEngine::examine_identity(pEp_identity *ident, void *management) return _ident; } +static IpEpEngineCallbacks * _unmarshaled_consumer(CpEpEngine::callback_container::Container::const_iterator p) +{ + if (!p->cdata && p->pdata->marshaled) { + HRESULT r = CoGetInterfaceAndReleaseStream(p->pdata->marshaled, IID_IpEpEngineCallbacks, (LPVOID*) &p->cdata); + if (!SUCCEEDED(r)) + throw runtime_error("_unmarshaled_consumer(): CoGetInterfaceAndReleaseStream() failed"); + p->pdata->marshaled = nullptr; + } + + return p->cdata; +} + PEP_STATUS CpEpEngine::messageToSend(message *msg) { assert(msg); @@ -745,11 +757,7 @@ PEP_STATUS CpEpEngine::messageToSend(message *msg) bool in_sync = on_sync_thread(); for (auto p = sync_callbacks.begin(); p != sync_callbacks.end(); ++p) { - IpEpEngineCallbacks *cb; - if (in_sync) - cb = p->cdata; - else - cb = p->pdata->unmarshaled; + IpEpEngineCallbacks *cb = in_sync ? _unmarshaled_consumer(p) : p->pdata->unmarshaled; if (cb) { TextMessage _msg; diff --git a/CpEpEngine.h b/CpEpEngine.h index 828071b..da9fa29 100644 --- a/CpEpEngine.h +++ b/CpEpEngine.h @@ -84,11 +84,11 @@ public: return res; } + startup(messageToSend, notifyHandshake, this, &CpEpEngine::Startup_sync); + ::register_examine_function(session(), CpEpEngine::examine_identity, (void *)this); ::log_event(session(), "Startup", "pEp COM Adapter", NULL, NULL); - startup(messageToSend, notifyHandshake, this, &CpEpEngine::Startup_sync); - return S_OK; } @@ -96,6 +96,13 @@ public: { } + struct MarshaledCallbacks { + IpEpEngineCallbacks *unmarshaled; + LPSTREAM marshaled; + }; + + typedef pEp::pc_container< MarshaledCallbacks, IpEpEngineCallbacks > callback_container; + protected: typedef locked_queue identity_queue_t; static ::pEp_identity * retrieve_next_identity(void *management); @@ -117,12 +124,8 @@ protected: private: // callbacks for sync - struct MarshaledCallbacks { - IpEpEngineCallbacks *unmarshaled; - LPSTREAM marshaled; - }; - static pEp::pc_container< MarshaledCallbacks, IpEpEngineCallbacks > sync_callbacks; + static callback_container sync_callbacks; void Startup_sync() {