blob: cd535aa69d57afef7f962e87949de4969a4145ed [file] [log] [blame]
rockot6d7be622016-06-15 18:25:191// 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
rockotb62e2e32017-03-24 18:36:448#include <map>
rockot6d7be622016-06-15 18:25:199
10#include "base/callback.h"
Ken Rockot267df5a2017-08-30 23:31:4511#include "base/containers/stack_container.h"
rockot6d7be622016-06-15 18:25:1912#include "base/macros.h"
13#include "base/memory/ref_counted.h"
Sam McNallyde5ae672017-06-19 23:34:4514#include "base/sequence_checker.h"
rockotb62e2e32017-03-24 18:36:4415#include "base/synchronization/waitable_event.h"
dcheng9c3e6582016-09-23 03:10:5016#include "mojo/public/cpp/bindings/bindings_export.h"
rockot6d7be622016-06-15 18:25:1917#include "mojo/public/cpp/system/core.h"
rockota9d566a2017-03-17 19:36:1518#include "mojo/public/cpp/system/wait_set.h"
rockot6d7be622016-06-15 18:25:1919
20namespace mojo {
21
Sam McNallyde5ae672017-06-19 23:34:4522// SyncHandleRegistry is a sequence-local storage to register handles that want
23// to be watched together.
rockot6d7be622016-06-15 18:25:1924//
Sam McNallyde5ae672017-06-19 23:34:4525// This class is thread unsafe.
dcheng9c3e6582016-09-23 03:10:5026class MOJO_CPP_BINDINGS_EXPORT SyncHandleRegistry
27 : public base::RefCounted<SyncHandleRegistry> {
rockot6d7be622016-06-15 18:25:1928 public:
Sam McNallyde5ae672017-06-19 23:34:4529 // Returns a sequence-local object.
rockot6d7be622016-06-15 18:25:1930 static scoped_refptr<SyncHandleRegistry> current();
31
32 using HandleCallback = base::Callback<void(MojoResult)>;
Ken Rockot267df5a2017-08-30 23:31:4533
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.
rockot6d7be622016-06-15 18:25:1937 bool RegisterHandle(const Handle& handle,
38 MojoHandleSignals handle_signals,
39 const HandleCallback& callback);
40
41 void UnregisterHandle(const Handle& handle);
42
rockotb62e2e32017-03-24 18:36:4443 // 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
Ken Rockot267df5a2017-08-30 23:31:4545 // 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);
rockotb62e2e32017-03-24 18:36:4448
Ken Rockot267df5a2017-08-30 23:31:4549 // Unregisters a specific |event|+|callback| pair.
50 void UnregisterEvent(base::WaitableEvent* event,
51 const base::Closure& callback);
rockotb62e2e32017-03-24 18:36:4452
53 // Waits on all the registered handles and events and runs callbacks
54 // synchronously for any that become ready.
rockot6d7be622016-06-15 18:25:1955 // The method:
56 // - returns true when any element of |should_stop| is set to true;
57 // - returns false when any error occurs.
rockotb62e2e32017-03-24 18:36:4458 bool Wait(const bool* should_stop[], size_t count);
rockot6d7be622016-06-15 18:25:1959
60 private:
61 friend class base::RefCounted<SyncHandleRegistry>;
62
Ken Rockot267df5a2017-08-30 23:31:4563 using EventCallbackList = base::StackVector<base::Closure, 1>;
64 using EventMap = std::map<base::WaitableEvent*, EventCallbackList>;
65
rockot6d7be622016-06-15 18:25:1966 SyncHandleRegistry();
67 ~SyncHandleRegistry();
68
Ken Rockot267df5a2017-08-30 23:31:4569 void RemoveInvalidEventCallbacks();
70
rockota9d566a2017-03-17 19:36:1571 WaitSet wait_set_;
rockotb62e2e32017-03-24 18:36:4472 std::map<Handle, HandleCallback> handles_;
Ken Rockot267df5a2017-08-30 23:31:4573 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;
rockot6d7be622016-06-15 18:25:1983
Sam McNallyde5ae672017-06-19 23:34:4584 SEQUENCE_CHECKER(sequence_checker_);
rockot6d7be622016-06-15 18:25:1985
86 DISALLOW_COPY_AND_ASSIGN(SyncHandleRegistry);
87};
88
89} // namespace mojo
90
91#endif // MOJO_PUBLIC_CPP_BINDINGS_SYNC_HANDLE_REGISTRY_H_