|  | // Copyright 2014 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #ifndef MOJO_CORE_HANDLE_TABLE_H_ | 
|  | #define MOJO_CORE_HANDLE_TABLE_H_ | 
|  |  | 
|  | #include <stdint.h> | 
|  |  | 
|  | #include <vector> | 
|  |  | 
|  | #include "base/containers/hash_tables.h" | 
|  | #include "base/gtest_prod_util.h" | 
|  | #include "base/macros.h" | 
|  | #include "base/synchronization/lock.h" | 
|  | #include "base/trace_event/memory_dump_provider.h" | 
|  | #include "mojo/core/dispatcher.h" | 
|  | #include "mojo/core/system_impl_export.h" | 
|  | #include "mojo/public/c/system/types.h" | 
|  |  | 
|  | namespace mojo { | 
|  | namespace core { | 
|  |  | 
|  | class MOJO_SYSTEM_IMPL_EXPORT HandleTable | 
|  | : public base::trace_event::MemoryDumpProvider { | 
|  | public: | 
|  | HandleTable(); | 
|  | ~HandleTable() override; | 
|  |  | 
|  | // HandleTable is thread-hostile. All access should be gated by GetLock(). | 
|  | base::Lock& GetLock(); | 
|  |  | 
|  | MojoHandle AddDispatcher(scoped_refptr<Dispatcher> dispatcher); | 
|  |  | 
|  | // Inserts multiple dispatchers received from message transit, populating | 
|  | // |handles| with their newly allocated handles. Returns |true| on success. | 
|  | bool AddDispatchersFromTransit( | 
|  | const std::vector<Dispatcher::DispatcherInTransit>& dispatchers, | 
|  | MojoHandle* handles); | 
|  |  | 
|  | scoped_refptr<Dispatcher> GetDispatcher(MojoHandle handle) const; | 
|  | MojoResult GetAndRemoveDispatcher(MojoHandle, | 
|  | scoped_refptr<Dispatcher>* dispatcher); | 
|  |  | 
|  | // Marks handles as busy and populates |dispatchers|. Returns MOJO_RESULT_BUSY | 
|  | // if any of the handles are already in transit; MOJO_RESULT_INVALID_ARGUMENT | 
|  | // if any of the handles are invalid; or MOJO_RESULT_OK if successful. | 
|  | MojoResult BeginTransit( | 
|  | const MojoHandle* handles, | 
|  | size_t num_handles, | 
|  | std::vector<Dispatcher::DispatcherInTransit>* dispatchers); | 
|  |  | 
|  | void CompleteTransitAndClose( | 
|  | const std::vector<Dispatcher::DispatcherInTransit>& dispatchers); | 
|  | void CancelTransit( | 
|  | const std::vector<Dispatcher::DispatcherInTransit>& dispatchers); | 
|  |  | 
|  | void GetActiveHandlesForTest(std::vector<MojoHandle>* handles); | 
|  |  | 
|  | private: | 
|  | FRIEND_TEST_ALL_PREFIXES(HandleTableTest, OnMemoryDump); | 
|  |  | 
|  | // MemoryDumpProvider implementation. | 
|  | bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, | 
|  | base::trace_event::ProcessMemoryDump* pmd) override; | 
|  |  | 
|  | struct Entry { | 
|  | Entry(); | 
|  | explicit Entry(scoped_refptr<Dispatcher> dispatcher); | 
|  | Entry(const Entry& other); | 
|  | ~Entry(); | 
|  |  | 
|  | scoped_refptr<Dispatcher> dispatcher; | 
|  | bool busy = false; | 
|  | }; | 
|  |  | 
|  | using HandleMap = base::hash_map<MojoHandle, Entry>; | 
|  |  | 
|  | HandleMap handles_; | 
|  | base::Lock lock_; | 
|  |  | 
|  | uint32_t next_available_handle_ = 1; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(HandleTable); | 
|  | }; | 
|  |  | 
|  | }  // namespace core | 
|  | }  // namespace mojo | 
|  |  | 
|  | #endif  // MOJO_CORE_HANDLE_TABLE_H_ |