Optional Two-phase heap tracing
[hiphop-php.git] / hphp / util / afdt-util.h
blob370a24378c3dcdc7cda4b37afde38b5bdb335bef
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_AFDT_UTIL_H_
18 #define incl_HPHP_AFDT_UTIL_H_
20 #ifdef _MSC_VER
21 # error AFDT is not currently supported for MSVC!
22 #endif
24 #include <sys/socket.h>
25 #include <vector>
26 #include <string>
27 #include <stdexcept>
28 #include <cstring>
30 namespace HPHP {
31 namespace afdt {
32 ///////////////////////////////////////////////////////////////////////////////
34 namespace detail {
36 typedef void (*SrFunc)(int afdt_fd, std::vector<iovec>& iov);
38 void sappend(int afdt_fd,
39 std::vector<iovec>& iov, const void* addr, size_t size);
40 void rappend(int afdt_fd,
41 std::vector<iovec>& iov, void* addr, size_t size);
43 template<class T>
44 typename std::enable_if<
45 std::is_fundamental<T>::value || std::is_pod<T>::value,
46 void
47 >::type sappend(int afdt_fd, std::vector<iovec>& iov, const T& elm) {
48 sappend(afdt_fd, iov, &elm, sizeof elm);
51 template<class T>
52 typename std::enable_if<
53 std::is_fundamental<T>::value || std::is_pod<T>::value,
54 void
55 >::type rappend(int afdt_fd, std::vector<iovec>& iov, T* elm) {
56 rappend(afdt_fd, iov, elm, sizeof *elm);
59 void send(int afdt_fd, std::vector<iovec>& iov);
61 template<class... Tail>
62 void send(int afdt_fd, std::vector<iovec>& iov,
63 const std::vector<std::string>& h, Tail&&... args);
65 template<class... Tail>
66 void send(int afdt_fd, std::vector<iovec>& iov,
67 const std::string& h, Tail&&... args);
69 template<class... Tail>
70 void send(int afdt_fd, std::vector<iovec>& iov,
71 const char* h, Tail&&... args);
73 template<class T, class... Tail>
74 typename std::enable_if<std::is_fundamental<T>::value, void>::type
75 send(int afdt_fd, std::vector<iovec>& iov,
76 const std::vector<T>& h, Tail&&... args);
78 template<class... Tail>
79 void send(int afdt_fd, std::vector<iovec>& iov,
80 const std::vector<std::string>& h, Tail&&... args);
83 template<class Head, class... Tail>
84 void send(int afdt_fd, std::vector<iovec>& iov,
85 const Head& h, Tail&&... args) {
86 sappend(afdt_fd, iov, h);
87 send(afdt_fd, iov, std::forward<Tail>(args)...);
90 template<class... Tail>
91 void send(int afdt_fd, std::vector<iovec>& iov,
92 const std::string& h, Tail&&... args) {
93 size_t s = h.size();
94 sappend(afdt_fd, iov, s);
95 sappend(afdt_fd, iov, &h[0], s);
96 send(afdt_fd, iov, std::forward<Tail>(args)...);
99 template<class... Tail>
100 void send(int afdt_fd, std::vector<iovec>& iov,
101 const char* h, Tail&&... args) {
102 size_t s = std::strlen(h);
103 sappend(afdt_fd, iov, s);
104 sappend(afdt_fd, iov, &h[0], s);
105 send(afdt_fd, iov, std::forward<Tail>(args)...);
108 template<class T, class... Tail>
109 typename std::enable_if<std::is_fundamental<T>::value, void>::type
110 send(int afdt_fd, std::vector<iovec>& iov,
111 const std::vector<T>& h, Tail&&... args) {
112 size_t s = h.size();
113 sappend(afdt_fd, iov, s);
114 sappend(afdt_fd, iov, &h[0], s * sizeof(T));
115 send(afdt_fd, iov, std::forward<Tail>(args)...);
118 template<class... Tail>
119 void send(int afdt_fd, std::vector<iovec>& iov,
120 const std::vector<std::string>& h, Tail&&... args) {
121 size_t s = h.size();
122 sappend(afdt_fd, iov, s);
123 std::vector<size_t> sizes;
124 sizes.reserve(s);
125 for (auto& e : h) {
126 auto strsz = e.size();
127 sizes.push_back(strsz);
128 sappend(afdt_fd, iov, sizes.back());
129 sappend(afdt_fd, iov, &e[0], strsz);
131 send(afdt_fd, iov, std::forward<Tail>(args)...);
134 void recv(int afdt_fd, std::vector<iovec>& iov);
136 template<class... Tail>
137 void recv(int afdt_fd, std::vector<iovec>& iov,
138 std::string& h, Tail&... args);
140 template<class T, class... Tail>
141 typename std::enable_if<std::is_fundamental<T>::value, void>::type
142 recv(int afdt_fd, std::vector<iovec>& iov,
143 std::vector<T>& h, Tail&... args);
145 template<class... Tail>
146 void recv(int afdt_fd, std::vector<iovec>& iov,
147 std::vector<std::string>& h, Tail&... args);
150 template<class Head, class... Tail>
151 void recv(int afdt_fd, std::vector<iovec>& iov,
152 Head& h, Tail&... args) {
153 rappend(afdt_fd, iov, &h);
154 recv(afdt_fd, iov, args...);
157 template<class... Tail>
158 void recv(int afdt_fd, std::vector<iovec>& iov,
159 std::string& h, Tail&... args) {
160 size_t sz;
161 rappend(afdt_fd, iov, &sz);
162 recv(afdt_fd, iov);
163 iov.clear();
164 h.resize(sz);
165 rappend(afdt_fd, iov, &h[0], sz);
166 recv(afdt_fd, iov, args...);
169 template<class T, class... Tail>
170 typename std::enable_if<std::is_fundamental<T>::value, void>::type
171 recv(int afdt_fd, std::vector<iovec>& iov,
172 std::vector<T>& h, Tail&... args) {
173 size_t sz;
174 rappend(afdt_fd, iov, &sz);
175 recv(afdt_fd, iov);
176 iov.clear();
177 h.resize(sz);
178 rappend(afdt_fd, iov, &h[0], sz * sizeof(h[0]));
179 recv(afdt_fd, iov, args...);
182 template<class... Tail>
183 void recv(int afdt_fd, std::vector<iovec>& iov,
184 std::vector<std::string>& h, Tail&... args) {
185 size_t sz;
186 rappend(afdt_fd, iov, &sz);
187 recv(afdt_fd, iov);
188 iov.clear();
189 h.resize(sz);
190 for (auto& e : h) {
191 size_t strsz;
192 rappend(afdt_fd, iov, &strsz);
193 recv(afdt_fd, iov);
194 iov.clear();
195 e.resize(strsz);
196 rappend(afdt_fd, iov, &e[0], strsz);
198 recv(afdt_fd, iov, args...);
203 template<class Head, class... Tail>
204 void sendx(int afdt_fd, const Head& h, Tail&&... args) {
205 std::vector<iovec> iov;
206 detail::send(afdt_fd, iov, h, std::forward<Tail>(args)...);
209 template<class Head, class... Tail>
210 void recvx(int afdt_fd, Head& h, Tail&... args) {
211 std::vector<iovec> iov;
212 detail::recv(afdt_fd, iov, h, args...);
215 template<class Head, class... Tail>
216 int sendRaw(int afdt_fd, const Head& h, Tail&&... args) {
217 std::vector<iovec> iov;
218 try {
219 detail::send(afdt_fd, iov, h, std::forward<Tail>(args)...);
220 return 0;
221 } catch (const std::runtime_error& e) {
222 return -1;
226 template<class Head, class... Tail>
227 int recvRaw(int afdt_fd, Head& h, Tail&... args) {
228 std::vector<iovec> iov;
229 try {
230 detail::recv(afdt_fd, iov, h, args...);
231 return 0;
232 } catch (const std::runtime_error& e) {
233 return -1;
237 bool send_fd(int afdt_fd, int fd);
238 int recv_fd(int afdt_fd);
240 ///////////////////////////////////////////////////////////////////////////////
243 #endif