cancelation_signal.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. // Copyright 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef COMPONENTS_SYNC_ENGINE_CANCELATION_SIGNAL_H_
  5. #define COMPONENTS_SYNC_ENGINE_CANCELATION_SIGNAL_H_
  6. #include "base/memory/raw_ptr.h"
  7. #include "base/synchronization/lock.h"
  8. namespace syncer {
  9. // This class is used to allow one thread to request that another abort and
  10. // return early.
  11. //
  12. // The signalling thread owns this class and my call Signal() at any time.
  13. // After that call, this class' IsSignalled() will always return true. The
  14. // intended use case is that the task intending to support early exit will
  15. // periodically check the value of IsSignalled() to see if it should return
  16. // early.
  17. //
  18. // The receiving task may also choose to register an observer whose
  19. // OnCancelationSignalReceived() method will be executed on the signaller's
  20. // thread when Signal() is called. This may be used for sending an early
  21. // Signal() to a WaitableEvent. The registration of the handler is necessarily
  22. // racy. If Signal() is executes before TryRegisterHandler(),
  23. // TryRegisterHandler() will not perform any registration and return false. That
  24. // function's caller must handle this case.
  25. //
  26. // This class supports only one handler, though it could easily support multiple
  27. // observers if we found a use case for such a feature.
  28. class CancelationSignal {
  29. public:
  30. class Observer {
  31. public:
  32. Observer() = default;
  33. virtual ~Observer() = default;
  34. // This may be called from a foreign thread while the CancelationSignal's
  35. // lock is held. The callee should avoid performing slow or blocking
  36. // operations.
  37. virtual void OnCancelationSignalReceived() = 0;
  38. };
  39. CancelationSignal();
  40. ~CancelationSignal();
  41. // Tries to register a handler to be invoked when Signal() is called.
  42. //
  43. // If Signal() has already been called, returns false without registering
  44. // the handler. Returns true when the registration is successful.
  45. //
  46. // If the registration was successful, the handler must be unregistered with
  47. // UnregisterHandler before this CancelationSignal is destroyed.
  48. bool TryRegisterHandler(Observer* handler);
  49. // Unregisters the abort handler.
  50. void UnregisterHandler(Observer* handler);
  51. // Returns true if Signal() has been called.
  52. bool IsSignalled();
  53. // Sets the stop_requested_ flag and calls the OnCancelationSignalReceived()
  54. // method of the registered handler, if there is one registered at the time.
  55. // SignalReceived() will be called with the |signal_lock_| held.
  56. void Signal();
  57. private:
  58. // Protects all members of this class.
  59. base::Lock signal_lock_;
  60. // True if Signal() has been invoked.
  61. bool signalled_ = false;
  62. // The registered abort handler. May be null.
  63. raw_ptr<Observer> handler_ = nullptr;
  64. };
  65. } // namespace syncer
  66. #endif // COMPONENTS_SYNC_ENGINE_CANCELATION_SIGNAL_H_