2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010- 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 +----------------------------------------------------------------------+
29 #include <netinet/in.h>
30 #include <arpa/inet.h>
37 #include <sys/types.h>
38 #include <sys/resource.h>
39 #include <sys/utsname.h>
40 #include <sys/socket.h>
55 #include <ext/hash_map>
56 #include <ext/hash_set>
58 #include <boost/shared_ptr.hpp>
59 #include <boost/enable_shared_from_this.hpp>
60 #include <boost/lexical_cast.hpp>
61 #include <boost/interprocess/sync/interprocess_upgradable_mutex.hpp>
62 #include <boost/foreach.hpp>
63 #include <boost/tuple/tuple.hpp>
64 #include <boost/filesystem/operations.hpp>
66 #include <util/hash.h>
69 ///////////////////////////////////////////////////////////////////////////////
78 #define ASSERT(x) assert(x)
81 #define ASSERT(x) assert(x)
84 ///////////////////////////////////////////////////////////////////////////////
88 #define WORDSIZE_IS_64
91 typedef unsigned char uchar
;
93 typedef unsigned char uint8
;
95 typedef unsigned short uint16
;
97 typedef unsigned int uint32
;
98 typedef long long int64
;
99 typedef unsigned long long uint64
;
102 #define ULLONG_MAX 0xffffffffffffffffULL
105 ///////////////////////////////////////////////////////////////////////////////
108 #define hphp_hash_map __gnu_cxx::hash_map
109 #define hphp_hash_set __gnu_cxx::hash_set
110 #define hphp_hash __gnu_cxx::hash
113 bool operator()(const char *s1
, const char *s2
) const {
114 return strcmp(s1
, s2
) < 0;
119 bool operator()(const char* s1
, const char* s2
) const {
120 return strcmp(s1
, s2
) == 0;
125 bool operator()(const std::string
&s1
, const std::string
&s2
) const {
126 return strcmp(s1
.c_str(), s2
.c_str()) < 0;
131 bool operator()(const std::string
&s1
, const std::string
&s2
) const {
132 return strcasecmp(s1
.c_str(), s2
.c_str()) < 0;
137 size_t operator()(const std::string
&s
) const {
138 return __gnu_cxx::__stl_hash_string(s
.c_str());
140 size_t hash(const std::string
&s
) const {
141 return operator()(s
);
145 struct string_case_hash
{
146 size_t operator()(const std::string
&s
) const {
147 return hash_string_i(s
.c_str(), s
.size());
149 size_t hash(const std::string
&s
) const {
150 return operator()(s
);
154 struct string_case_eq
{
155 bool operator()(const std::string
&lhs
,
156 const std::string
&rhs
) const {
157 return !strcasecmp(lhs
.c_str(), rhs
.c_str());
161 template<class type
, class T
> struct gnu_case_hash
:
162 public __gnu_cxx::hash_map
<std::string
, type
, string_hash
> {
166 size_t operator() (const int64 v
) const {
167 return (size_t)hash_int64(v
);
169 size_t hash(const int64 v
) const {
170 return operator()(v
);
172 bool equal(const int64 lhs
, const int64 rhs
) const {
178 struct pointer_hash
{
179 size_t operator() (const T
*const &p
) const {
180 return (size_t)hash_int64(intptr_t(p
));
182 size_t hash(const T
*const &p
) const {
183 return operator()(p
);
185 bool equal(const T
*const &lhs
,
186 const T
*const &rhs
) const {
192 struct smart_pointer_hash
{
193 size_t operator() (const T
&p
) const {
194 return (size_t)hash_int64(intptr_t(p
.get()));
196 size_t hash (const T
&p
) const {
197 return operator()(p
);
199 bool equal(const T
&lhs
, const T
&rhs
) const {
200 return lhs
.get() == rhs
.get();
204 template <class T
> class hphp_raw_ptr
{
206 hphp_raw_ptr() : ptr(0) {}
207 explicit hphp_raw_ptr(T
*p
) : ptr(p
) {}
209 hphp_raw_ptr(const boost::weak_ptr
<T
> &p
) : ptr(p
.lock().get()) {}
212 hphp_raw_ptr(const boost::shared_ptr
<S
> &p
) : ptr(p
.get()) {}
214 hphp_raw_ptr(const boost::weak_ptr
<S
> &p
) : ptr(p
.lock().get()) {}
216 hphp_raw_ptr(const hphp_raw_ptr
<S
> &p
) : ptr(p
.get()) {}
218 boost::shared_ptr
<T
> lock() const {
219 return ptr
? boost::static_pointer_cast
<T
>(ptr
->shared_from_this()) :
220 boost::shared_ptr
<T
>();
222 bool expired() const {
227 operator boost::shared_ptr
<S
>() const {
228 S
*s
= ptr
; // just to verify the implicit conversion T->S
229 return s
? boost::static_pointer_cast
<S
>(ptr
->shared_from_this()) :
230 boost::shared_ptr
<S
>();
233 T
*operator->() const { ASSERT(ptr
); return ptr
; }
234 T
*get() const { return ptr
; }
235 operator bool() const { return !expired(); }
236 void reset() { ptr
= 0; }
241 #define IMPLEMENT_PTR_OPERATORS(A, B) \
242 template <class T, class U> \
243 inline bool operator==(const A<T> &p1, const B<U> &p2) { \
244 return p1.get() == p2.get(); \
246 template <class T, class U> \
247 inline bool operator!=(const A<T> &p1, const B<U> &p2) { \
248 return p1.get() != p2.get(); \
250 template <class T, class U> \
251 inline bool operator<(const A<T> &p1, const B<U> &p2) { \
252 return intptr_t(p1.get()) < intptr_t(p2.get()); \
255 IMPLEMENT_PTR_OPERATORS(hphp_raw_ptr
, hphp_raw_ptr
);
256 IMPLEMENT_PTR_OPERATORS(hphp_raw_ptr
, boost::shared_ptr
);
257 IMPLEMENT_PTR_OPERATORS(boost::shared_ptr
, hphp_raw_ptr
);
260 class hphp_const_char_map
:
261 public hphp_hash_map
<const char *, T
, hphp_hash
<const char *>, eqstr
> {
265 class hphp_string_map
:
266 public hphp_hash_map
<std::string
, T
, string_hash
> {
269 typedef hphp_hash_set
<std::string
, string_hash
> hphp_string_set
;
270 typedef hphp_hash_set
<const char *, hphp_hash
<const char *>,
271 eqstr
> hphp_const_char_set
;
273 typedef hphp_hash_map
<void*, void*, pointer_hash
<void> > PointerMap
;
274 typedef hphp_hash_map
<void*, int, pointer_hash
<void> > PointerCounterMap
;
275 typedef hphp_hash_set
<void*, pointer_hash
<void> > PointerSet
;
277 typedef std::vector
<std::string
> StringVec
;
278 typedef boost::shared_ptr
<std::vector
<std::string
> > StringVecPtr
;
279 typedef std::pair
<std::string
, std::string
> StringPair
;
280 typedef std::set
<std::pair
<std::string
, std::string
> > StringPairSet
;
281 typedef std::vector
<StringPairSet
> StringPairSetVec
;
283 ///////////////////////////////////////////////////////////////////////////////
286 // Let us always use hphp's definition of DECLARE_BOOST_TYPES, esp. when it is
287 // used as an external library.
288 #ifdef DECLARE_BOOST_TYPES
289 #undef DECLARE_BOOST_TYPES
292 #define DECLARE_BOOST_TYPES(classname) \
294 typedef boost::shared_ptr<classname> classname ## Ptr; \
295 typedef hphp_raw_ptr<classname> classname ## RawPtr; \
296 typedef boost::weak_ptr<classname> classname ## WeakPtr; \
297 typedef boost::shared_ptr<const classname> classname ## ConstPtr; \
298 typedef std::vector<classname ## Ptr> classname ## PtrVec; \
299 typedef std::set<classname ## Ptr> classname ## PtrSet; \
300 typedef std::list<classname ## Ptr> classname ## PtrList; \
301 typedef std::deque<classname ## Ptr> classname ## PtrQueue; \
302 typedef gnu_case_hash<classname ## Ptr, classname> \
303 StringTo ## classname ## PtrMap; \
304 typedef gnu_case_hash<classname ## PtrVec, classname> \
305 StringTo ## classname ## PtrVecMap; \
306 typedef gnu_case_hash<classname ## PtrSet, classname> \
307 StringTo ## classname ## PtrSetMap; \
309 typedef boost::shared_ptr<FILE> FilePtr;
311 struct null_deleter
{
312 void operator()(void const *) const {
317 void operator()(FILE *f
) const {
322 ///////////////////////////////////////////////////////////////////////////////
324 #define ATTRIBUTE_UNUSED __attribute__((unused))
325 #if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __ICC >= 1200 || __GNUC__ > 4
326 #define ATTRIBUTE_COLD __attribute__((cold))
328 #define ATTRIBUTE_COLD
331 ///////////////////////////////////////////////////////////////////////////////
336 template <typename T
, typename U
>
337 HPHP::hphp_raw_ptr
<T
> dynamic_pointer_cast(HPHP::hphp_raw_ptr
<U
> p
) {
338 return HPHP::hphp_raw_ptr
<T
>(dynamic_cast<T
*>(p
.get()));
341 template <typename T
, typename U
>
342 HPHP::hphp_raw_ptr
<T
> static_pointer_cast(HPHP::hphp_raw_ptr
<U
> p
) {
343 return HPHP::hphp_raw_ptr
<T
>(static_cast<T
*>(p
.get()));