Logo AND Algorithmique Numérique Distribuée

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