| Index: src/shared/EventWithSetter.h | 
| diff --git a/src/shared/EventWithSetter.h b/src/shared/EventWithSetter.h | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..b5c12af10049d0a7288a841b9c4151c778cfb1c5 | 
| --- /dev/null | 
| +++ b/src/shared/EventWithSetter.h | 
| @@ -0,0 +1,100 @@ | 
| +#pragma once | 
| +/* | 
| +* This file is part of Adblock Plus <https://adblockplus.org/>, | 
| +* Copyright (C) 2006-2016 Eyeo GmbH | 
| +* | 
| +* Adblock Plus is free software: you can redistribute it and/or modify | 
| +* it under the terms of the GNU General Public License version 3 as | 
| +* published by the Free Software Foundation. | 
| +* | 
| +* Adblock Plus is distributed in the hope that it will be useful, | 
| +* but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
| +* GNU General Public License for more details. | 
| +* | 
| +* You should have received a copy of the GNU General Public License | 
| +* along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 
| +*/ | 
| +#include "AutoHandle.h" | 
| +#include <cstdint> | 
| +#include <memory> | 
| + | 
| +/// Wrapper around unnamed manual event windows object. | 
| +class Event { | 
| +public: | 
| +  enum { | 
| +    InfiniteTimeout = 0xFFFFFFFF | 
| +  }; | 
| +  /// Creates manual event with nonsignaled initial state. | 
| +  Event(); | 
| +  ~Event(); | 
| +  void Set(); | 
| +  void Reset(); | 
| +  bool operator!() const { | 
| +    return m_handle == nullptr; | 
| +  } | 
| +  bool Wait(int32_t timeoutMsec = InfiniteTimeout); | 
| +private: | 
| +  Event(const Event&); | 
| +  void operator=(const Event&); | 
| +private: | 
| +  HANDLE m_handle; | 
| +}; | 
| + | 
| +/// This class is a temporary replacement of std::promise/std::future. | 
| +/// | 
| +/// Before scheduling a task to a worker thread, the caller creates | 
| +/// `EventWithSetter` and obtains `EventWithSetter::Setter`. The task at the | 
| +/// end should call `EventWithSetter::Setter::Set` to notify the caller about | 
| +/// finishing. | 
| +/// If the the task is not finished because it has been canceled or it has | 
| +/// thrown an exception then the `EventWithSetter::Wait` returns `false`. | 
| +/// Example: | 
| +/// EventWithSetter event; | 
| +/// { // this scope is important because without it if `doWork()` throws | 
| +///   // `setter` won't be destroyed and the caller will wait forever. | 
| +///   auto setter = event.CreateSetter(); | 
| +///   dispatchTask([setter]{ | 
| +///     doWork(); | 
| +///     setter->Set(); | 
| +///   }); | 
| +/// } | 
| +/// if (event.Wait()) onSuccess(); | 
| +/// else onFail(); | 
| +class EventWithSetter | 
| +{ | 
| +public: | 
| +  class Setter; | 
| +private: | 
| +  struct Data | 
| +  { | 
| +    Data() : isSetCalled(false), isSetterCreated(false) | 
| +    {} | 
| +    Event event; | 
| +    std::weak_ptr<Setter> eventSetter; | 
| +    bool isSetCalled; | 
| +    bool isSetterCreated; | 
| +  }; | 
| +  typedef std::shared_ptr<Data> DataPtr; | 
| +public: | 
| +  class Setter | 
| +  { | 
| +  public: | 
| +    Setter(const DataPtr& data); | 
| +    ~Setter(); | 
| +    void Set(); | 
| +  private: | 
| +    Setter(const Setter&); | 
| +    void operator=(const Setter&); | 
| +  private: | 
| +    DataPtr m_data; | 
| +  }; | 
| +  EventWithSetter(); | 
| +  std::shared_ptr<Setter> CreateSetter(); | 
| +  bool Wait(int32_t timeoutMsec = Event::InfiniteTimeout); | 
| +private: | 
| +  EventWithSetter(const EventWithSetter&); | 
| +  void operator=(const EventWithSetter&); | 
| +private: | 
| +  DataPtr m_data; | 
| +}; | 
|  |