Add sub-controls for Hack array compat runtime checks
[hiphop-php.git] / hphp / runtime / base / stat-cache.h
blob9e183de85ac212d41d10f610802596d8fa154833
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_STAT_CACHE_H_
18 #define incl_HPHP_STAT_CACHE_H_
20 #ifdef __linux__
21 #include <sys/inotify.h>
22 #endif
24 #include <sys/types.h>
25 #include <sys/stat.h>
27 #include <tbb/concurrent_hash_map.h>
29 #include "hphp/util/hash-map-typedefs.h"
30 #include "hphp/util/lock.h"
31 #include "hphp/runtime/base/atomic-shared-ptr.h"
32 #include "hphp/runtime/base/atomic-countable.h"
34 #include <folly/portability/Unistd.h>
36 namespace HPHP {
37 ///////////////////////////////////////////////////////////////////////////////
39 struct StatCache {
40 struct Node;
41 typedef AtomicSharedPtr<Node> NodePtr;
42 typedef tbb::concurrent_hash_map<std::string, NodePtr,
43 stringHashCompare> NameNodeMap;
44 typedef hphp_hash_map<int, NodePtr, int64_hash> WatchNodeMap;
46 struct Node : AtomicCountable {
47 typedef hphp_hash_map<std::string, NodePtr, string_hash> NameNodeMap;
48 typedef hphp_hash_map<std::string, void*, string_hash> NameMap;
50 explicit Node(StatCache& statCache, int wd=-1);
51 void atomicRelease();
53 void touch(bool invalidate=true);
54 void expirePaths(bool invalidate=true);
55 int stat(const std::string& path, struct stat* buf, time_t lastRefresh=0);
56 int lstat(const std::string& path, struct stat* buf, time_t lastRefresh=0);
57 bool isLink();
58 std::string readlink(const std::string& path, time_t lastRefresh=0);
59 void insertChild(const std::string& childName, NodePtr child, bool follow);
60 void removeChild(const std::string& childName);
61 NodePtr getChild(const std::string& childName, bool follow);
62 void setPath(const std::string& path) {
63 m_path = path;
65 const std::string& path() const { return m_path; }
67 private:
68 template <bool removePaths>
69 void touchLocked(bool invalidate=true);
70 void detachLocked();
71 void sanityCheck(const std::string& path, bool isStat,
72 const struct stat* buf, time_t lastRefresh);
73 bool isLinkLocked();
74 bool validate(const std::string& path, bool& cached);
76 StatCache& m_statCache;
77 SimpleMutex m_lock;
78 int m_wd; // Watch descriptor; -1 if a file.
80 bool m_valid; // True if m_stat/m_lstat are currently valid.
81 struct stat m_stat; // Cached stat() result.
82 struct stat m_lstat; // Cached lstat() result.
83 std::string m_link; // Cached readlink() result.
85 bool m_inExpirePaths;
86 NameNodeMap m_children; // stat() children.
87 NameNodeMap m_lChildren; // lstat() children.
89 NameMap m_paths; // Associated entries in StatCache::m_path2Node.
90 NameMap m_lpaths; // Associated entries in StatCache::m_lpath2Node.
92 std::string m_path;
95 StatCache();
96 ~StatCache();
98 static void requestInit(); // Process pending file change notifications.
99 static int stat(const std::string& path, struct stat* buf);
100 static int lstat(const std::string& path, struct stat* buf);
101 static std::string readlink(const std::string& path);
102 static std::string realpath(const char* path);
104 private:
105 bool init();
106 void clear();
107 void reset();
108 NodePtr getNode(const std::string& path, bool follow);
109 bool mergePath(const std::string& path, bool follow);
110 #ifdef __linux__
111 bool handleEvent(const struct inotify_event* event);
112 #endif
113 void removeWatch(int wd);
114 void removePath(const std::string& path, Node* node);
115 void removeLPath(const std::string& path, Node* node);
116 void refresh();
117 time_t lastRefresh();
118 int statImpl(const std::string& path, struct stat* buf);
119 int lstatImpl(const std::string& path, struct stat* buf);
120 std::string readlinkImpl(const std::string& path);
121 std::string realpathImpl(const char* path);
123 static StatCache s_sc;
125 NameNodeMap m_path2Node; // stat() path cache.
126 NameNodeMap m_lpath2Node; // lstat() path cache.
128 SimpleMutex m_lock; // Protects the following fields.
129 int m_ifd;
130 #ifdef __linux__
131 static const size_t kReadBufSize = 10 * (sizeof(struct inotify_event)
132 + NAME_MAX + 1);
133 char m_readBuf[kReadBufSize];
134 #endif
135 time_t m_lastRefresh; // Used for debugging.
136 WatchNodeMap m_watch2Node;
137 NodePtr m_root;
140 ///////////////////////////////////////////////////////////////////////////////
142 #endif // incl_HPHP_STAT_CACHE_H_