Add a HHIR-level peephole optimization to reorder CheckTypes
[hiphop-php.git] / hphp / util / afdt-util.cpp
blobda129d2d30360c8ec7af3324ea5c79d0c32d608e
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 +----------------------------------------------------------------------+
16 #include "hphp/util/afdt-util.h"
17 #include <afdt.h>
18 #include <fcntl.h>
19 #include <errno.h>
20 #include <limits.h>
21 #include <system_error>
23 #include "hphp/util/assertions.h"
25 namespace HPHP {
26 namespace afdt {
27 ///////////////////////////////////////////////////////////////////////////////
29 namespace detail {
31 namespace {
32 void append(std::vector<iovec>& iov, const void* addr, size_t size) {
33 if (!size) return;
35 iovec io;
36 io.iov_base = const_cast<void*>(addr);
37 io.iov_len = size;
38 iov.push_back(io);
42 void sappend(int afdt_fd,
43 std::vector<iovec>& iov, const void* addr, size_t size) {
44 if (iov.size() == IOV_MAX) {
45 send(afdt_fd, iov);
46 iov.clear();
48 append(iov, addr, size);
51 void rappend(int afdt_fd,
52 std::vector<iovec>& iov, void* addr, size_t size) {
53 if (iov.size() == IOV_MAX) {
54 recv(afdt_fd, iov);
55 iov.clear();
57 append(iov, addr, size);
60 void send(int afdt_fd, std::vector<iovec>& iov) {
61 if (iov.size() == 0) return;
63 struct msghdr msg;
64 memset(&msg, 0, sizeof(msg));
65 msg.msg_iov = &iov[0];
66 msg.msg_iovlen = iov.size();
67 ssize_t nwritten = sendmsg(afdt_fd, &msg, MSG_WAITALL);
68 if (nwritten < 0) {
69 throw std::system_error(errno, std::generic_category(), "send failed");
71 for (auto& io : iov) {
72 nwritten -= io.iov_len;
74 if (nwritten) throw std::runtime_error("sent wrong number of bytes");
77 void recv(int afdt_fd, std::vector<iovec>& iov) {
78 if (iov.size() == 0) return;
80 struct msghdr msg;
81 memset(&msg, 0, sizeof(msg));
82 msg.msg_iov = &iov[0];
83 msg.msg_iovlen = iov.size();
84 ssize_t nread = recvmsg(afdt_fd, &msg, MSG_WAITALL);
85 if (nread <= 0) {
86 throw std::system_error(errno, std::generic_category(), "recv failed");
88 for (auto& io : iov) {
89 nread -= io.iov_len;
91 if (nread) throw std::runtime_error("recv received wrong number of bytes");
96 bool send_fd(int afdt_fd, int fd) {
97 afdt_error_t err = AFDT_ERROR_T_INIT;
98 errno = 0;
99 int ret = afdt_send_fd_msg(afdt_fd, nullptr, 0, fd, &err);
100 if (ret < 0 && errno == 0) {
101 // Set non-empty errno if afdt_send_fd_msg doesn't set one on error
102 errno = EPROTO;
104 return ret >= 0;
107 int recv_fd(int afdt_fd) {
108 #ifdef __APPLE__
110 errno = 0;
111 int flags = fcntl(0, F_GETFD);
112 always_assert(flags != -1 || errno != EBADF);
114 #endif
115 int fd;
116 afdt_error_t err = AFDT_ERROR_T_INIT;
117 uint32_t afdt_len = 0;
118 errno = 0;
119 if (afdt_recv_fd_msg(afdt_fd, nullptr, &afdt_len, &fd, &err) < 0) {
120 if (errno == 0) {
121 // Set non-empty errno if afdt_send_fd_msg doesn't set one on error
122 errno = EPROTO;
124 return -1;
126 return fd;
129 ///////////////////////////////////////////////////////////////////////////////