|
|
@ -8,6 +8,9 @@ |
|
|
|
#include "status_to_string.hh" |
|
|
|
#include "pEpLog.hh" |
|
|
|
#include "passphrase_cache.hh" |
|
|
|
#include "callback_dispatcher.hh" |
|
|
|
#include "group_manager_api.h" |
|
|
|
#include <iostream> |
|
|
|
|
|
|
|
using namespace std; |
|
|
|
|
|
|
@ -36,18 +39,12 @@ namespace pEp { |
|
|
|
throw RuntimeError(_status, status); |
|
|
|
} |
|
|
|
|
|
|
|
RuntimeError::RuntimeError(const std::string &_text, ::PEP_STATUS _status) |
|
|
|
: std::runtime_error(_text.c_str()), text(_text), status(_status) |
|
|
|
RuntimeError::RuntimeError(const std::string &_text, ::PEP_STATUS _status) : |
|
|
|
std::runtime_error(_text.c_str()), text(_text), status(_status) |
|
|
|
{ |
|
|
|
} |
|
|
|
|
|
|
|
namespace Adapter { |
|
|
|
// private
|
|
|
|
SyncModes _sync_mode = SyncModes::Async; |
|
|
|
::messageToSend_t _messageToSend = nullptr; |
|
|
|
::notifyHandshake_t _notifyHandshake = nullptr; |
|
|
|
bool _adapter_manages_sync_thread = false; |
|
|
|
::inject_sync_event_t _inject_action = _inject_sync_event; |
|
|
|
std::thread _sync_thread; |
|
|
|
::utility::locked_queue<SYNC_EVENT, ::free_Sync_event> sync_evt_q; |
|
|
|
std::mutex mut; |
|
|
@ -58,67 +55,6 @@ namespace pEp { |
|
|
|
return _sync_thread.get_id(); |
|
|
|
} |
|
|
|
|
|
|
|
// public
|
|
|
|
void sync_initialize( |
|
|
|
SyncModes mode, |
|
|
|
::messageToSend_t messageToSend, |
|
|
|
::notifyHandshake_t notifyHandshake, |
|
|
|
bool adapter_manages_sync_thread) |
|
|
|
{ |
|
|
|
_messageToSend = messageToSend; |
|
|
|
_notifyHandshake = notifyHandshake; |
|
|
|
_adapter_manages_sync_thread = adapter_manages_sync_thread; |
|
|
|
set_sync_mode(mode); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// public
|
|
|
|
void set_sync_mode(SyncModes mode) |
|
|
|
{ |
|
|
|
// std::lock_guard<mutex> lock(mut);
|
|
|
|
_sync_mode = mode; |
|
|
|
if (_sync_mode == SyncModes::Sync) { |
|
|
|
// init session with inject_sync = process
|
|
|
|
// stop sync
|
|
|
|
session(release); |
|
|
|
_inject_action = _process_sync_event; |
|
|
|
session(init); |
|
|
|
::register_sync_callbacks(session(), nullptr, _notifyHandshake, _retrieve_next_sync_event); |
|
|
|
if(!_adapter_manages_sync_thread) { |
|
|
|
shutdown(); |
|
|
|
} else { |
|
|
|
// The adapter need to shutdown sync thread
|
|
|
|
} |
|
|
|
} |
|
|
|
if (_sync_mode == SyncModes::Async) { |
|
|
|
// init session with inject_sync = queue
|
|
|
|
// start sync thread
|
|
|
|
session(release); |
|
|
|
_inject_action = _inject_sync_event; |
|
|
|
session(init); |
|
|
|
if(!_adapter_manages_sync_thread) { |
|
|
|
if (!is_sync_running()) { |
|
|
|
startup<void>(_messageToSend, _notifyHandshake, nullptr, nullptr); |
|
|
|
} |
|
|
|
} else { |
|
|
|
// The adapter need to do sync thread start up
|
|
|
|
} |
|
|
|
} |
|
|
|
if (_sync_mode == SyncModes::Off) { |
|
|
|
// init sesssion with inject_sync = null
|
|
|
|
// stop sync thread
|
|
|
|
if(!_adapter_manages_sync_thread) { |
|
|
|
shutdown(); |
|
|
|
} else { |
|
|
|
// Adapter needs to shutdown sync thread
|
|
|
|
} |
|
|
|
session(release); |
|
|
|
_inject_action = _inject_sync_event; |
|
|
|
session(init); |
|
|
|
} |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// private
|
|
|
|
int _process_sync_event(::SYNC_EVENT ev, void *management) |
|
|
|
{ |
|
|
@ -171,34 +107,104 @@ namespace pEp { |
|
|
|
return _sync_thread.get_id() == this_thread::get_id(); |
|
|
|
} |
|
|
|
|
|
|
|
// public
|
|
|
|
::PEP_SESSION Session::operator()(session_action action) |
|
|
|
// ---------------------------------------------------------------------------------------
|
|
|
|
Session::Session() : |
|
|
|
_messageToSend{ nullptr }, _notifyHandshake{ nullptr }, _sync_mode{ SyncModes::Async }, |
|
|
|
_adapter_manages_sync_thread{ false } |
|
|
|
{ |
|
|
|
std::lock_guard<mutex> lock(mut); |
|
|
|
} |
|
|
|
|
|
|
|
::PEP_STATUS status = ::PEP_STATUS_OK; |
|
|
|
void Session::initialize(SyncModes sync_mode, bool adapter_manages_sync_thread) |
|
|
|
{ |
|
|
|
pEpLog("Initializing session with CallbackDispatcher..."); |
|
|
|
_init( |
|
|
|
pEp::CallbackDispatcher::messageToSend, |
|
|
|
pEp::CallbackDispatcher::notifyHandshake, |
|
|
|
sync_mode, |
|
|
|
adapter_manages_sync_thread); |
|
|
|
} |
|
|
|
|
|
|
|
switch (action) { |
|
|
|
case release: |
|
|
|
if (_session.get()) { |
|
|
|
_session = nullptr; |
|
|
|
} |
|
|
|
break; |
|
|
|
void Session::initialize( |
|
|
|
SyncModes sync_mode, |
|
|
|
bool adapter_manages_sync_thread, |
|
|
|
::messageToSend_t messageToSend, |
|
|
|
::notifyHandshake_t notifyHandshake) |
|
|
|
{ |
|
|
|
pEpLog("Initializing session..."); |
|
|
|
_init(messageToSend, notifyHandshake, sync_mode, adapter_manages_sync_thread); |
|
|
|
} |
|
|
|
|
|
|
|
case init: |
|
|
|
if (!_session.get()) { |
|
|
|
::PEP_SESSION session_; |
|
|
|
status = ::init(&session_, _messageToSend, _inject_action, _ensure_passphrase); |
|
|
|
throw_status(status); |
|
|
|
_session = SessionPtr{session_, ::release}; |
|
|
|
} |
|
|
|
break; |
|
|
|
default: |
|
|
|
status = ::PEP_ILLEGAL_VALUE; |
|
|
|
void Session::_init( |
|
|
|
::messageToSend_t messageToSend, |
|
|
|
::notifyHandshake_t notifyHandshake, |
|
|
|
SyncModes sync_mode, |
|
|
|
bool adapter_manages_sync_thread) |
|
|
|
{ |
|
|
|
// cache the values for sync-thread session creation
|
|
|
|
_messageToSend = messageToSend; |
|
|
|
_notifyHandshake = notifyHandshake; |
|
|
|
_sync_mode = sync_mode; |
|
|
|
_adapter_manages_sync_thread = adapter_manages_sync_thread; |
|
|
|
refresh(); |
|
|
|
::adapter_group_init(); |
|
|
|
} |
|
|
|
|
|
|
|
void Session::refresh() |
|
|
|
{ |
|
|
|
std::lock_guard<mutex> lock(mut); |
|
|
|
release(); |
|
|
|
|
|
|
|
// Switch to mode "Sync" ensures the sync thread to be shutdown
|
|
|
|
if (_sync_mode == SyncModes::Sync) { |
|
|
|
// process the event directly
|
|
|
|
_inject_action = _process_sync_event; |
|
|
|
if (!_adapter_manages_sync_thread) { |
|
|
|
stop_sync(); |
|
|
|
} else { |
|
|
|
// The adapter needs to shutdown sync thread
|
|
|
|
} |
|
|
|
} |
|
|
|
// Switch to mode "ASync", sync thread needs to be started using start_sync
|
|
|
|
if (_sync_mode == SyncModes::Async) { |
|
|
|
// put the event on queue
|
|
|
|
_inject_action = _inject_sync_event; |
|
|
|
} |
|
|
|
|
|
|
|
// create
|
|
|
|
::PEP_SESSION session_; |
|
|
|
::PEP_STATUS status; |
|
|
|
status = ::init(&session_, _messageToSend, _inject_action, _ensure_passphrase); |
|
|
|
throw_status(status); |
|
|
|
return _session.get(); |
|
|
|
status = ::register_sync_callbacks( |
|
|
|
session_, |
|
|
|
nullptr, |
|
|
|
_notifyHandshake, |
|
|
|
_retrieve_next_sync_event); |
|
|
|
if (status != PEP_STATUS_OK) { |
|
|
|
pEpLog("libpEpAdapter: WARNING - session is initialized but without sync/callbacks. " |
|
|
|
"This is normal if there are no own identities yet. Call session.init() again to " |
|
|
|
"re-initialize the session after creating an own identity."); |
|
|
|
} |
|
|
|
// store
|
|
|
|
_session = SessionPtr{ session_, ::release }; |
|
|
|
} |
|
|
|
|
|
|
|
void Session::release() |
|
|
|
{ |
|
|
|
if (_session.get()) { |
|
|
|
_session = nullptr; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// public
|
|
|
|
::PEP_SESSION Session::operator()() |
|
|
|
{ |
|
|
|
if (!_session.get()) { |
|
|
|
throw std::runtime_error( |
|
|
|
"libpEpAdapter: No session! Before use, call session.initialize() for each thread"); |
|
|
|
} else { |
|
|
|
return _session.get(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// public
|
|
|
@ -230,7 +236,7 @@ namespace pEp { |
|
|
|
// public
|
|
|
|
bool is_sync_running() |
|
|
|
{ |
|
|
|
if(!_adapter_manages_sync_thread) { |
|
|
|
if (!session._adapter_manages_sync_thread) { |
|
|
|
return _sync_thread.joinable(); |
|
|
|
} else { |
|
|
|
return false; |
|
|
|