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