Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Move the memory handling of RemoteProcessMemory singleton from ModelChecker to Checke...
[simgrid.git] / src / mc / remote / CheckerSide.cpp
1 /* Copyright (c) 2007-2023. The SimGrid Team. All rights reserved.          */
2
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. */
5
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"
10 #include <csignal>
11 #include <sys/wait.h>
12
13 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_checkerside, mc, "MC communication with the application");
14
15 namespace simgrid::mc {
16 CheckerSide::CheckerSide(int sockfd, std::unique_ptr<RemoteProcessMemory> memory, ModelChecker* mc)
17     : remote_memory_(std::move(memory)), channel_(sockfd)
18 {
19   auto* base = event_base_new();
20   base_.reset(base);
21
22   auto* socket_event = event_new(
23       base, get_channel().get_socket(), EV_READ | EV_PERSIST,
24       [](evutil_socket_t sig, short events, void* arg) {
25         auto checker = static_cast<simgrid::mc::CheckerSide*>(arg);
26         if (events == EV_READ) {
27           std::array<char, MC_MESSAGE_LENGTH> buffer;
28           ssize_t size = recv(checker->get_channel().get_socket(), buffer.data(), buffer.size(), MSG_DONTWAIT);
29           if (size == -1) {
30             XBT_ERROR("Channel::receive failure: %s", strerror(errno));
31             if (errno != EAGAIN)
32               throw simgrid::xbt::errno_error();
33           }
34
35           if (not checker->get_remote_memory().handle_message(buffer.data(), size))
36             checker->break_loop();
37         } else {
38           xbt_die("Unexpected event");
39         }
40       },
41       this);
42   event_add(socket_event, nullptr);
43   socket_event_.reset(socket_event);
44
45   auto* signal_event = event_new(
46       base, SIGCHLD, EV_SIGNAL | EV_PERSIST,
47       [](evutil_socket_t sig, short events, void* arg) {
48         auto checker = static_cast<simgrid::mc::CheckerSide*>(arg);
49         if (events == EV_SIGNAL) {
50           if (sig == SIGCHLD)
51             checker->get_remote_memory().handle_waitpid();
52           else
53             xbt_die("Unexpected signal: %d", sig);
54         } else {
55           xbt_die("Unexpected event");
56         }
57       },
58       this);
59   event_add(signal_event, nullptr);
60   signal_event_.reset(signal_event);
61 }
62
63 void CheckerSide::dispatch_events() const
64 {
65   event_base_dispatch(base_.get());
66 }
67
68 void CheckerSide::break_loop() const
69 {
70   event_base_loopbreak(base_.get());
71 }
72
73 } // namespace simgrid::mc