blob: b570793dbe0f4286dc204f76402fa29665c40b91 [file] [log] [blame]
jam76bcf0c2015-10-02 21:01:281// Copyright 2014 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#include "mojo/edk/system/handle_table.h"
6
Avi Drissman2e88ac372015-12-21 18:14:577#include <stdint.h>
8
jam76bcf0c2015-10-02 21:01:289#include <limits>
10
jam76bcf0c2015-10-02 21:01:2811namespace mojo {
12namespace edk {
13
rockotce69a042016-01-26 19:23:2114HandleTable::HandleTable() {}
15
16HandleTable::~HandleTable() {}
17
18MojoHandle HandleTable::AddDispatcher(scoped_refptr<Dispatcher> dispatcher) {
19 // Oops, we're out of handles.
20 if (next_available_handle_ == MOJO_HANDLE_INVALID)
21 return MOJO_HANDLE_INVALID;
22
23 MojoHandle handle = next_available_handle_++;
tzik1fb60dd2017-03-08 04:52:0624 auto result =
25 handles_.insert(std::make_pair(handle, Entry(std::move(dispatcher))));
rockotce69a042016-01-26 19:23:2126 DCHECK(result.second);
27
28 return handle;
jam76bcf0c2015-10-02 21:01:2829}
30
rockotce69a042016-01-26 19:23:2131bool HandleTable::AddDispatchersFromTransit(
32 const std::vector<Dispatcher::DispatcherInTransit>& dispatchers,
33 MojoHandle* handles) {
34 // Oops, we're out of handles.
35 if (next_available_handle_ == MOJO_HANDLE_INVALID)
36 return false;
37
38 DCHECK_LE(dispatchers.size(), std::numeric_limits<uint32_t>::max());
39 // If this insertion would cause handle overflow, we're out of handles.
40 if (next_available_handle_ + dispatchers.size() < next_available_handle_)
41 return false;
42
43 for (size_t i = 0; i < dispatchers.size(); ++i) {
44 MojoHandle handle = next_available_handle_++;
45 auto result = handles_.insert(
46 std::make_pair(handle, Entry(dispatchers[i].dispatcher)));
47 DCHECK(result.second);
48 handles[i] = handle;
49 }
50
51 return true;
jam76bcf0c2015-10-02 21:01:2852}
53
rockotce69a042016-01-26 19:23:2154scoped_refptr<Dispatcher> HandleTable::GetDispatcher(MojoHandle handle) const {
55 auto it = handles_.find(handle);
56 if (it == handles_.end())
jam76bcf0c2015-10-02 21:01:2857 return nullptr;
rockotce69a042016-01-26 19:23:2158 return it->second.dispatcher;
jam76bcf0c2015-10-02 21:01:2859}
60
61MojoResult HandleTable::GetAndRemoveDispatcher(
62 MojoHandle handle,
63 scoped_refptr<Dispatcher>* dispatcher) {
rockotce69a042016-01-26 19:23:2164 auto it = handles_.find(handle);
65 if (it == handles_.end())
jam76bcf0c2015-10-02 21:01:2866 return MOJO_RESULT_INVALID_ARGUMENT;
67 if (it->second.busy)
68 return MOJO_RESULT_BUSY;
jam76bcf0c2015-10-02 21:01:2869
tzik1fb60dd2017-03-08 04:52:0670 *dispatcher = std::move(it->second.dispatcher);
rockotce69a042016-01-26 19:23:2171 handles_.erase(it);
jam76bcf0c2015-10-02 21:01:2872 return MOJO_RESULT_OK;
73}
74
rockotce69a042016-01-26 19:23:2175MojoResult HandleTable::BeginTransit(
jam76bcf0c2015-10-02 21:01:2876 const MojoHandle* handles,
77 uint32_t num_handles,
rockotce69a042016-01-26 19:23:2178 std::vector<Dispatcher::DispatcherInTransit>* dispatchers) {
79 dispatchers->clear();
80 dispatchers->reserve(num_handles);
81 for (size_t i = 0; i < num_handles; ++i) {
82 auto it = handles_.find(handles[i]);
83 if (it == handles_.end())
84 return MOJO_RESULT_INVALID_ARGUMENT;
85 if (it->second.busy)
86 return MOJO_RESULT_BUSY;
jam76bcf0c2015-10-02 21:01:2887
rockotce69a042016-01-26 19:23:2188 Dispatcher::DispatcherInTransit d;
89 d.local_handle = handles[i];
90 d.dispatcher = it->second.dispatcher;
91 if (!d.dispatcher->BeginTransit())
92 return MOJO_RESULT_BUSY;
93 it->second.busy = true;
94 dispatchers->push_back(d);
jam76bcf0c2015-10-02 21:01:2895 }
jam76bcf0c2015-10-02 21:01:2896 return MOJO_RESULT_OK;
97}
98
rockotce69a042016-01-26 19:23:2199void HandleTable::CompleteTransitAndClose(
100 const std::vector<Dispatcher::DispatcherInTransit>& dispatchers) {
101 for (const auto& dispatcher : dispatchers) {
102 auto it = handles_.find(dispatcher.local_handle);
103 DCHECK(it != handles_.end() && it->second.busy);
104 handles_.erase(it);
105 dispatcher.dispatcher->CompleteTransitAndClose();
jam76bcf0c2015-10-02 21:01:28106 }
107}
108
rockotce69a042016-01-26 19:23:21109void HandleTable::CancelTransit(
110 const std::vector<Dispatcher::DispatcherInTransit>& dispatchers) {
111 for (const auto& dispatcher : dispatchers) {
112 auto it = handles_.find(dispatcher.local_handle);
113 DCHECK(it != handles_.end() && it->second.busy);
jam76bcf0c2015-10-02 21:01:28114 it->second.busy = false;
rockotce69a042016-01-26 19:23:21115 dispatcher.dispatcher->CancelTransit();
jam76bcf0c2015-10-02 21:01:28116 }
117}
118
rockotce69a042016-01-26 19:23:21119void HandleTable::GetActiveHandlesForTest(std::vector<MojoHandle>* handles) {
120 handles->clear();
121 for (const auto& entry : handles_)
122 handles->push_back(entry.first);
123}
124
125HandleTable::Entry::Entry() {}
126
127HandleTable::Entry::Entry(scoped_refptr<Dispatcher> dispatcher)
tzik1fb60dd2017-03-08 04:52:06128 : dispatcher(std::move(dispatcher)) {}
rockotce69a042016-01-26 19:23:21129
vmpstr11ea3852016-02-29 20:33:57130HandleTable::Entry::Entry(const Entry& other) = default;
131
rockotce69a042016-01-26 19:23:21132HandleTable::Entry::~Entry() {}
133
jam76bcf0c2015-10-02 21:01:28134} // namespace edk
135} // namespace mojo