Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

133 lines (110 sloc) 5.024 kb
/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010- Facebook, Inc. (http://www.facebook.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#ifndef __STAT_CACHE_H__
#define __STAT_CACHE_H__
#include <sys/inotify.h>
#include <tbb/concurrent_hash_map.h>
#include "util/base.h"
#include "util/lock.h"
#include "runtime/base/util/smart_ptr.h"
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
class StatCache {
public:
struct Node;
typedef AtomicSmartPtr<Node> NodePtr;
typedef tbb::concurrent_hash_map<std::string, NodePtr,
stringHashCompare> NameNodeMap;
typedef hphp_hash_map<int, NodePtr, int64_hash> WatchNodeMap;
class Node : public AtomicCountable {
public:
typedef hphp_hash_map<std::string, NodePtr, string_hash> NameNodeMap;
typedef hphp_hash_map<std::string, void*, string_hash> NameMap;
Node(StatCache& statCache, int wd=-1);
void atomicRelease();
void touch(bool invalidate=true);
void expirePaths(bool invalidate=true);
int stat(const std::string& path, struct stat* buf, time_t lastRefresh=0);
int lstat(const std::string& path, struct stat* buf, time_t lastRefresh=0);
bool isLink();
std::string readlink(const std::string& path, time_t lastRefresh=0);
void insertChild(const std::string& childName, NodePtr child, bool follow);
void removeChild(const std::string& childName);
NodePtr getChild(const std::string& childName, bool follow);
void setPath(const std::string& path) {
m_path = path;
}
const std::string& path() const { return m_path; }
private:
template <bool removePaths>
void touchLocked(bool invalidate=true);
void detachLocked();
void sanityCheck(const std::string& path, bool isStat,
const struct stat* buf, time_t lastRefresh);
bool isLinkLocked();
bool validate(const std::string& path, bool& cached);
StatCache& m_statCache;
SimpleMutex m_lock;
int m_wd; // Watch descriptor; -1 if a file.
bool m_valid; // True if m_stat/m_lstat are currently valid.
struct stat m_stat; // Cached stat() result.
struct stat m_lstat; // Cached lstat() result.
std::string m_link; // Cached readlink() result.
bool m_inExpirePaths;
NameNodeMap m_children; // stat() children.
NameNodeMap m_lChildren; // lstat() children.
NameMap m_paths; // Associated entries in StatCache::m_path2Node.
NameMap m_lpaths; // Associated entries in StatCache::m_lpath2Node.
std::string m_path;
};
StatCache();
~StatCache();
static void requestInit(); // Process pending file change notifications.
static int stat(const std::string& path, struct stat* buf);
static int lstat(const std::string& path, struct stat* buf);
static std::string readlink(const std::string& path);
static std::string realpath(const char* path);
private:
bool init();
void clear();
void reset();
NodePtr getNode(const std::string& path, bool follow);
bool mergePath(const std::string& path, bool follow);
bool handleEvent(const struct inotify_event* event);
void removeWatch(int wd);
void removePath(const std::string& path, Node* node);
void removeLPath(const std::string& path, Node* node);
void refresh();
time_t lastRefresh();
int statImpl(const std::string& path, struct stat* buf);
int lstatImpl(const std::string& path, struct stat* buf);
std::string readlinkImpl(const std::string& path);
std::string realpathImpl(const char* path);
static StatCache s_sc;
NameNodeMap m_path2Node; // stat() path cache.
NameNodeMap m_lpath2Node; // lstat() path cache.
SimpleMutex m_lock; // Protects the following fields.
int m_ifd;
static const size_t kReadBufSize = 10 * (sizeof(struct inotify_event)
+ NAME_MAX + 1);
char m_readBuf[kReadBufSize];
time_t m_lastRefresh; // Used for debugging.
WatchNodeMap m_watch2Node;
NodePtr m_root;
};
///////////////////////////////////////////////////////////////////////////////
}
#endif // __STAT_CACHE_H__
Jump to Line
Something went wrong with that request. Please try again.