1 // ANNA - Anna is Not Nothingness Anymore //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
12 #include <sys/types.h>
14 #include <anna/core/tracing/Logger.hpp>
16 #include <anna/timex/Engine.hpp>
17 #include <anna/timex/internal/TickConsumer.hpp>
18 #include <anna/timex/internal/TickProducer.hpp>
23 //--------------------------------------------------------------------------------------------
24 // (1) Para evitar que el 'write' sobre el pipe se pueda quedar bloqueado cuando halla algn
25 // problema. Se detecto el bloqueo cuando el disco sobre el que se ejecutaba la aplicacin
27 // (2) Puede ser que se invoque mas de una vez.
28 //--------------------------------------------------------------------------------------------
29 void anna::timex::TickConsumer::initialize()
30 throw(RuntimeException) {
31 if(a_pipe [0] != -1) // (2)
35 throw RuntimeException("Cannot create the pipe", errno, ANNA_FILE_LOCATION);
37 if(fcntl(a_pipe [1], F_SETFL, O_NONBLOCK | O_NDELAY) == -1) // (1)
38 throw RuntimeException("Cannot establish Non-Block mode on pipe", errno, ANNA_FILE_LOCATION);
43 void anna::timex::TickConsumer::apply()
44 throw(RuntimeException) {
53 anna_signal_shield(r, read(a_pipe [0], buffer, sizeof(buffer)));
56 Logger::write(Logger::Critical, "Cannot recover the tick", strerror(errno), ANNA_FILE_LOCATION);
59 a_timeController.tick();
62 } catch(Exception& ex) {
67 void anna::timex::TickConsumer::finalize()
69 if(a_timeController.a_tickProducer)
70 a_timeController.a_tickProducer->requestStop();
74 * Si usaramos directamente el duplicado de los fd's que hace fork, todos los procesos compartirian el
75 * mismo pipe, es decir, el proceso padre podria escribir al generar la alarma, pero el tratamiento del
76 * tick podria hacerlo el tercer hijo, lo que haria imposible el correcto funcionamiento de las transaciones.
78 * Asi que cada proceso debe tener su propia copia del pipe, para que cada uno lleve independientemente
79 * el control de tiempos.
81 void anna::timex::TickConsumer::clone()
82 throw(RuntimeException) {
87 throw RuntimeException("Cannot create the pipe", errno, ANNA_FILE_LOCATION);
89 if(fcntl(a_pipe [1], F_SETFL, O_NONBLOCK | O_NDELAY) == -1) // (1)
90 throw RuntimeException("Cannot establish Non-Block mode on pipe", errno, ANNA_FILE_LOCATION);
94 if(a_timeController.a_tickProducer)
95 a_timeController.a_tickProducer->setfd(a_pipe [1]);
98 std::string anna::timex::TickConsumer::asString() const
100 string result("timex::TickConsumer { ");
101 result += Handler::asString();
102 return result += functions::asString(" | Pipe (Read = %d, Write = %d) } ", a_pipe [0], a_pipe [1]);