1// 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#ifndef MOJO_EDK_SYSTEM_HANDLE_TABLE_H_
6#define MOJO_EDK_SYSTEM_HANDLE_TABLE_H_
7
8#include <stdint.h>
9
10#include <vector>
11
12#include "base/containers/hash_tables.h"
13#include "base/macros.h"
14#include "mojo/edk/system/dispatcher.h"
15#include "mojo/public/c/system/types.h"
16
17namespace mojo {
18namespace edk {
19
20class HandleTable {
21 public:
22  HandleTable();
23  ~HandleTable();
24
25  MojoHandle AddDispatcher(scoped_refptr<Dispatcher> dispatcher);
26
27  // Inserts multiple dispatchers received from message transit, populating
28  // |handles| with their newly allocated handles. Returns |true| on success.
29  bool AddDispatchersFromTransit(
30      const std::vector<Dispatcher::DispatcherInTransit>& dispatchers,
31      MojoHandle* handles);
32
33  scoped_refptr<Dispatcher> GetDispatcher(MojoHandle handle) const;
34  MojoResult GetAndRemoveDispatcher(MojoHandle,
35                                    scoped_refptr<Dispatcher>* dispatcher);
36
37  // Marks handles as busy and populates |dispatchers|. Returns MOJO_RESULT_BUSY
38  // if any of the handles are already in transit; MOJO_RESULT_INVALID_ARGUMENT
39  // if any of the handles are invalid; or MOJO_RESULT_OK if successful.
40  MojoResult BeginTransit(
41      const MojoHandle* handles,
42      uint32_t num_handles,
43      std::vector<Dispatcher::DispatcherInTransit>* dispatchers);
44
45  void CompleteTransitAndClose(
46      const std::vector<Dispatcher::DispatcherInTransit>& dispatchers);
47  void CancelTransit(
48      const std::vector<Dispatcher::DispatcherInTransit>& dispatchers);
49
50  void GetActiveHandlesForTest(std::vector<MojoHandle> *handles);
51
52 private:
53  struct Entry {
54   Entry();
55   explicit Entry(scoped_refptr<Dispatcher> dispatcher);
56   Entry(const Entry& other);
57   ~Entry();
58
59   scoped_refptr<Dispatcher> dispatcher;
60   bool busy = false;
61  };
62
63  using HandleMap = base::hash_map<MojoHandle, Entry>;
64
65  HandleMap handles_;
66
67  uint32_t next_available_handle_ = 1;
68
69  DISALLOW_COPY_AND_ASSIGN(HandleTable);
70};
71
72}  // namespace edk
73}  // namespace mojo
74
75#endif  // MOJO_EDK_SYSTEM_HANDLE_TABLE_H_
76