Codemod asserts to assertxs in the runtime
[hiphop-php.git] / hphp / runtime / base / root-map.h
blobcc5bde5143cc58126e738372dbf7f6a3d56ade1c
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_ROOT_MAP_H_
18 #define incl_HPHP_ROOT_MAP_H_
20 #include "hphp/runtime/base/req-containers.h"
21 #include "hphp/runtime/base/req-ptr.h"
23 namespace HPHP {
26 * RootMap wraps a simple id->object hashtable, useful for extensions
27 * that need pass 'handles' to objects or resources into 3rd party apis
28 * masked as integers or void* pointers. The map is intended to be a
29 * field of a thread local, where it will be automatically scanned by
30 * the gc, and must be reset() between requests.
32 template<class T> struct RootMap {
33 using RootId = uintptr_t;
34 using Map = req::hash_map<RootId,req::ptr<T>>;
36 RootId addRoot(req::ptr<T>&& ptr) {
37 assertx(ptr);
38 const RootId tok = ptr->getId();
39 getMap().emplace(tok, std::move(ptr));
40 return tok;
43 RootId addRoot(const req::ptr<T>& ptr) {
44 assertx(ptr);
45 auto tok = ptr->getId();
46 getMap()[tok] = ptr;
47 return tok;
48 static_assert(sizeof(tok) <= sizeof(RootId), "");
51 req::ptr<T> lookupRoot(const void* vp) const {
52 return lookupRoot(reinterpret_cast<RootId>(vp));
55 req::ptr<T> lookupRoot(RootId tok) const {
56 if (!m_map) return nullptr;
57 auto& map = *m_map;
58 auto it = map.find(tok);
59 return it != map.end() ? unsafe_cast_or_null<T>(it->second) : nullptr;
62 req::ptr<T> removeRoot(RootId tok) {
63 if (m_map) {
64 auto it = m_map->find(tok);
65 if (it != m_map->end()) {
66 auto ptr = std::move(it->second);
67 m_map->erase(it);
68 return unsafe_cast_or_null<T>(ptr);
71 return nullptr;
74 req::ptr<T> removeRoot(const void* vp) {
75 return removeRoot(reinterpret_cast<RootId>(vp));
78 bool removeRoot(const req::ptr<T>& ptr) {
79 return removeRoot(ptr->getId()) != nullptr;
82 bool removeRoot(const T* ptr) {
83 return removeRoot(ptr->getId()) != nullptr;
86 void reset() {
87 m_map = nullptr;
90 private:
91 Map& getMap() {
92 if (UNLIKELY(!m_map)) {
93 m_map = req::make_raw<Map>();
95 return *m_map;
97 Map* m_map{nullptr};
101 #endif