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