1 /* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved. */
3 /* This program is free software; you can redistribute it and/or modify it
4 * under the terms of the license (GNU LGPL) which comes with this package. */
6 #include "src/mc/remote/CheckerSide.hpp"
7 #include "src/mc/ModelChecker.hpp"
8 #include "src/mc/sosp/RemoteProcessMemory.hpp"
9 #include "xbt/system_error.hpp"
13 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_checkerside, mc, "MC communication with the application");
15 namespace simgrid::mc {
16 CheckerSide::CheckerSide(int sockfd, ModelChecker* mc) : channel_(sockfd)
18 auto* base = event_base_new();
21 auto* socket_event = event_new(
22 base, get_channel().get_socket(), EV_READ | EV_PERSIST,
23 [](evutil_socket_t sig, short events, void* arg) {
24 auto checker = static_cast<simgrid::mc::CheckerSide*>(arg);
25 if (events == EV_READ) {
26 std::array<char, MC_MESSAGE_LENGTH> buffer;
27 ssize_t size = recv(checker->get_channel().get_socket(), buffer.data(), buffer.size(), MSG_DONTWAIT);
29 XBT_ERROR("Channel::receive failure: %s", strerror(errno));
31 throw simgrid::xbt::errno_error();
34 if (not mc_model_checker->handle_message(buffer.data(), size))
35 checker->break_loop();
37 xbt_die("Unexpected event");
41 event_add(socket_event, nullptr);
42 socket_event_.reset(socket_event);
44 auto* signal_event = event_new(
45 base, SIGCHLD, EV_SIGNAL | EV_PERSIST,
46 [](evutil_socket_t sig, short events, void* arg) {
47 auto mc = static_cast<simgrid::mc::ModelChecker*>(arg);
48 if (events == EV_SIGNAL) {
50 mc->handle_waitpid(mc->get_remote_process_memory().pid());
52 xbt_die("Unexpected signal: %d", sig);
54 xbt_die("Unexpected event");
58 event_add(signal_event, nullptr);
59 signal_event_.reset(signal_event);
62 void CheckerSide::dispatch() const
64 event_base_dispatch(base_.get());
67 void CheckerSide::break_loop() const
69 event_base_loopbreak(base_.get());
72 } // namespace simgrid::mc