76 bool EventLoop::init(
int argc,
char* argv[]) {
77 struct sigaction sact{};
78 sigemptyset(&sact.sa_mask);
80 sact.sa_handler = SIG_IGN;
82 struct sigaction oldPipeAct{};
83 sigaction(SIGPIPE, &sact, &oldPipeAct);
85 struct sigaction oldIntAct{};
86 sigaction(SIGINT, &sact, &oldIntAct);
88 struct sigaction oldTermAct{};
89 sigaction(SIGTERM, &sact, &oldTermAct);
91 struct sigaction oldAlarmAct{};
92 sigaction(SIGALRM, &sact, &oldAlarmAct);
94 struct sigaction oldHupAct{};
95 sigaction(SIGHUP, &sact, &oldHupAct);
97 logger::Logger::setCustomFormatSpec(
"%tick", core::getTickCounterAsString);
99 if (utils::Config::init(argc, argv)) {
100 eventLoopState = State::INITIALIZED;
102 LOG(TRACE) <<
"SNode.C: Starting ... HELLO";
105 sigaction(SIGPIPE, &oldPipeAct,
nullptr);
106 sigaction(SIGINT, &oldIntAct,
nullptr);
107 sigaction(SIGTERM, &oldTermAct,
nullptr);
108 sigaction(SIGALRM, &oldAlarmAct,
nullptr);
109 sigaction(SIGHUP, &oldHupAct,
nullptr);
111 return eventLoopState == State::INITIALIZED;
114 TickStatus EventLoop::_tick(
const utils::Timeval& tickTimeOut) {
115 TickStatus tickStatus = TickStatus::SUCCESS;
120 sigaddset(&newSet, SIGINT);
121 sigaddset(&newSet, SIGTERM);
122 sigaddset(&newSet, SIGALRM);
123 sigaddset(&newSet, SIGHUP);
126 sigprocmask(SIG_BLOCK, &newSet, &oldSet);
128 if (eventLoopState == State::RUNNING || eventLoopState == State::STOPPING) {
129 tickStatus = eventMultiplexer.tick(tickTimeOut, oldSet);
132 sigprocmask(SIG_SETMASK, &oldSet,
nullptr);
137 TickStatus EventLoop::tick(
const utils::Timeval& timeOut) {
138 TickStatus tickStatus = TickStatus::TRACE;
140 if (eventLoopState == State::INITIALIZED) {
141 struct sigaction sact{};
142 sigemptyset(&sact.sa_mask);
144 sact.sa_handler = SIG_IGN;
146 struct sigaction oldPipeAct{};
147 sigaction(SIGPIPE, &sact, &oldPipeAct);
149 tickStatus = EventLoop::instance()._tick(timeOut);
151 sigaction(SIGPIPE, &oldPipeAct,
nullptr);
153 EventLoop::instance().eventMultiplexer.clearEventQueue();
156 PLOG(FATAL) <<
"Core: not initialized: No events will be processed\nCall SNodeC::init(argc, argv) before SNodeC::tick().";
162 int EventLoop::start(
const utils::Timeval& timeOut) {
163 struct sigaction sact{};
164 sigemptyset(&sact.sa_mask);
166 sact.sa_handler = SIG_IGN;
168 struct sigaction oldPipeAct{};
169 sigaction(SIGPIPE, &sact, &oldPipeAct);
171 sact.sa_handler = EventLoop::stoponsig;
173 struct sigaction oldIntAct{};
174 sigaction(SIGINT, &sact, &oldIntAct);
176 struct sigaction oldTermAct{};
177 sigaction(SIGTERM, &sact, &oldTermAct);
179 struct sigaction oldAlarmAct{};
180 sigaction(SIGALRM, &sact, &oldAlarmAct);
182 struct sigaction oldHupAct{};
183 sigaction(SIGHUP, &sact, &oldHupAct);
185 if (eventLoopState == State::INITIALIZED && utils::Config::bootstrap()) {
186 eventLoopState = State::RUNNING;
187 core::TickStatus tickStatus = TickStatus::SUCCESS;
189 LOG(TRACE) <<
"Core::EventLoop: started";
192 tickStatus = EventLoop::instance()._tick(timeOut);
193 }
while ((tickStatus == TickStatus::SUCCESS || tickStatus == TickStatus::INTERRUPTED) && eventLoopState == State::RUNNING);
195 switch (tickStatus) {
196 case TickStatus::SUCCESS:
197 LOG(TRACE) <<
"Core::EventLoop: Stopped";
199 case TickStatus::NOOBSERVER:
200 LOG(TRACE) <<
"Core::EventLoop: No Observer";
202 case TickStatus::INTERRUPTED:
203 LOG(TRACE) <<
"Core::EventLoop: Interrupted";
205 case TickStatus::TRACE:
206 PLOG(FATAL) <<
"Core::EventLoop: _tick()";
211 sigaction(SIGPIPE, &oldPipeAct,
nullptr);
212 sigaction(SIGTERM, &oldTermAct,
nullptr);
213 sigaction(SIGALRM, &oldAlarmAct,
nullptr);
214 sigaction(SIGHUP, &oldHupAct,
nullptr);
218 sigaction(SIGINT, &oldIntAct,
nullptr);
227 void EventLoop::free() {
228 std::string signal =
"SIG" + utils::system::sigabbrev_np(stopsig);
230 if (signal ==
"SIGUNKNOWN") {
231 signal = std::to_string(stopsig);
235 LOG(TRACE) <<
"Core: Sending signal " << signal <<
" to all DescriptorEventReceivers";
237 EventLoop::instance().eventMultiplexer.signal(stopsig);
240 eventLoopState = State::STOPPING;
242 utils::Timeval timeout = 2;
244 core::TickStatus tickStatus = TickStatus::SUCCESS;
246 auto t1 = std::chrono::system_clock::now();
247 const utils::Timeval timeoutOp = timeout;
249 tickStatus = EventLoop::instance()._tick(timeoutOp);
251 auto t2 = std::chrono::system_clock::now();
252 const std::chrono::duration<
double> seconds = t2 - t1;
254 timeout -= seconds.count();
255 }
while (timeout > 0 && (tickStatus == TickStatus::SUCCESS));
257 LOG(TRACE) <<
"Core: Terminate all stalled DescriptorEventReceivers";
259 EventLoop::instance().eventMultiplexer.terminate();
261 LOG(TRACE) <<
"Core: Close all libraries opened during runtime";
263 DynamicLoader::execDlCloseAll();
265 LOG(TRACE) <<
"Core:: Clean up the filesystem";
267 utils::Config::terminate();
269 LOG(TRACE) <<
"Core:: All resources released";
271 LOG(TRACE) <<
"SNode.C: Ended ... BYE";