CpEpEngine.cpp
branchsync
changeset 297 a48f0545e221
parent 296 43d9e57b6561
child 298 06734cf5b96a
     1.1 --- a/CpEpEngine.cpp	Tue Oct 16 01:24:16 2018 +0200
     1.2 +++ b/CpEpEngine.cpp	Sat Oct 20 22:59:40 2018 +0200
     1.3 @@ -17,10 +17,6 @@
     1.4  // keysync thread actually has finished before we're destructed.
     1.5  
     1.6  std::mutex CpEpEngine::init_mutex;
     1.7 -
     1.8 -std::list< IpEpEngineCallbacks * > CpEpEngine::all_callbacks;
     1.9 -std::mutex CpEpEngine::callbacks_mutex;
    1.10 -
    1.11  atomic< int > CpEpEngine::count = 0;
    1.12  
    1.13  STDMETHODIMP CpEpEngine::InterfaceSupportsErrorInfo(REFIID riid)
    1.14 @@ -738,63 +734,85 @@
    1.15      return _ident;
    1.16  }
    1.17  
    1.18 -PEP_STATUS CpEpEngine::messageToSend(message *msg)
    1.19 +PEP_STATUS CpEpEngine::_messageToSend(message *msg, bool in_sync)
    1.20  {
    1.21      assert(msg);
    1.22      if (!msg)
    1.23          return PEP_ILLEGAL_VALUE;
    1.24  
    1.25 -    lock_guard< mutex > lock(callbacks_mutex);
    1.26 +    for (auto p = sync_callbacks.begin(); p != sync_callbacks.end(); ++p) {
    1.27 +        IpEpEngineCallbacks *cb = p->pdata->unmarshaled;
    1.28  
    1.29 -    // use the first one
    1.30 -    IpEpEngineCallbacks *cb = all_callbacks.front();
    1.31 +        if (cb) {
    1.32 +            TextMessage _msg;
    1.33 +            memset(&_msg, 0, sizeof(TextMessage));
    1.34  
    1.35 -    TextMessage _msg;
    1.36 -    memset(&_msg, 0, sizeof(TextMessage));
    1.37 +            text_message_from_C(&_msg, msg);
    1.38 +            HRESULT r = cb->MessageToSend(&_msg);
    1.39 +            assert(r == S_OK);
    1.40 +            clear_text_message(&_msg);
    1.41 +            if (r == E_OUTOFMEMORY)
    1.42 +                return PEP_OUT_OF_MEMORY;
    1.43 +            if (r != S_OK)
    1.44 +                return PEP_UNKNOWN_ERROR;
    1.45 +        }
    1.46 +    }
    1.47  
    1.48 -    text_message_from_C(&_msg, msg);
    1.49 -    HRESULT r = cb->MessageToSend(&_msg);
    1.50 -    assert(r == S_OK);
    1.51 -    clear_text_message(&_msg);
    1.52 -    if (r == E_OUTOFMEMORY)
    1.53 -        return PEP_OUT_OF_MEMORY;
    1.54 -    if (r != S_OK)
    1.55 -        return PEP_UNKNOWN_ERROR;
    1.56 +    return PEP_STATUS_OK;
    1.57 +}
    1.58 +
    1.59 +PEP_STATUS CpEpEngine::messageToSend(message *msg)
    1.60 +{
    1.61 +    return _messageToSend(msg);
    1.62 +}
    1.63 +
    1.64 +PEP_STATUS CpEpEngine::messageToSend_sync(message *msg)
    1.65 +{
    1.66 +    return _messageToSend(msg, true);
    1.67 +}
    1.68 +
    1.69 +PEP_STATUS CpEpEngine::_notifyHandshake(::pEp_identity *self, ::pEp_identity *partner, sync_handshake_signal signal, bool in_sync)
    1.70 +{
    1.71 +    assert(self && partner);
    1.72 +    if (!(self && partner))
    1.73 +        return PEP_ILLEGAL_VALUE;
    1.74 +
    1.75 +    // fire all of them
    1.76 +    for (auto p = sync_callbacks.begin(); p != sync_callbacks.end(); ++p) {
    1.77 +        IpEpEngineCallbacks *cb = nullptr;
    1.78 +        if (in_sync)
    1.79 +            cb = p->cdata;
    1.80 +        else
    1.81 +            cb = p->pdata->unmarshaled;
    1.82 +
    1.83 +        if (cb) {
    1.84 +            pEpIdentity _self;
    1.85 +            copy_identity(&_self, self);
    1.86 +            pEpIdentity _partner;
    1.87 +            copy_identity(&_partner, partner);
    1.88 +
    1.89 +            SyncHandshakeSignal _signal = (SyncHandshakeSignal)signal;
    1.90 +            SyncHandshakeResult result;
    1.91 +            HRESULT r = cb->NotifyHandshake(&_self, &_partner, _signal, &result);
    1.92 +            assert(r == S_OK);
    1.93 +            clear_identity_s(_self);
    1.94 +            clear_identity_s(_partner);
    1.95 +            if (r == E_OUTOFMEMORY)
    1.96 +                return PEP_OUT_OF_MEMORY;
    1.97 +        }
    1.98 +    }
    1.99  
   1.100      return PEP_STATUS_OK;
   1.101  }
   1.102  
   1.103  PEP_STATUS CpEpEngine::notifyHandshake(::pEp_identity *self, ::pEp_identity *partner, sync_handshake_signal signal)
   1.104  {
   1.105 -    assert(self && partner);
   1.106 -    if (!(self && partner))
   1.107 -        return PEP_ILLEGAL_VALUE;
   1.108 +    return _notifyHandshake(self, partner, signal);
   1.109 +}
   1.110  
   1.111 -    lock_guard< mutex > lock(callbacks_mutex);
   1.112 -    
   1.113 -    if (all_callbacks.size() == 0)
   1.114 -        return PEP_SYNC_NO_NOTIFY_CALLBACK;
   1.115 -
   1.116 -    // fire all of them
   1.117 -    for (auto i = all_callbacks.begin(); i != all_callbacks.end(); ++i) {
   1.118 -        IpEpEngineCallbacks *cb = *i;
   1.119 -
   1.120 -        pEpIdentity _self;
   1.121 -        copy_identity(&_self, self);
   1.122 -        pEpIdentity _partner;
   1.123 -        copy_identity(&_partner, partner);
   1.124 -
   1.125 -        SyncHandshakeSignal _signal = (SyncHandshakeSignal) signal;
   1.126 -        SyncHandshakeResult result;
   1.127 -        HRESULT r = cb->NotifyHandshake(&_self, &_partner, _signal, &result);
   1.128 -        assert(r == S_OK);
   1.129 -        clear_identity_s(_self);
   1.130 -        clear_identity_s(_partner);
   1.131 -        if (r == E_OUTOFMEMORY)
   1.132 -            return PEP_OUT_OF_MEMORY;
   1.133 -    }
   1.134 -
   1.135 -    return PEP_STATUS_OK;
   1.136 +PEP_STATUS CpEpEngine::notifyHandshake_sync(::pEp_identity *self, ::pEp_identity *partner, sync_handshake_signal signal)
   1.137 +{
   1.138 +    return _notifyHandshake(self, partner, signal, true);
   1.139  }
   1.140  
   1.141  STDMETHODIMP CpEpEngine::BlacklistAdd(BSTR fpr)
   1.142 @@ -1340,10 +1358,12 @@
   1.143      this->client_callbacks = new_callbacks;
   1.144      new_callbacks->AddRef();
   1.145  
   1.146 -    {
   1.147 -        lock_guard< mutex > lock(callbacks_mutex);
   1.148 -        all_callbacks.push_back(this->client_callbacks);
   1.149 -    }
   1.150 +    // provide callbacks to sync
   1.151 +    LPSTREAM marshaled_callbacks;
   1.152 +    auto result = CoMarshalInterThreadInterfaceInStream(IID_IpEpEngineCallbacks, client_callbacks, &marshaled_callbacks);
   1.153 +    assert(SUCCEEDED(result));
   1.154 +    assert(marshaled_callbacks);
   1.155 +    sync_callbacks.insert(new MarshaledCallbacks({ this->client_callbacks, marshaled_callbacks }));
   1.156  
   1.157      return S_OK;
   1.158  }
   1.159 @@ -1355,13 +1375,11 @@
   1.160      if (!this->client_callbacks)
   1.161          return S_FALSE;
   1.162  
   1.163 -    {
   1.164 -        lock_guard< mutex > lock(callbacks_mutex);
   1.165 -        for (auto i = all_callbacks.begin(); i != all_callbacks.end(); ++i) {
   1.166 -            if (*i == this->client_callbacks) {
   1.167 -                all_callbacks.erase(i);
   1.168 -                break;
   1.169 -            }
   1.170 +    for (auto p = sync_callbacks.begin(); p != sync_callbacks.end(); ++p) {
   1.171 +        if (p->pdata->unmarshaled == this->client_callbacks) {
   1.172 +            delete p->pdata;
   1.173 +            sync_callbacks.erase(p);
   1.174 +            break;
   1.175          }
   1.176      }
   1.177