AbstractRTEquipment.cpp
Go to the documentation of this file.00001
00002
00003 #include <fesa-core/RealTime/AbstractRTEquipment.h>
00004 #include <fesa-core/RealTime/AbstractRTDeviceClass.h>
00005 #include <fesa-core/Diagnostic/FesaStream.h>
00006 #include <fesa-core/DataStore/EquipmentData.h>
00007 #include <fesa-core/RealTime/RTScheduler.h>
00008 #include <fesa-core/RealTime/RTController.h>
00009 #include <fesa-core/Core/AbstractEquipment.h>
00010 #include <pthread.h>
00011
00012 #include <cmw-log/Logger.h>
00013
00014
00015 namespace
00016 {
00017
00018 CMW::Log::Logger& logger = CMW::Log::LoggerFactory::getLogger("FESA.FWK.fesa-core.RealTime.AbstractRTEquipment");
00019
00020 }
00021
00022
00023 namespace fesa
00024 {
00025
00026
00027 AbstractRTEquipment* AbstractRTEquipment::theInstance_ = NULL;
00028
00029 AbstractRTEquipment::AbstractRTEquipment()
00030
00031 {
00032
00033 theInstance_ = this;
00034 rtController_ = new RTController();
00035 }
00036
00037 void AbstractRTEquipment::initialize()
00038 {
00039 EquipmentData* eqData = EquipmentData::getInstance();
00040 *(eqData->rtUp_) = false;
00041
00042 if (*(eqData->rtProcessID_) != 0)
00043 {
00044
00045 if(kill(*(eqData->rtProcessID_), SIGFESA_CHECK_PROCESS_ALIVE) == 0)
00046 {
00047
00048 throw FesaException(__FILE__, __LINE__, FesaErrorRTProcessAlreadyExists.c_str());
00049 }
00050 else
00051 {
00052 if (errno != ESRCH)
00053 {
00054
00055 throw FesaException(__FILE__, __LINE__, FesaErrorNoPermissionToSendSignals.c_str());
00056 }
00057 }
00058 }
00059 *(eqData->rtProcessID_) = getpid();
00060
00061
00062 AbstractComponentEquipment::initialize();
00063 rtController_->initialize();
00064 }
00065
00066 void AbstractRTEquipment::start(RunMode runMode)
00067 {
00068
00069 AbstractEquipment* pEqp = AbstractEquipment::getInstance();
00070 std::string equipmentName = pEqp->getEquipmentName();
00071 FesaStream* configStream = FesaStream::getConfigStream(equipmentName + "Rt");
00072
00073 *configStream << " fesa-version=\"" << pEqp->getFesaVersion() << "\" deploy-type=\"" << pEqp->getProcessTypeAsString() << "\" fesa-compilation-DT=\"" << pEqp->getFesaBuildDate() << "\">" << std::endl;
00074 *configStream << "\t<equipment-real-time class-name=\"\" class-version=\"\"" << std::endl;
00075
00076 rtController_->printConfigAll(configStream);
00077 configStream->update();
00078 delete configStream;
00079
00080 rtController_->start();
00081
00082
00083 *(EquipmentData::getInstance()->rtUp_) = true;
00084
00085 if ( runMode == blocking )
00086 {
00087 waitSignal();
00088 }
00089 }
00090
00091 AbstractRTEquipment::~AbstractRTEquipment()
00092 {
00093 if (rtController_ != NULL)
00094 {
00095 delete rtController_;
00096 rtController_ = NULL;
00097 }
00098
00099 theInstance_ = NULL;
00100 }
00101
00102 void AbstractRTEquipment::printConfigAll(FesaStream* fesaStream)
00103 {
00104 rtController_->printConfigAll(fesaStream);
00105 }
00106 void AbstractRTEquipment::printStateAll(FesaStream* fesaStream, double elapsedTime)
00107 {
00108 rtController_->printStateAll(fesaStream, elapsedTime);
00109 }
00110
00111 void AbstractRTEquipment::waitSignal()
00112 {
00113
00114
00115 sigset_t sigset;
00116 sigemptyset(&sigset);
00117 sigaddset(&sigset, SIGTSTP);
00118 pthread_sigmask(SIG_UNBLOCK, &sigset, NULL);
00119
00120 sigemptyset(&sigset);
00121 sigaddset(&sigset, SIGHUP);
00122 sigaddset(&sigset, SIGINT);
00123 sigaddset(&sigset, SIGQUIT);
00124 sigaddset(&sigset, SIGILL);
00125 sigaddset(&sigset, SIGTRAP);
00126 sigaddset(&sigset, SIGABRT);
00127 sigaddset(&sigset, SIGBUS);
00128 sigaddset(&sigset, SIGFPE);
00129 sigaddset(&sigset, SIGSEGV);
00130 sigaddset(&sigset, SIGTERM);
00131 sigaddset(&sigset, SIGSTKFLT);
00132 sigaddset(&sigset, SIGSTOP);
00133 sigaddset(&sigset, SIGTTIN);
00134 sigaddset(&sigset, SIGTTOU);
00135 sigaddset(&sigset, SIGFESA_CHECK_PROCESS_ALIVE);
00136
00137 int32_t signalID;
00138 for (;;)
00139 {
00140
00141 sigwait(&sigset, &signalID);
00142
00143 if(signalID == SIGFESA_CHECK_PROCESS_ALIVE)
00144 {
00145 continue;
00146 }
00147
00148
00149 EquipmentData* equipmentData = EquipmentData::getInstance();
00150 kill(*(equipmentData->srvProcessPid_), SIGFESA_RT_DOWN);
00151
00152 *(equipmentData->rtUp_) = false;
00153
00154
00155 std::string errorStr("Fatal signal received, shutting down RT process. Informing Server process if any.");
00156 LOG_WARNING_IF(logger, errorStr);
00157
00158
00159
00160 pthread_sigmask(SIG_UNBLOCK, &sigset, NULL);
00161 signal(signalID, SIG_DFL);
00162 raise(signalID);
00163
00164 }
00165 return;
00166 }
00167
00168 void AbstractRTEquipment::fillRTSchedulerInfo(std::vector<RTLayerInfo*>& layerCol)
00169 {
00170
00171 RTLayerInfo* layer = new RTLayerInfo();
00172
00173 layer->layerName_ = DIAGNOSTIC_LAYER;
00174 layer->queueSize_ = -1;
00175
00176 RTSchedulingUnitRef schedulingUnit;
00177 schedulingUnit.className_ = AbstractEquipment::getInstance()->getEquipmentName();
00178 schedulingUnit.name_ = "diagnosticLayer";
00179 schedulingUnit.perDeviceCollection_ = false;
00180 schedulingUnit.found_ = false;
00181 layer->schedulingUnitRefCol_.push_back(schedulingUnit);
00182
00183 layerCol.push_back(layer);
00184 }
00185
00186 void RTLayerInfo::print()
00187 {
00188 if (logger.isLoggable(CMW::Log::Level::LL_DEBUG))
00189 {
00190 std::ostringstream msg;
00191 msg << " layerName_: " << layerName_ << " queueSize_: " << queueSize_;
00192 LOG_DEBUG_IF(logger, msg.str());
00193 }
00194 }
00195
00196 }