| 384 | } |
| 385 | |
| 386 | void fork_exec_impl_mainloop(const char* arg) override { |
| 387 | CHECK_SYS_ERR(prctl(PR_SET_PDEATHSIG, SIGKILL)); |
| 388 | |
| 389 | create_sock_and_bind(arg, ::connect); |
| 390 | m_peer_fd = m_sock_fd; |
| 391 | |
| 392 | // hello and handshake |
| 393 | write_pod<uint32_t>(read_pod<uint32_t>() + 1); |
| 394 | |
| 395 | std::vector<uint8_t> param_buf; |
| 396 | |
| 397 | for (;;) { |
| 398 | auto func_id = read_pod<FuncId>(); |
| 399 | auto param_size = read_pod<size_t>(); |
| 400 | param_buf.resize(param_size); |
| 401 | read(param_buf.data(), param_size); |
| 402 | |
| 403 | bool init_done_written = false; |
| 404 | |
| 405 | bool err = false; |
| 406 | Result res; |
| 407 | auto setup_err = [&](const char* msg) { |
| 408 | err = true; |
| 409 | res.size = strlen(msg); |
| 410 | res.data = std::make_unique<uint8_t[]>(res.size); |
| 411 | memcpy(res.data.get(), msg, res.size); |
| 412 | }; |
| 413 | MGB_MARK_USED_VAR(setup_err); |
| 414 | Param func_param{param_size, param_buf.data()}; |
| 415 | MGB_TRY { |
| 416 | auto&& entry = m_func_registry.at(func_id); |
| 417 | if (entry.init) { |
| 418 | entry.init(func_param); |
| 419 | } |
| 420 | write_pod(INIT_DONE_FLAG); |
| 421 | init_done_written = true; |
| 422 | |
| 423 | res = entry.func(func_param); |
| 424 | } |
| 425 | MGB_CATCH(std::exception & exc, { setup_err(exc.what()); }) |
| 426 | MGB_CATCH(..., { setup_err("unknown error"); }); |
| 427 | if (!init_done_written) { |
| 428 | write_pod(INIT_DONE_FLAG); |
| 429 | } |
| 430 | write_pod(err); |
| 431 | write_pod(res.size); |
| 432 | write(res.data.get(), res.size); |
| 433 | } |
| 434 | } |
| 435 | |
| 436 | void register_func(FuncId id, const Func& func, const FuncInit& init) override { |