Adapter.hxx
author Volker Birk <vb@pep-project.org>
Thu, 14 Nov 2019 23:22:05 +0100
changeset 134 b6e70c7067b3
parent 133 c40d1808ee92
child 136 198e8bb1534a
permissions -rw-r--r--
merging
vb@41
     1
#pragma once
vb@41
     2
roker@78
     3
#include <thread>
roker@78
     4
#include "locked_queue.hh"
roker@113
     5
#include <cassert>
vb@41
     6
vb@41
     7
namespace pEp {
vb@41
     8
    namespace Adapter {
roker@78
     9
        using std::function;
vb@118
    10
vb@41
    11
        extern messageToSend_t _messageToSend;
vb@41
    12
        extern notifyHandshake_t _notifyHandshake;
vb@41
    13
        extern std::thread *_sync_thread;
vb@41
    14
vb@133
    15
        extern ::utility::locked_queue< SYNC_EVENT, ::free_Sync_event > q;
vb@41
    16
        extern std::mutex m;
vb@41
    17
vb@79
    18
        SYNC_EVENT _retrieve_next_sync_event(void *management, unsigned threshold);
vb@41
    19
vb@125
    20
        static std::exception_ptr _ex;
vb@125
    21
        static bool register_done = false;
vb@121
    22
vb@41
    23
        template< class T > void sync_thread(T *obj, function< void(T *) > _startup, function< void(T *) > _shutdown)
vb@41
    24
        {
vb@110
    25
            assert(_messageToSend);
vb@110
    26
            assert(_notifyHandshake);
vb@66
    27
            if (obj && _startup)
vb@66
    28
                _startup(obj);
vb@66
    29
vb@110
    30
            session();
vb@110
    31
vb@121
    32
            {
vb@121
    33
                PEP_STATUS status = register_sync_callbacks(session(), nullptr,
vb@121
    34
                    _notifyHandshake, _retrieve_next_sync_event);
vb@121
    35
                try {
vb@121
    36
                    throw_status(status);
vb@125
    37
                    register_done = true;
vb@121
    38
                }
vb@121
    39
                catch (...) {
vb@121
    40
                    _ex = std::current_exception();
vb@125
    41
                    register_done = true;
vb@121
    42
                    return;
vb@121
    43
                }
vb@121
    44
            }
vb@41
    45
vb@41
    46
            do_sync_protocol(session(), (void *)obj);
vb@41
    47
            unregister_sync_callbacks(session());
vb@41
    48
vb@41
    49
            session(release);
vb@41
    50
vb@41
    51
            if (obj && _shutdown)
vb@41
    52
                _shutdown(obj);
vb@41
    53
        }
vb@41
    54
vb@55
    55
        template< class T > void startup(
vb@55
    56
            messageToSend_t messageToSend,
vb@55
    57
            notifyHandshake_t notifyHandshake,
vb@55
    58
            T *obj,
vb@41
    59
            function< void(T *) > _startup,
vb@41
    60
            function< void(T *) > _shutdown
vb@41
    61
        )
vb@119
    62
            throw (RuntimeError)
vb@41
    63
        {
vb@41
    64
            if (messageToSend)
vb@41
    65
                _messageToSend = messageToSend;
vb@41
    66
vb@41
    67
            if (notifyHandshake)
vb@41
    68
                _notifyHandshake = notifyHandshake;
vb@41
    69
vb@41
    70
            session();
vb@41
    71
vb@125
    72
            if (!_sync_thread) {
vb@125
    73
                register_done = false;
vb@125
    74
                _sync_thread = new std::thread(sync_thread<T>, obj, _startup, _shutdown);
vb@125
    75
                while (!register_done)
vb@125
    76
                    std::this_thread::sleep_for(std::chrono::milliseconds(100));
vb@41
    77
vb@125
    78
                if (_ex) {
vb@125
    79
                    _sync_thread = nullptr;
vb@125
    80
                    std::rethrow_exception(_ex);
vb@118
    81
                }
vb@41
    82
            }
vb@41
    83
        }
vb@41
    84
    }
vb@41
    85
}