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 <unordered_map>
9 
10 #include "base/callback.h"
11 #include "base/macros.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/threading/thread_checker.h"
14 #include "mojo/public/cpp/bindings/bindings_export.h"
15 #include "mojo/public/cpp/system/core.h"
16 
17 namespace mojo {
18 
19 // SyncHandleRegistry is a thread-local storage to register handles that want to
20 // be watched together.
21 //
22 // This class is not thread safe.
23 class MOJO_CPP_BINDINGS_EXPORT SyncHandleRegistry
24     : public base::RefCounted<SyncHandleRegistry> {
25  public:
26   // Returns a thread-local object.
27   static scoped_refptr<SyncHandleRegistry> current();
28 
29   using HandleCallback = base::Callback<void(MojoResult)>;
30   bool RegisterHandle(const Handle& handle,
31                       MojoHandleSignals handle_signals,
32                       const HandleCallback& callback);
33 
34   void UnregisterHandle(const Handle& handle);
35 
36   // Waits on all the registered handles and runs callbacks synchronously for
37   // those ready handles.
38   // The method:
39   //   - returns true when any element of |should_stop| is set to true;
40   //   - returns false when any error occurs.
41   bool WatchAllHandles(const bool* should_stop[], size_t count);
42 
43  private:
44   friend class base::RefCounted<SyncHandleRegistry>;
45 
46   struct HandleHasher {
operatorHandleHasher47     size_t operator()(const Handle& handle) const {
48       return std::hash<uint32_t>()(static_cast<uint32_t>(handle.value()));
49     }
50   };
51   using HandleMap = std::unordered_map<Handle, HandleCallback, HandleHasher>;
52 
53   SyncHandleRegistry();
54   ~SyncHandleRegistry();
55 
56   HandleMap handles_;
57 
58   ScopedHandle wait_set_handle_;
59 
60   base::ThreadChecker thread_checker_;
61 
62   DISALLOW_COPY_AND_ASSIGN(SyncHandleRegistry);
63 };
64 
65 }  // namespace mojo
66 
67 #endif  // MOJO_PUBLIC_CPP_BINDINGS_SYNC_HANDLE_REGISTRY_H_
68