some implementation
parent
a0e3b50a33
commit
f5648a2972
@ -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