
2 changed files with 165 additions and 0 deletions
@ -0,0 +1,119 @@ |
|||
// This file is under GNU General Public License 3.0
|
|||
// see LICENSE.txt
|
|||
|
|||
#include "Adapter.hh" |
|||
#include <sstream> |
|||
#include <iomanip> |
|||
#include <assert.h> |
|||
|
|||
namespace pEp { |
|||
using namespace std; |
|||
|
|||
void throw_status(PEP_STATUS status) |
|||
{ |
|||
if (status == PEP_STATUS_OK) |
|||
return; |
|||
if (status >= 0x400 && status <= 0x4ff) |
|||
return; |
|||
if (status == PEP_OUT_OF_MEMORY) |
|||
throw bad_alloc(); |
|||
if (status == PEP_ILLEGAL_VALUE) |
|||
throw invalid_argument("illegal value"); |
|||
|
|||
stringstream build; |
|||
build << setfill('0') << "p≡p 0x" << setw(4) << hex << status; |
|||
throw runtime_error(build.str()); |
|||
} |
|||
|
|||
messageToSend_t Adapter::_messageToSend = nullptr; |
|||
notifyHandshake_t Adapter::_notifyHandshake = nullptr; |
|||
|
|||
Adapter::Adapter(messageToSend_t messageToSend, |
|||
notifyHandshake_t notifyHandshake, bool is_sync_thread) |
|||
{ |
|||
if (messageToSend) |
|||
_messageToSend = messageToSend; |
|||
|
|||
if (notifyHandshake) |
|||
_notifyHandshake = notifyHandshake; |
|||
|
|||
PEP_SESSION _session = session(); |
|||
|
|||
if (is_sync_thread) { |
|||
PEP_STATUS status = register_sync_callbacks(_session, nullptr, |
|||
notifyHandshake, _retrieve_next_sync_event); |
|||
throw_status(status); |
|||
} |
|||
} |
|||
|
|||
PEP_SESSION Adapter::session(session_action action) |
|||
{ |
|||
lock_guard<mutex> lock(mtx()); |
|||
|
|||
thread_local static PEP_SESSION _session = nullptr; |
|||
PEP_STATUS status = PEP_STATUS_OK; |
|||
|
|||
switch (action) { |
|||
case release: |
|||
if (_session) { |
|||
::release(_session); |
|||
_session = nullptr; |
|||
} |
|||
break; |
|||
|
|||
case init: |
|||
if (!_session) |
|||
status = ::init(&_session, _messageToSend, _inject_sync_event); |
|||
break; |
|||
|
|||
default: |
|||
status = PEP_ILLEGAL_VALUE; |
|||
} |
|||
|
|||
if (status) |
|||
throw_status(status); |
|||
|
|||
return _session; |
|||
} |
|||
|
|||
int Adapter::_inject_sync_event(SYNC_EVENT ev, void *management) |
|||
{ |
|||
if (is_sync_thread(session())) { |
|||
PEP_STATUS status = do_sync_protocol_step(session(), nullptr, ev); |
|||
return status == PEP_STATUS_OK ? 0 : 1; |
|||
} |
|||
|
|||
try { |
|||
queue().push_front(ev); |
|||
} |
|||
catch (exception&) { |
|||
return 1; |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
SYNC_EVENT Adapter::_retrieve_next_sync_event(void *management, time_t threshold) |
|||
{ |
|||
time_t started = time(nullptr); |
|||
bool timeout = false; |
|||
|
|||
while (queue().empty()) { |
|||
int i = 0; |
|||
++i; |
|||
if (i > 10) { |
|||
if (time(nullptr) > started + threshold) { |
|||
timeout = true; |
|||
break; |
|||
} |
|||
i = 0; |
|||
} |
|||
nanosleep((const struct timespec[]){{0, 100000000L}}, NULL); |
|||
} |
|||
|
|||
if (timeout) |
|||
return new_sync_timeout_event(); |
|||
|
|||
return queue().pop_front(); |
|||
} |
|||
} |
|||
|
@ -0,0 +1,46 @@ |
|||
// This file is under GNU General Public License 3.0
|
|||
// see LICENSE.txt
|
|||
|
|||
#pragma once |
|||
|
|||
#include "locked_queue.hh" |
|||
#include <pEp/sync_api.h> |
|||
|
|||
namespace pEp { |
|||
void throw_status(PEP_STATUS status); |
|||
|
|||
class Adapter { |
|||
static messageToSend_t _messageToSend; |
|||
static notifyHandshake_t _notifyHandshake; |
|||
|
|||
public: |
|||
Adapter(messageToSend_t messageToSend, |
|||
notifyHandshake_t notifyHandshake, |
|||
bool is_sync_thread = false); |
|||
virtual ~Adapter() { } |
|||
|
|||
enum session_action { |
|||
init, |
|||
release |
|||
}; |
|||
|
|||
static PEP_SESSION session(session_action action = init); |
|||
static ::utility::locked_queue< SYNC_EVENT >& queue() |
|||
{ |
|||
static ::utility::locked_queue< SYNC_EVENT > q; |
|||
return q; |
|||
} |
|||
|
|||
protected: |
|||
static int _inject_sync_event(SYNC_EVENT ev, void *management); |
|||
static SYNC_EVENT _retrieve_next_sync_event(void *management, time_t threshold); |
|||
|
|||
private: |
|||
static std::mutex& mtx() |
|||
{ |
|||
static std::mutex m; |
|||
return m; |
|||
} |
|||
}; |
|||
} |
|||
|
Loading…
Reference in new issue