Home | History | Annotate | Download | only in bindings
      1 // Copyright 2016 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 
      5 #ifndef MOJO_PUBLIC_CPP_BINDINGS_SYNC_HANDLE_REGISTRY_H_
      6 #define MOJO_PUBLIC_CPP_BINDINGS_SYNC_HANDLE_REGISTRY_H_
      7 
      8 #include <map>
      9 
     10 #include "base/callback.h"
     11 #include "base/containers/stack_container.h"
     12 #include "base/macros.h"
     13 #include "base/memory/ref_counted.h"
     14 #include "base/sequence_checker.h"
     15 #include "base/synchronization/waitable_event.h"
     16 #include "mojo/public/cpp/bindings/bindings_export.h"
     17 #include "mojo/public/cpp/system/core.h"
     18 #include "mojo/public/cpp/system/wait_set.h"
     19 
     20 namespace mojo {
     21 
     22 // SyncHandleRegistry is a sequence-local storage to register handles that want
     23 // to be watched together.
     24 //
     25 // This class is thread unsafe.
     26 class MOJO_CPP_BINDINGS_EXPORT SyncHandleRegistry
     27     : public base::RefCounted<SyncHandleRegistry> {
     28  public:
     29   // Returns a sequence-local object.
     30   static scoped_refptr<SyncHandleRegistry> current();
     31 
     32   using HandleCallback = base::Callback<void(MojoResult)>;
     33 
     34   // Registers a |Handle| to be watched for |handle_signals|. If any such
     35   // signals are satisfied during a Wait(), the Wait() is woken up and
     36   // |callback| is run.
     37   bool RegisterHandle(const Handle& handle,
     38                       MojoHandleSignals handle_signals,
     39                       const HandleCallback& callback);
     40 
     41   void UnregisterHandle(const Handle& handle);
     42 
     43   // Registers a |base::WaitableEvent| which can be used to wake up
     44   // Wait() before any handle signals. |event| is not owned, and if it signals
     45   // during Wait(), |callback| is invoked.  Note that |event| may be registered
     46   // multiple times with different callbacks.
     47   void RegisterEvent(base::WaitableEvent* event, const base::Closure& callback);
     48 
     49   // Unregisters a specific |event|+|callback| pair.
     50   void UnregisterEvent(base::WaitableEvent* event,
     51                        const base::Closure& callback);
     52 
     53   // Waits on all the registered handles and events and runs callbacks
     54   // synchronously for any that become ready.
     55   // The method:
     56   //   - returns true when any element of |should_stop| is set to true;
     57   //   - returns false when any error occurs.
     58   bool Wait(const bool* should_stop[], size_t count);
     59 
     60  private:
     61   friend class base::RefCounted<SyncHandleRegistry>;
     62 
     63   using EventCallbackList = base::StackVector<base::Closure, 1>;
     64   using EventMap = std::map<base::WaitableEvent*, EventCallbackList>;
     65 
     66   SyncHandleRegistry();
     67   ~SyncHandleRegistry();
     68 
     69   void RemoveInvalidEventCallbacks();
     70 
     71   WaitSet wait_set_;
     72   std::map<Handle, HandleCallback> handles_;
     73   EventMap events_;
     74 
     75   // |true| iff this registry is currently dispatching event callbacks in
     76   // Wait(). Used to allow for safe event registration/unregistration from event
     77   // callbacks.
     78   bool is_dispatching_event_callbacks_ = false;
     79 
     80   // Indicates if one or more event callbacks was unregistered during the most
     81   // recent event callback dispatch.
     82   bool remove_invalid_event_callbacks_after_dispatch_ = false;
     83 
     84   SEQUENCE_CHECKER(sequence_checker_);
     85 
     86   DISALLOW_COPY_AND_ASSIGN(SyncHandleRegistry);
     87 };
     88 
     89 }  // namespace mojo
     90 
     91 #endif  // MOJO_PUBLIC_CPP_BINDINGS_SYNC_HANDLE_REGISTRY_H_
     92