12 #ifndef HNET_H_INCLUDED 13 #define HNET_H_INCLUDED 24 #include <sys/types.h> 26 #include <sys/socket.h> 27 #include <sys/ioctl.h> 28 #include <netinet/in.h> 36 #define HNET_VERSION ((uint32_t)0x00010000) 37 #define HNET_CMD_DEFEXPR ((uint8_t)0) 38 #define HNET_CMD_INVOKE ((uint8_t)2) 39 #define HNET_RESULT_FAIL 0 41 typedef std::vector<uint8_t>
bytes;
44 inline void sendData(
int socket,
const uint8_t* d,
size_t sz) {
47 ssize_t c = ::send(socket, d + i, sz - i, 0);
49 throw std::runtime_error(
"Couldn't write to socket: " + std::string(strerror(errno)));
55 inline void sendString(
int socket,
const std::string& s) {
57 sendData(socket, (
const uint8_t*)&n,
sizeof(n));
58 sendData(socket, (
const uint8_t*)s.data(), n);
63 sendData(socket, (
const uint8_t*)&n,
sizeof(n));
70 inline void recvData(
int socket, uint8_t* d,
size_t sz) {
73 ssize_t di = recv(socket, d + i, sz - i, 0);
77 throw std::runtime_error(
"Couldn't read socket: " + std::string(strerror(errno)));
80 throw std::runtime_error(
"Remote process closed session prematurely");
89 recvData(socket, (uint8_t*)&n,
sizeof(n));
92 recvData(socket, (uint8_t*)&((*x)[0]), n);
96 int f = fcntl(socket, F_GETFL, 0);
98 fcntl(socket, F_SETFL, block ? (f & (~O_NONBLOCK)) : (f | O_NONBLOCK));
102 ssize_t di = recv(socket, d, sz, 0);
105 throw std::runtime_error(
"Remote process closed session prematurely");
107 if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
110 throw std::runtime_error(
"Couldn't read socket: " + std::string(strerror(errno)));
133 sendData(s, (
const uint8_t*)&version,
sizeof(version));
135 for (
const auto& rpcd : rpcds) {
137 sendData(s, &defCmd,
sizeof(defCmd));
138 sendData(s, (
const uint8_t*)&rpcd.id,
sizeof(rpcd.id));
144 recvData(s, &result,
sizeof(result));
148 std::ostringstream
m;
149 m <<
"While trying to define '" << rpcd.expr <<
"' with id=" << rpcd.id <<
": " << err << std::flush;
150 throw std::runtime_error(m.str());
157 if (connect(s, saddr, len) == -1) {
158 std::ostringstream ss;
159 ss <<
"Unable to connect socket: " << strerror(errno) << std::flush;
161 throw std::runtime_error(ss.str());
168 if (
select(s + 1, 0, &wd, 0, 0) == -1) {
169 std::ostringstream ss;
170 ss <<
"Failed to connect socket while waiting for writeability: " << strerror(errno) << std::flush;
172 throw std::runtime_error(ss.str());
179 int s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
181 throw std::runtime_error(
"Unable to allocate socket: " + std::string(strerror(errno)));
185 memset(&addr, 0,
sizeof(addr));
186 addr.sin_family = AF_INET;
187 addr.sin_addr = *((in_addr*)(host.h_addr_list[0]));
188 addr.sin_port = htons(port);
194 if (
const hostent* h = (host.size() > 0 && std::isdigit(host[0]) != 0) ? gethostbyaddr(host.c_str(), host.size(), AF_INET) : gethostbyname(host.c_str())) {
197 throw std::runtime_error(
"Unable to resolve host: " + host);
202 std::istringstream ss(port);
208 struct servent* s = getservbyname(port.c_str(),
"tcp");
212 throw std::runtime_error(
"Failed to resolve port name: " + port);
218 auto p = hostport.find(
":");
219 if (p == std::string::npos) {
220 throw std::runtime_error(
"Failed to determine port: " + hostport);
222 return makeConnection(hostport.substr(0, p), hostport.substr(p + 1, hostport.size()));
227 #define _HNET_FIRST(a, ...) a 228 #define _HNET_SECOND(a, b, ...) b 229 #define _HNET_JOIN(a,b) a ## b 230 #define _HNET_IS_NEGATE(...) _HNET_SECOND(__VA_ARGS__, 0) 231 #define _HNET_NOT(x) _HNET_IS_NEGATE(_HNET_JOIN(_HNET__NOT_, x)) 232 #define _HNET__NOT_0 NEGATE, 1 233 #define _HNET_BOOL(x) _HNET_NOT(_HNET_NOT(x)) 234 #define _HNET_IF_ELSE(condition) _HNET__IF_ELSE(_HNET_BOOL(condition)) 235 #define _HNET__IF_ELSE(condition) _HNET_JOIN(_HNET__IF_, condition) 236 #define _HNET__IF_1(...) __VA_ARGS__ _HNET__IF_1_ELSE 237 #define _HNET__IF_0(...) _HNET__IF_0_ELSE 238 #define _HNET__IF_1_ELSE(...) 239 #define _HNET__IF_0_ELSE(...) __VA_ARGS__ 240 #define _HNET_EMPTY() 241 #define _HNET_EVAL(...) _HNET_EVAL256(__VA_ARGS__) 242 #define _HNET_EVAL256(...) _HNET_EVAL128(_HNET_EVAL128(__VA_ARGS__)) 243 #define _HNET_EVAL128(...) _HNET_EVAL64(_HNET_EVAL64(__VA_ARGS__)) 244 #define _HNET_EVAL64(...) _HNET_EVAL32(_HNET_EVAL32(__VA_ARGS__)) 245 #define _HNET_EVAL32(...) _HNET_EVAL16(_HNET_EVAL16(__VA_ARGS__)) 246 #define _HNET_EVAL16(...) _HNET_EVAL8(_HNET_EVAL8(__VA_ARGS__)) 247 #define _HNET_EVAL8(...) _HNET_EVAL4(_HNET_EVAL4(__VA_ARGS__)) 248 #define _HNET_EVAL4(...) _HNET_EVAL2(_HNET_EVAL2(__VA_ARGS__)) 249 #define _HNET_EVAL2(...) _HNET_EVAL1(_HNET_EVAL1(__VA_ARGS__)) 250 #define _HNET_EVAL1(...) __VA_ARGS__ 251 #define _HNET_DEFER2(m) m _HNET_EMPTY _HNET_EMPTY()() 252 #define _HNET_HAS_PARGS(...) _HNET_BOOL(_HNET_FIRST(_HNET__EOAP_ __VA_ARGS__)()) 253 #define _HNET__EOAP_(...) _HNET_BOOL(_HNET_FIRST(_HNET__EOA_ __VA_ARGS__)()) 254 #define _HNET__EOA_() 0 255 #define _HNET_MAP(f, VS...) _HNET_EVAL(_HNET_MAPP(f, VS)) 256 #define _HNET_MAPP(f, H, T...) \ 258 _HNET_IF_ELSE(_HNET_HAS_PARGS(T))( \ 259 _HNET_DEFER2(_HNET__MAPP)()(f, T) \ 262 #define _HNET__MAPP() _HNET_MAPP 267 template <
typename T,
typename P =
void>
272 #define _HNET_TYCTOR_PRIM ((int)0) 273 #define _HNET_TYCTOR_TVAR ((int)2) 274 #define _HNET_TYCTOR_FIXEDARR ((int)4) 275 #define _HNET_TYCTOR_ARR ((int)5) 276 #define _HNET_TYCTOR_VARIANT ((int)6) 277 #define _HNET_TYCTOR_STRUCT ((int)7) 278 #define _HNET_TYCTOR_SIZE ((int)11) 279 #define _HNET_TYCTOR_RECURSIVE ((int)13) 281 template <
typename T>
282 void w(
const T& x, bytes*
out) {
283 out->insert(out->end(), (uint8_t*)&x, ((uint8_t*)&x) +
sizeof(x));
285 inline void ws(
const char* x, bytes*
out) {
286 size_t n = strlen(x);
288 out->insert(out->end(), x, x + n);
290 inline void ws(
const std::string& x, bytes*
out) {
291 w((
size_t)x.size(),
out);
292 out->insert(out->end(), x.begin(), x.end());
294 inline void ws(
const bytes& x, bytes*
out) {
295 w((
size_t)x.size(),
out);
296 out->insert(out->end(), x.begin(), x.end());
306 #define _HNET_DEFINE_PRIMTYS(T, n) \ 309 typedef void can_memcpy; \ 310 static void encode(bytes* out) { encode_primty(n, out); } \ 311 static std::string describe() { return n; } \ 312 static void write(int s, const T& x) { sendData(s, (const uint8_t*)&x, sizeof(x)); } \ 313 static void read(int s, T* x) { recvData(s, (uint8_t*)x, sizeof(T)); } \ 314 typedef uint8_t async_read_state; \ 315 static void prepare(uint8_t* o) { *o = 0; } \ 316 static bool accum(int s, uint8_t* o, T* x) { *o += recvDataPartial(s, ((uint8_t*)x) + *o, sizeof(T) - *o); return *o == sizeof(T); } \ 333 template <
typename T,
typename P =
void>
337 template <
typename T>
353 #define HNET_ENUM_CTOR_DEF(n) n , 354 #define HNET_ENUM_CTOR_CTOR(n) static const SelfT n() { return SelfT(SelfT::Enum::n); } 355 #define HNET_ENUM_CTORC_SUCC(n) +1 356 #define HNET_ENUM_CTOR_STR(n) + "|" #n 357 #define HNET_ENUM_CTOR_ENCODE(n) \ 358 ::hobbes::net::ws(#n, out); \ 359 ::hobbes::net::w((uint32_t)(Enum :: n), out); \ 360 ::hobbes::net::encode_primty("unit", out); 361 #define HNET_ENUM_TOSTR_CASE(n) \ 362 case SelfT :: Enum :: n: o << "|" #n "|"; break; 364 #define DEFINE_HNET_ENUM(T, CTORS...) \ 366 typedef void is_hnet_enum; \ 367 enum class Enum : uint32_t { \ 368 _HNET_MAP(HNET_ENUM_CTOR_DEF, CTORS) \ 373 T(Enum v) : value(v) { } \ 374 T& operator=(Enum v) { this->value = v; return *this; } \ 375 operator Enum() { return this->value; } \ 377 _HNET_MAP(HNET_ENUM_CTOR_CTOR, CTORS) \ 378 static void encode(::hobbes::net::bytes* out) { \ 379 ::hobbes::net::w(_HNET_TYCTOR_VARIANT, out); \ 380 ::hobbes::net::w((size_t)(0 _HNET_MAP(HNET_ENUM_CTORC_SUCC, CTORS)), out); \ 381 _HNET_MAP(HNET_ENUM_CTOR_ENCODE, CTORS); \ 383 static std::string describe() { \ 384 return (std::string("") _HNET_MAP(HNET_ENUM_CTOR_STR, CTORS)).substr(1); \ 386 bool operator==(const T& rhs) const { return this->value == rhs.value; } \ 388 inline std::ostream& operator<<(std::ostream& o, const T& x) { \ 391 _HNET_MAP(HNET_ENUM_TOSTR_CASE, CTORS) \ 399 template <
typename T>
400 struct io<T, typename T::is_hnet_enum> {
403 static std::string
describe() {
return T::describe(); }
404 static size_t size(
const T&) {
return sizeof(T); }
410 static bool accum(
int s, uint8_t* o, T* x) { *o +=
recvDataPartial(s, ((uint8_t*)x) + *o,
sizeof(uint32_t) - *o);
return *o ==
sizeof(uint32_t); }
414 #define DEFINE_HNET_VARIANT_GEN(T, VDECL, VCTORS, VCOPY, VDESTROY, CTORCOUNT, VENCODE, VDESC, VWRITE, VREAD, VVISITCASE, VEQCASE, CTAGS, CDATA, CAIOSTATES, CAIOSTATEINIT, CAIOREAD) \ 415 template <typename R> \ 416 struct T##Visitor { \ 420 typedef void is_hnet_variant; \ 422 T() : tag(Enum::COUNT) { } \ 424 T(const T& rhs) : tag(rhs.tag) { \ 425 switch (this->tag) { \ 431 switch (this->tag) { \ 436 T& operator=(const T& rhs) { \ 437 if (this == &rhs) return *this; \ 438 switch (this->tag) { \ 442 this->tag = rhs.tag; \ 443 switch (this->tag) { \ 449 static void encode(::hobbes::net::bytes* out) { \ 450 ::hobbes::net::w(_HNET_TYCTOR_VARIANT, out); \ 451 ::hobbes::net::w((size_t)(0 CTORCOUNT), out); \ 454 static std::string describe() { \ 455 return "|" + (std::string("") VDESC).substr(1) + "|"; \ 457 void write(int s) const { \ 458 switch (this->tag) { \ 464 switch (this->tag) { \ 468 this->tag = Enum::COUNT; \ 469 ::hobbes::net::io<uint32_t>::read(s, (uint32_t*)&this->tag); \ 470 switch (this->tag) { \ 475 template <typename R> \ 476 R visit(const T##Visitor<R>& v) const { \ 477 switch (this->tag) { \ 479 default: throw std::runtime_error("while deconstructing the " #T " variant, cannot decide payload type because tag is invalid"); \ 482 bool operator==(const T& rhs) const { \ 483 if (this->tag != rhs.tag) { \ 486 switch (this->tag) { \ 488 default: return false; \ 493 enum class Enum : uint32_t { \ 503 typedef ::hobbes::net::io<uint32_t>::async_read_state TagState; \ 504 union PayloadState { \ 508 struct async_read_state { \ 511 PayloadState payloadS; \ 513 static void prepare(async_read_state* o) { o->readTag = true; ::hobbes::net::io<uint32_t>::prepare(&o->tagS); } \ 514 static bool accum(int s, async_read_state* o, T* x) { \ 516 if (::hobbes::net::io<uint32_t>::accum(s, &o->tagS, (uint32_t*)&x->tag)) { \ 517 o->readTag = false; \ 534 #define HNET_VARIANT_CTOR(n, t) static SelfT n(const t & x) { SelfT r; r.tag = Enum::tag_##n; new (r.data) t(x); return r; } 535 #define HNET_VARIANT_CTOR_STR(n, t) + "," #n ":" + ::hobbes::net::io< t >::describe() 536 #define HNET_VARIANT_CTOR_TAG(n, t) tag_##n, 537 #define HNET_VARIANT_WRITE_CASE(n, t) case Enum::tag_##n: ::hobbes::net::io<int>::write(s, (int)this->tag); ::hobbes::net::io< t >::write(s, this->n##_data); break; 538 #define HNET_VARIANT_READ_CASE(n, t) case Enum::tag_##n: new (this->data) t(); ::hobbes::net::io< t >::read(s, &this->n##_data); break; 539 #define HNET_VARIANT_PCOPY(n, t) case Enum::tag_##n: new (this->data) t(rhs.n##_data); break; 540 #define HNET_VARIANT_PDESTROY(n, t) case Enum::tag_##n: { typedef t __DT; ((__DT*)&this->n##_data)->~__DT(); } break; 541 #define HNET_VARIANT_SUCC(n, t) +1 542 #define HNET_VARIANT_CTOR_OPAQUEDATA(n, t) t n##_data; 543 #define HNET_VARIANT_CTOR_ENCODE(n, t) \ 544 ::hobbes::net::ws(#n, out); \ 545 ::hobbes::net::w((uint32_t)Enum::tag_##n, out); \ 546 ::hobbes::net::io< t >::encode(out); 548 #define HNET_VARIANT_VDECL(n, t) virtual R n(const t & x) const = 0; 549 #define HNET_VARIANT_VCASE(n, t) case Enum::tag_##n: return v.n (this->n##_data); 550 #define HNET_VARIANT_EQCASE(n, t) case Enum::tag_##n: return (this->n##_data == rhs.n##_data); 552 #define HNET_VARIANT_AIOSTATE_DATA(n, t) ::hobbes::net::io<t>::async_read_state n##_aioS; 553 #define HNET_VARIANT_AIOSTATE_INIT(n, t) case Enum::tag_##n: { new (o->payloadS.data) ::hobbes::net::io<t>::async_read_state(); ::hobbes::net::io<t>::prepare(&o->payloadS.n##_aioS); new (x->data) t(); } break; 554 #define HNET_VARIANT_AIOSTATE_ACCUM(n, t) case Enum::tag_##n: return ::hobbes::net::io<t>::accum(s, &o->payloadS.n##_aioS, &x->n##_data); 556 #define DEFINE_HNET_VARIANT(T, CTORS...) \ 557 DEFINE_HNET_VARIANT_GEN(T, _HNET_MAP(HNET_VARIANT_VDECL, CTORS), _HNET_MAP(HNET_VARIANT_CTOR, CTORS), _HNET_MAP(HNET_VARIANT_PCOPY, CTORS), _HNET_MAP(HNET_VARIANT_PDESTROY, CTORS), _HNET_MAP(HNET_VARIANT_SUCC, CTORS), _HNET_MAP(HNET_VARIANT_CTOR_ENCODE, CTORS), _HNET_MAP(HNET_VARIANT_CTOR_STR, CTORS), _HNET_MAP(HNET_VARIANT_WRITE_CASE, CTORS), _HNET_MAP(HNET_VARIANT_READ_CASE, CTORS), _HNET_MAP(HNET_VARIANT_VCASE, CTORS), _HNET_MAP(HNET_VARIANT_EQCASE, CTORS), _HNET_MAP(HNET_VARIANT_CTOR_TAG, CTORS), _HNET_MAP(HNET_VARIANT_CTOR_OPAQUEDATA, CTORS), _HNET_MAP(HNET_VARIANT_AIOSTATE_DATA, CTORS), _HNET_MAP(HNET_VARIANT_AIOSTATE_INIT, CTORS), _HNET_MAP(HNET_VARIANT_AIOSTATE_ACCUM, CTORS)) 560 #define HNET_VARIANT_LBL_CTOR(n, lbl, t) static SelfT n(const t & x) { SelfT r; r.tag = Enum::tag_##n; new (r.data) t(x); return r; } 561 #define HNET_VARIANT_LBL_CTOR_STR(n, lbl, t) + "," #n ":" + ::hobbes::net::io< t >::describe() 562 #define HNET_VARIANT_LBL_CTOR_TAG(n, lbl, t) tag_##n, 563 #define HNET_VARIANT_LBL_WRITE_CASE(n, lbl, t) case Enum::tag_##n: ::hobbes::net::io<int>::write(s, (int)this->tag); ::hobbes::net::io< t >::write(s, this->n##_data); break; 564 #define HNET_VARIANT_LBL_READ_CASE(n, lbl, t) case Enum::tag_##n: new (this->data) t(); ::hobbes::net::io< t >::read(s, &this->n##_data); break; 565 #define HNET_VARIANT_LBL_PCOPY(n, lbl, t) case Enum::tag_##n: new (this->data) t(rhs.n##_data); break; 566 #define HNET_VARIANT_LBL_PDESTROY(n, lbl, t) case Enum::tag_##n: { typedef t __DT; ((__DT*)&this->n##_data)->~__DT(); } break; 567 #define HNET_VARIANT_LBL_SUCC(n, lbl, t) +1 568 #define HNET_VARIANT_LBL_CTOR_OPAQUEDATA(n, lbl, t) t n##_data; 569 #define HNET_VARIANT_LBL_CTOR_ENCODE(n, lbl, t) \ 570 ::hobbes::net::ws(#lbl, out); \ 571 ::hobbes::net::w((uint32_t)Enum::tag_##n, out); \ 572 ::hobbes::net::io< t >::encode(out); 574 #define HNET_VARIANT_LBL_VDECL(n, lbl, t) virtual R n(const t & x) const = 0; 575 #define HNET_VARIANT_LBL_VCASE(n, lbl, t) case Enum::tag_##n: return v. n (this->n##_data); 576 #define HNET_VARIANT_LBL_EQCASE(n, lbl, t) case Enum::tag_##n: return (this->n##_data == rhs.n##_data); 578 #define HNET_VARIANT_LBL_CTOR_AIOSTATE_DATA(n, lbl, t) ::hobbes::net::io<t>::async_read_state n##_aioS; 579 #define HNET_VARIANT_LBL_CTOR_AIOSTATE_INIT(n, lbl, t) case Enum::tag_##n: { new (o->payloadS.data) ::hobbes::net::io<t>::async_read_state(); ::hobbes::net::io<t>::prepare(&o->payloadS.n##_aioS); new (x->data) t(); } break; 580 #define HNET_VARIANT_LBL_CTOR_AIOSTATE_ACCUM(n, lbl, t) case Enum::tag_##n: return ::hobbes::net::io<t>::accum(s, &o->payloadS.n##_aioS, &x->n##_data); 582 #define DEFINE_HNET_VARIANT_WITH_LABELS(T, CTORS...) \ 583 DEFINE_HNET_VARIANT_GEN(T, _HNET_MAP(HNET_VARIANT_LBL_VDECL, CTORS), _HNET_MAP(HNET_VARIANT_LBL_CTOR, CTORS), _HNET_MAP(HNET_VARIANT_LBL_PCOPY, CTORS), _HNET_MAP(HNET_VARIANT_LBL_PDESTROY, CTORS), _HNET_MAP(HNET_VARIANT_LBL_SUCC, CTORS), _HNET_MAP(HNET_VARIANT_LBL_CTOR_ENCODE, CTORS), _HNET_MAP(HNET_VARIANT_LBL_CTOR_STR, CTORS), _HNET_MAP(HNET_VARIANT_LBL_WRITE_CASE, CTORS), _HNET_MAP(HNET_VARIANT_LBL_READ_CASE, CTORS), _HNET_MAP(HNET_VARIANT_LBL_VCASE, CTORS), _HNET_MAP(HNET_VARIANT_LBL_EQCASE, CTORS), _HNET_MAP(HNET_VARIANT_LBL_CTOR_TAG, CTORS), _HNET_MAP(HNET_VARIANT_LBL_CTOR_OPAQUEDATA, CTORS), _HNET_MAP(HNET_VARIANT_LBL_CTOR_AIOSTATE_DATA, CTORS), _HNET_MAP(HNET_VARIANT_LBL_CTOR_AIOSTATE_INIT, CTORS), _HNET_MAP(HNET_VARIANT_LBL_CTOR_AIOSTATE_ACCUM, CTORS)) 585 template <
typename T>
586 struct io<T, typename T::is_hnet_variant> {
588 static std::string
describe() {
return T::describe(); }
589 static void write(
int s,
const T& x) {
return x.write(s); }
590 static void read(
int s, T* x) {
return x->read(s); }
594 static void prepare(async_read_state* o) { T::prepare(o); }
595 static bool accum(
int s, async_read_state* o, T* x) {
return T::accum(s, o, x); }
599 template <
typename U,
typename V>
616 static void write(
int s,
const std::pair<U,V>& p) {
620 static void read(
int s, std::pair<U,V>* p) {
626 struct async_read_state {
641 static bool accum(
int s, async_read_state* o, std::pair<U, V>* x) {
644 o->readFirst =
false;
656 template <
typename T>
657 struct io<
std::vector<T>, typename
io<T>::can_memcpy> {
660 static void write(
int s,
const std::vector<T>& x) {
size_t n = x.size();
io<size_t>::write(s, n);
if (n > 0)
sendData(s, (
const uint8_t*)&x[0],
sizeof(T) * n); }
664 struct async_read_state {
678 static bool accum(
int s, async_read_state* o, std::vector<T>* x) {
681 x->resize(o->byteLen);
683 o->byteLen =
sizeof(T) * o->byteLen;
687 uint8_t* buf = (uint8_t*)&((*x)[0]);
688 o->bytesRead +=
recvDataPartial(s, buf + o->bytesRead, o->byteLen - o->bytesRead);
690 return !o->readLen && o->bytesRead == o->byteLen;
694 template <
typename T>
698 static void write(
int s,
const std::vector<T>& x) {
701 for (
size_t i = 0; i < n; ++i) {
705 static void read(
int s, std::vector<T>* x) {
709 for (
size_t i = 0; i < n; ++i) {
715 struct async_read_state {
730 static bool accum(
int s, async_read_state* o, std::vector<T>* x) {
744 return !o->readLen && o->idx == x->size();
749 template <
typename K,
typename T>
753 static void write(
int s,
const std::map<K,T>& x) {
756 for (
const auto& xp : x) {
761 static void read(
int s, std::map<K,T>* x) {
764 for (
size_t i = 0; i < n; ++i) {
776 enum class ReadS : uint8_t { LenS, KS, TS };
778 struct async_read_state {
788 o->readS = ReadS::LenS;
791 static bool accum(
int s, async_read_state* o, std::map<K,T>* x) {
795 o->readS = ReadS::KS;
801 o->readS = ReadS::TS;
809 o->readS = ReadS::KS;
814 return o->readS != ReadS::LenS && o->len == 0;
820 struct io<const char*> {
833 struct async_read_state {
847 static bool accum(
int s, async_read_state* o, std::string* x) {
850 x->resize(o->byteLen);
855 uint8_t* buf = (uint8_t*)&((*x)[0]);
856 o->bytesRead +=
recvDataPartial(s, buf + o->bytesRead, o->byteLen - o->bytesRead);
858 return !o->readLen && o->bytesRead == o->byteLen;
863 #define HNET_FIELDC_SUCC(t,n) +1 864 #define HNET_FIELD_COUNT(FIELDS...) (0 _HNET_MAP(HNET_FIELDC_SUCC, FIELDS)) 866 #define HNET_FIELDW_SUCC(t,n) ::hobbes::net::io< t >::write(s, this-> n); 867 #define HNET_FIELD_WRITES(FIELDS...) _HNET_MAP(HNET_FIELDW_SUCC, FIELDS) 869 #define HNET_FIELDR_SUCC(t,n) ::hobbes::net::io< t >::read(s, &this-> n); 870 #define HNET_FIELD_READS(FIELDS...) _HNET_MAP(HNET_FIELDR_SUCC, FIELDS) 872 #define HNET_STRUCT_FIELD(t, n) t n; 873 #define HNET_STRUCT_FIELD_ENC(t, n) ::hobbes::net::ws(#n, out); ::hobbes::net::w((int)-1, out); ::hobbes::net::io< t >::encode(out); 874 #define HNET_STRUCT_FIELD_DESC(t, n) + (", " #n " : " + ::hobbes::net::io< t >::describe()) 876 #define HNET_FIELD_ASYNC_READ_IDX_DEF(_, n) readAt_##n, 877 #define HNET_FIELD_ASYNC_READ_STATE_DEC(t, n) ::hobbes::net::io< t >::async_read_state n; 878 #define HNET_FIELD_ASYNC_READ_STATE_INIT(t, n) ::hobbes::net::io< t >::prepare(&o->fieldStates.n); 879 #define HNET_FIELD_ASYNC_READ_FIELD(t, n) case FieldIndex::readAt_##n: if (::hobbes::net::io< t >::accum(s, &o->fieldStates.n, &x->n)) { o->idx = (FieldIndex)(((uint32_t)o->idx) + 1); } break; 881 #define DEFINE_HNET_STRUCT(T, FIELDS...) \ 883 _HNET_MAP(HNET_STRUCT_FIELD, FIELDS) \ 884 typedef void is_hnet_struct; \ 885 static void encode(::hobbes::net::bytes* out) { \ 886 size_t arity = HNET_FIELD_COUNT(FIELDS); \ 888 ::hobbes::net::w(_HNET_TYCTOR_STRUCT, out); \ 889 ::hobbes::net::w(arity, out); \ 890 _HNET_MAP(HNET_STRUCT_FIELD_ENC, FIELDS) \ 892 ::hobbes::net::encode_primty("unit", out); \ 895 static std::string describe() { \ 896 return "{" + ( std::string("") _HNET_MAP(HNET_STRUCT_FIELD_DESC, FIELDS) ).substr(2) + "}"; \ 898 void write(int s) const { \ 899 HNET_FIELD_WRITES(FIELDS); \ 902 HNET_FIELD_READS(FIELDS); \ 905 enum class FieldIndex : uint32_t { \ 907 _HNET_MAP(HNET_FIELD_ASYNC_READ_IDX_DEF, FIELDS) \ 910 struct async_read_state { \ 913 _HNET_MAP(HNET_FIELD_ASYNC_READ_STATE_DEC, FIELDS) \ 916 static void prepare(async_read_state* o) { \ 917 o->idx = (FieldIndex)1; \ 918 _HNET_MAP(HNET_FIELD_ASYNC_READ_STATE_INIT, FIELDS) \ 920 static bool accum(int s, async_read_state* o, T* x) { \ 922 _HNET_MAP(HNET_FIELD_ASYNC_READ_FIELD, FIELDS) \ 925 return o->idx == FieldIndex::_FieldListEnd; \ 929 template <
typename T>
930 struct io<T, typename T::is_hnet_struct> {
932 static std::string
describe() {
return T::describe(); }
933 static void write(
int s,
const T& x) { x.write(s); }
934 static void read(
int s, T* x) { x->read(s); }
937 static void prepare(async_read_state* o) { T::prepare(o); }
938 static bool accum(
int s, async_read_state* o, T* x) {
return T::accum(s, o, x); }
942 template <
typename ... Ts>
944 static const size_t count = 0;
947 static void write(
int,
const Ts&...) { }
949 template <
typename T,
typename ... Ts>
951 static const size_t count = 1 +
oSeq<Ts...>::count;
955 snprintf(fn,
sizeof(fn),
".f%lld", (
unsigned long long)f);
965 static void write(
int socket,
const T& x,
const Ts&... xs) {
971 template <
size_t i,
size_t e,
typename ... Ts>
973 static void write(
int s,
const std::tuple<Ts...>& t) {
977 static void read(
int s, std::tuple<Ts...>* t) {
978 io<
typename std::tuple_element<i,
std::tuple<Ts...>>::type>
::read(s, &std::get<i>(*t));
982 template <
size_t e,
typename ... Ts>
984 static void write(
int s,
const std::tuple<Ts...>&) { }
985 static void read(
int s, std::tuple<Ts...>*) { }
988 template <
typename ... Ts>
993 template <
typename T,
typename ... Ts>
1004 template <
size_t i,
typename T>
1006 template <
typename U,
typename V>
1009 static U*
get(std::pair<U,V>* x) {
return &x->first; }
1011 template <
size_t i,
typename U,
typename V>
1017 template <
size_t i,
size_t e,
typename ... Ts>
1027 template <
size_t e,
typename ... Ts>
1032 template <
typename ... Ts>
1035 size_t arity =
oSeq<Ts...>::count;
1047 return (x.size() > 1) ? x.substr(0,x.size()-1) : x;
1049 static void write(
int s,
const std::tuple<Ts...>& t) {
1052 static void read(
int s, std::tuple<Ts...>* t) {
1059 static bool accum(
int s, async_read_state* o, std::tuple<Ts...>* x) {
1060 if (
aioTupleRead<0, std::tuple_size<std::tuple<Ts...>>::value, Ts...>::accum(s, o->first, &o->second, x)) {
1063 return o->first ==
oSeq<Ts...>::count;
1068 #define DEFINE_HNET_TYPE_ALIAS(_ATY, _REPTY) \ 1070 typedef void is_hnet_alias; \ 1071 typedef _REPTY type; \ 1072 static const char* name() { return #_ATY; } \ 1073 inline operator _REPTY() { return this->value; } \ 1075 _ATY() : value() { } \ 1076 _ATY(const _REPTY& x) : value(x) { } \ 1077 _ATY(const _ATY& x) : value(x.value) { } \ 1078 _ATY& operator=(const _ATY& x) { this->value = x.value; return *this; } \ 1081 template <
typename T>
1082 struct io<T, typename T::is_hnet_alias> {
1098 template <
typename F>
1101 template <
typename R,
typename ...
Args>
1106 template <
typename ...
Args>
1113 template <
typename F>
1116 template <
typename R,
typename ...
Args>
1121 int s = *this->socket;
1135 template <
typename ...
Args>
1140 int s = *this->socket;
1151 #define _HNET_CLIENT_MAKE_EXPRID(n, _, __) , exprID_##n 1152 #define _HNET_CLIENT_MAKE_RPCDEF(n, t, e) result.push_back(::hobbes::net::RPCDef((uint32_t)exprID_##n, e, ::hobbes::net::RPCTyDef<t>::inputType(), ::hobbes::net::RPCTyDef<t>::outputType())); 1153 #define _HNET_CLIENT_INIT_RPCFUNC(n, t, _) , n(&this->s, (uint32_t)exprID_##n) 1154 #define _HNET_CLIENT_MAKE_RPCFUNC(n, t, _) ::hobbes::net::RPCFunc<t> n; 1156 #define DEFINE_NET_CLIENT(T, C...) \ 1161 T(int fd) : s(::hobbes::net::initSession(fd, makeRPCDefs())) _HNET_MAP(_HNET_CLIENT_INIT_RPCFUNC, C) { } \ 1162 T(const std::string& host, size_t port) : T(::hobbes::net::makeConnection(host, port)) { } \ 1163 T(const std::string& host, const std::string& port) : T(::hobbes::net::makeConnection(host, port)) { } \ 1164 T(const std::string& hostport) : T(::hobbes::net::makeConnection(hostport)) { } \ 1165 virtual ~T() { closeC(); } \ 1166 int fd() const { return this->s; } \ 1167 void reconnect(int fd) { closeC(); this->s = ::hobbes::net::initSession(fd, makeRPCDefs()); } \ 1168 void reconnect(const std::string& host, size_t port) { reconnect(::hobbes::net::makeConnection(host, port)); } \ 1169 void reconnect(const std::string& host, const std::string& port) { reconnect(::hobbes::net::makeConnection(host, port)); } \ 1170 void reconnect(const std::string& hostport) { reconnect(::hobbes::net::makeConnection(hostport)); } \ 1172 _HNET_MAP(_HNET_CLIENT_MAKE_RPCFUNC, C) \ 1176 _HNET_MAP(_HNET_CLIENT_MAKE_EXPRID, C) \ 1178 static ::hobbes::net::RPCDefs makeRPCDefs() { \ 1179 ::hobbes::net::RPCDefs result; \ 1180 _HNET_MAP(_HNET_CLIENT_MAKE_RPCDEF, C) \ 1192 template <
typename F>
1195 template <
typename R,
typename ...
Args>
1197 typedef std::function<void(const R&)>
K;
1200 sched(sched), socket(socket), exprid(exprid)
1206 int s = *this->socket;
1217 this->sched->enqueue(
this);
1222 this->ks.front()(this->
r);
1237 typedef std::queue<K>
KS;
1243 template <
typename ...
Args>
1248 int s = *this->socket;
1264 #define _HNET_CLIENT_INIT_ASYNC_RPCFUNC(n, t, _) , n(this, &this->s, (uint32_t)exprID_##n) 1265 #define _HNET_CLIENT_MAKE_ASYNC_RPCFUNC(n, t, _) ::hobbes::net::AsyncRPCFunc<t> n; 1267 #define DEFINE_ASYNC_NET_CLIENT(T, C...) \ 1268 class T : public ::hobbes::net::AsyncScheduler { \ 1272 T(int fd) : s(::hobbes::net::initSession(fd, makeRPCDefs())) _HNET_MAP(_HNET_CLIENT_INIT_ASYNC_RPCFUNC, C) { } \ 1273 T(const std::string& host, size_t port) : T(::hobbes::net::makeConnection(host, port)) { } \ 1274 T(const std::string& host, const std::string& port) : T(::hobbes::net::makeConnection(host, port)) { } \ 1275 T(const std::string& hostport) : T(::hobbes::net::makeConnection(hostport)) { } \ 1276 virtual ~T() { closeC(); } \ 1277 int fd() const { return this->s; } \ 1278 void reconnect(int fd) { closeC(); this->s = ::hobbes::net::initSession(fd, makeRPCDefs()); } \ 1279 void reconnect(const std::string& host, size_t port) { reconnect(::hobbes::net::makeConnection(host, port)); } \ 1280 void reconnect(const std::string& host, const std::string& port) { reconnect(::hobbes::net::makeConnection(host, port)); } \ 1281 void reconnect(const std::string& hostport) { reconnect(::hobbes::net::makeConnection(hostport)); } \ 1282 void step() { while (this->asyncReaders.size() > 0 && this->asyncReaders.front()->readAndFinish()) { this->asyncReaders.pop(); } } \ 1283 size_t pendingRequests() const { return this->asyncReaders.size(); } \ 1285 _HNET_MAP(_HNET_CLIENT_MAKE_ASYNC_RPCFUNC, C) \ 1289 _HNET_MAP(_HNET_CLIENT_MAKE_EXPRID, C) \ 1291 static ::hobbes::net::RPCDefs makeRPCDefs() { \ 1292 ::hobbes::net::RPCDefs result; \ 1293 _HNET_MAP(_HNET_CLIENT_MAKE_RPCDEF, C) \ 1296 std::queue<::hobbes::net::AsyncReader*> asyncReaders; \ 1297 void enqueue(::hobbes::net::AsyncReader* r) { this->asyncReaders.push(r); } \ 1300 this->asyncReaders = std::queue<::hobbes::net::AsyncReader*>(); \ static void encode(bytes *out)
Definition: net.H:587
static bool accum(int s, async_read_state *o, std::vector< T > *x)
Definition: net.H:730
static void prepare(async_read_state *o)
Definition: net.H:725
size_t byteLen
Definition: net.H:670
static bytes outputType()
Definition: net.H:1109
#define _HNET_TYCTOR_ARR
Definition: net.H:275
void type
Definition: net.H:335
void write(int fd, const char *s)
Definition: www.C:23
bytes willGet
Definition: net.H:126
R r
Definition: net.H:1240
size_t byteLen
Definition: net.H:839
LenS lenS
Definition: net.H:780
aioTupleStateAt< i-1, V >::type type
Definition: net.H:1013
aioTupleState< Ts... >::async_read_state SndRS
Definition: net.H:996
static void write(int s, const T &x)
Definition: net.H:405
io< V >::async_read_state Vstate
Definition: net.H:628
io< size_t >::async_read_state LenS
Definition: net.H:773
static void write(int s, const std::string &x)
Definition: net.H:829
static void prepare(async_read_state *o)
Definition: net.H:673
static void encode(bytes *out)
Definition: net.H:658
static std::string describe()
Definition: net.H:1045
static void prepare(async_read_state *o)
Definition: net.H:787
io< U >::async_read_state Ustate
Definition: net.H:627
size_t len
Definition: net.H:781
std::vector< RPCDef > RPCDefs
Definition: net.H:128
void recvData(int socket, uint8_t *d, size_t sz)
Definition: net.H:70
void encode(const PrimitivePtr &, std::ostream &)
Definition: expr.C:1674
static void encode(bytes *out)
Definition: net.H:1083
static void encode(bytes *out)
Definition: net.H:931
static void encode(bytes *out)
Definition: net.H:402
static void encode(size_t, bytes *)
Definition: net.H:945
void read(gzbuffer *in, uint8_t *b, size_t n)
Definition: batchrecv.C:86
size_t bytesRead
Definition: net.H:838
static void write(int socket, const T &x, const Ts &... xs)
Definition: net.H:965
bool readLen
Definition: net.H:836
static size_t size(const T &)
Definition: net.H:404
int * socket
Definition: net.H:1147
std::tuple async_read_state
Definition: net.H:990
static void read(int s, std::tuple< Ts... > *t)
Definition: net.H:977
bool readLen
Definition: net.H:667
static void encode(bytes *out)
Definition: net.H:827
void can_memcpy
Definition: net.H:401
uint32_t exprid
Definition: net.H:1133
std::vector< uint8_t > bytes
Definition: net.H:41
static void encode(bytes *out)
Definition: net.H:346
static void write(int s, const std::tuple< Ts... > &)
Definition: net.H:984
Definition: pattern.H:281
std::pair< std::string, std::string > pair
Definition: str.H:220
static bool accum(int s, async_read_state *o, T *x)
Definition: net.H:938
static bytes inputType()
Definition: net.H:1103
std::string expr
Definition: net.H:124
int * socket
Definition: net.H:1260
R operator()(const Args &... args)
Definition: net.H:1120
size_t bytesRead
Definition: net.H:669
static void write(int s, const T &x)
Definition: net.H:589
static void write(int s, const T &x)
Definition: net.H:1085
static std::string describe()
Definition: net.H:828
void operator()(const Args &... args, const K &k)
Definition: net.H:1205
static void read(int s, T *x)
Definition: net.H:406
AsyncScheduler * sched
Definition: net.H:1232
static bool accum(int s, async_read_state *o, T *x)
Definition: net.H:595
static void prepare(async_read_state *)
Definition: net.H:991
static bool accum(int s, async_read_state *o, std::pair< U, V > *x)
Definition: net.H:641
bool readLen
Definition: net.H:719
uint32_t id
Definition: net.H:123
static void write(int s, const std::map< K, T > &x)
Definition: net.H:753
uint32_t exprid
Definition: net.H:34
static std::string describe()
Definition: net.H:1084
KS kS
Definition: net.H:782
io< size_t >::async_read_state LenS
Definition: net.H:834
static std::string describe()
Definition: net.H:588
ReadS readS
Definition: net.H:779
U type
Definition: net.H:1008
static void read(int s, std::vector< T > *x)
Definition: net.H:661
static void write(int s, const std::tuple< Ts... > &t)
Definition: net.H:1049
static void read(int s, std::vector< T > *x)
Definition: net.H:705
static void read(int s, std::pair< U, V > *p)
Definition: net.H:620
static void prepare(async_read_state *o)
Definition: net.H:999
RPCDef(uint32_t id=0, const std::string &expr="", const bytes &willPut=bytes(), const bytes &willGet=bytes())
Definition: net.H:118
static bool accum(int s, size_t ti, typename aioTupleState< Ts... >::async_read_state *o, std::tuple< Ts... > *x)
Definition: net.H:1019
std::function< void(const R &)> K
Definition: net.H:1197
bool readAndFinish()
Definition: net.H:1220
static void encode(bytes *out)
Definition: net.H:751
uint32_t exprid
Definition: net.H:1234
RPCFunc(int *socket, uint32_t exprid)
Definition: net.H:1118
void sendString(int socket, const std::string &s)
Definition: net.H:55
void sendData(int socket, const uint8_t *d, size_t sz)
Definition: net.H:44
#define _HNET_TYCTOR_STRUCT
Definition: net.H:277
static void encode(bytes *out)
Definition: net.H:1034
T * get(variant< Ctors... > &v)
Definition: variant.H:156
T select(const std::vector< T > &xs, I i)
Definition: array.H:92
io< K >::async_read_state KS
Definition: net.H:774
int initSession(int s, const RPCDefs &rpcds)
Definition: net.H:131
static std::string describe()
Definition: net.H:613
void setBlockingBit(int socket, bool block)
Definition: net.H:95
static void read(int s, T *x)
Definition: net.H:1086
void encode_primty(const char *tn, bytes *out)
Definition: net.H:299
static void write(int s, const char *x)
Definition: net.H:823
void ws(const char *x, bytes *out)
Definition: net.H:285
io< typename T::type >::async_read_state async_read_state
Definition: net.H:1088
T::async_read_state async_read_state
Definition: net.H:936
static std::string describe()
Definition: net.H:822
static void write(int s, const T &x)
Definition: net.H:933
static bytes outputType()
Definition: net.H:1104
void operator()(const Args &... args)
Definition: net.H:1247
void write(imagefile *f, const T &x)
Definition: file.C:188
uint32_t exprid
Definition: net.H:1261
static void encode(bytes *out)
Definition: net.H:601
static void write(int s, const std::vector< T > &x)
Definition: net.H:660
static void read(int s, std::map< K, T > *x)
Definition: net.H:761
static bool accum(int s, async_read_state *o, std::map< K, T > *x)
Definition: net.H:791
static std::string describe()
Definition: net.H:697
#define HNET_CMD_INVOKE
Definition: net.H:38
static void prepare(async_read_state *o)
Definition: net.H:635
static void prepare(async_read_state *o)
Definition: net.H:842
static std::string describe()
Definition: net.H:946
static void prepare(async_read_state *o)
Definition: net.H:1058
ElemS elemS
Definition: net.H:722
static bool accum(int s, size_t, typename aioTupleState< Ts... >::async_read_state *, std::tuple< Ts... > *)
Definition: net.H:1029
LenS lenS
Definition: net.H:837
bool readFirst
Definition: net.H:630
io< T >::async_read_state TS
Definition: net.H:775
static void read(int s, std::string *x)
Definition: net.H:830
void operator()(const Args &... args)
Definition: net.H:1139
io< size_t >::async_read_state LenS
Definition: net.H:665
static std::string describe()
Definition: net.H:752
static bool accum(int s, async_read_state *o, T *x)
Definition: net.H:1090
size_t r(const reader::MetaData &md, size_t o, T *t)
Definition: storage.H:1730
#define HNET_RESULT_FAIL
Definition: net.H:39
void w(const T &x, bytes *out)
Definition: net.H:282
static bool accum(int s, async_read_state *o, std::string *x)
Definition: net.H:847
static void write(int s, const std::vector< T > &x)
Definition: net.H:698
int * socket
Definition: net.H:1233
static bool accum(int s, async_read_state *o, std::tuple< Ts... > *x)
Definition: net.H:1059
int * socket
Definition: net.H:1132
static void read(int s, std::tuple< Ts... > *)
Definition: net.H:985
int makeConnection(int s, sockaddr *saddr, size_t len)
Definition: net.H:156
io< size_t >::async_read_state LenS
Definition: net.H:716
size_t recvDataPartial(int socket, uint8_t *d, size_t sz)
Definition: net.H:101
static void write(int, const Ts &...)
Definition: net.H:947
#define HNET_CMD_DEFEXPR
Definition: net.H:37
ExprPtr fn(const str::seq &vns, const ExprPtr &b, const LexicalAnnotation &la)
Definition: expr.H:837
std::pair< FstRS, SndRS > async_read_state
Definition: net.H:997
#define out
Definition: netio.H:19
static bytes inputType()
Definition: net.H:1108
io< T >::async_read_state FstRS
Definition: net.H:995
Vstate sndState
Definition: net.H:632
uint32_t result
Definition: regex.C:376
static std::string describe()
Definition: net.H:347
static void prepare(async_read_state *o)
Definition: net.H:937
size_t idx
Definition: net.H:721
#define _HNET_TYCTOR_PRIM
Definition: net.H:272
KS ks
Definition: net.H:1239
void sendBytes(int socket, const bytes &x)
Definition: net.H:61
static void write(int s, const unit &)
Definition: net.H:348
static bool accum(int s, async_read_state *o, std::vector< T > *x)
Definition: net.H:678
static std::string describe()
Definition: net.H:403
uint8_t async_read_state
Definition: net.H:408
_HNET_DEFINE_PRIMTYS(bool, "bool")
static void read(int s, T *x)
Definition: net.H:934
static void prepare(async_read_state *o)
Definition: net.H:594
RPCFunc(int *socket, uint32_t exprid)
Definition: net.H:1137
static void encode(bytes *out)
Definition: net.H:696
std::map< std::string, llvm::Value * > Args
Definition: dfa.C:1276
unit()
Definition: net.H:342
AsyncRPCFunc(AsyncScheduler *, int *socket, uint32_t exprid)
Definition: net.H:1245
AsyncRPCFunc(AsyncScheduler *sched, int *socket, uint32_t exprid)
Definition: net.H:1199
static void write(int s, const std::pair< U, V > &p)
Definition: net.H:616
static void write(int s, const std::tuple< Ts... > &t)
Definition: net.H:973
io< T >::async_read_state ElemS
Definition: net.H:717
ReadS
Definition: net.H:776
io< R >::async_read_state async_read_state
Definition: net.H:1236
LenS lenS
Definition: net.H:668
static std::string describe()
Definition: net.H:962
MonoTypePtr tuple(const MonoTypes &mtys=MonoTypes())
Definition: type.H:1068
static void read(int s, T *x)
Definition: net.H:590
LexicalAnnotation m(const YYLTYPE &p)
Definition: hexpr.parse.C:127
#define HNET_VERSION
Definition: net.H:36
LenS lenS
Definition: net.H:720
static void read(int s, std::tuple< Ts... > *t)
Definition: net.H:1052
static void prepare(async_read_state *o)
Definition: net.H:1089
static void encode(size_t f, bytes *out)
Definition: net.H:953
static std::string describe()
Definition: net.H:932
static void read(int s, unit *)
Definition: net.H:349
std::queue< K > KS
Definition: net.H:1237
static std::string describe()
Definition: net.H:659
static void encode(bytes *out)
Definition: net.H:821
std::pair< size_t, typename aioTupleState< Ts... >::async_read_state > async_read_state
Definition: net.H:1057
static void prepare(uint8_t *o)
Definition: net.H:409
uint32_t exprid
Definition: net.H:1148
static bool accum(int s, uint8_t *o, T *x)
Definition: net.H:410
void read(const imagefile *f, T *x)
Definition: file.C:215
Ustate fstState
Definition: net.H:631
void recvString(int socket, std::string *x)
Definition: net.H:87
T::async_read_state async_read_state
Definition: net.H:593
async_read_state pr
Definition: net.H:1241
bytes willPut
Definition: net.H:125
TS tS
Definition: net.H:784