UniSet  2.6.0
SharedMemory.h
00001 /*
00002  * Copyright (c) 2015 Pavel Vainerman.
00003  *
00004  * This program is free software: you can redistribute it and/or modify
00005  * it under the terms of the GNU Lesser General Public License as
00006  * published by the Free Software Foundation, version 2.1.
00007  *
00008  * This program is distributed in the hope that it will be useful, but
00009  * WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00011  * Lesser General Lesser Public License for more details.
00012  *
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this program. If not, see <http://www.gnu.org/licenses/>.
00015  */
00016 // -----------------------------------------------------------------------------
00017 #ifndef SharedMemory_H_
00018 #define SharedMemory_H_
00019 // -----------------------------------------------------------------------------
00020 #include <unordered_map>
00021 #include <string>
00022 #include <memory>
00023 #include <deque>
00024 #include <time.h>
00025 #include "IONotifyController.h"
00026 #include "Mutex.h"
00027 #include "PassiveTimer.h"
00028 #include "NCRestorer.h"
00029 #include "WDTInterface.h"
00030 #include "LogServer.h"
00031 #include "DebugStream.h"
00032 #include "LogAgregator.h"
00033 #include "VMonitor.h"
00034 // -----------------------------------------------------------------------------
00035 #ifndef vmonit
00036 #define vmonit( var ) vmon.add( #var, var )
00037 #endif
00038 // --------------------------------------------------------------------------
00039 namespace uniset
00040 {
00041 // -----------------------------------------------------------------------------
00042 
00322 class SharedMemory:
00323     public IONotifyController
00324 {
00325     public:
00326         SharedMemory( uniset::ObjectId id, const std::string& datafile, const std::string& confname = "" );
00327         virtual ~SharedMemory();
00328 
00330         static std::shared_ptr<SharedMemory> init_smemory( int argc, const char* const* argv );
00331 
00333         static void help_print( int argc, const char* const* argv );
00334 
00335         // функция определяет "готовность" SM к работе.
00336         // должна использоваться другими процессами, для того,
00337         // чтобы понять, когда можно получать от SM данные.
00338         virtual CORBA::Boolean exist() override;
00339 
00340         virtual uniset::SimpleInfo* getInfo( const char* userparam = 0 ) override;
00341 
00342         void addReadItem( Restorer_XML::ReaderSlot sl );
00343 
00344         // ------------  HISTORY  --------------------
00345         typedef std::deque<long> HBuffer;
00346 
00347         struct HistoryItem
00348         {
00349             explicit HistoryItem( size_t bufsize = 0 ): id(uniset::DefaultObjectId), buf(bufsize) {}
00350             HistoryItem( const uniset::ObjectId _id, const size_t bufsize, const long val ): id(_id), buf(bufsize, val) {}
00351 
00352             inline void init( size_t size, long val )
00353             {
00354                 if( size > 0 )
00355                     buf.assign(size, val);
00356             }
00357 
00358             uniset::ObjectId id;
00359             HBuffer buf;
00360 
00361             IOStateList::iterator ioit;
00362 
00363             void add( long val, size_t size )
00364             {
00365                 // т.к. буфер у нас уже заданного размера
00366                 // то просто удаляем очередную точку в начале
00367                 // и добавляем в конце
00368                 buf.pop_front();
00369                 buf.push_back(val);
00370             }
00371         };
00372 
00373         typedef std::list<HistoryItem> HistoryList;
00374 
00375         struct HistoryInfo
00376         {
00377             HistoryInfo()
00378             {
00379                 ::clock_gettime(CLOCK_REALTIME, &fuse_tm);
00380             }
00381 
00382             long id = { 0 };                // ID
00383             HistoryList hlst;               // history list
00384             size_t size = { 0 };
00385             std::string filter = { "" };    // filter field
00386             uniset::ObjectId fuse_id = { uniset::DefaultObjectId };  // fuse sesnsor
00387             bool fuse_invert = { false };
00388             bool fuse_use_val = { false };
00389             long fuse_val = { 0 };
00390             timespec fuse_tm = { 0, 0 }; // timestamp
00391         };
00392 
00393         friend std::ostream& operator<<( std::ostream& os, const HistoryInfo& h );
00394 
00395         typedef std::list<HistoryInfo> History;
00396 
00397         // т.к. могуть быть одинаковые "детонаторы" для разных "историй" то,
00398         // вводим не просто map, а "map списка историй".
00399         // точнее итераторов-историй.
00400         typedef std::list<History::iterator> HistoryItList;
00401         typedef std::unordered_map<uniset::ObjectId, HistoryItList> HistoryFuseMap;
00402 
00403         typedef sigc::signal<void, const HistoryInfo&> HistorySlot;
00404         HistorySlot signal_history(); 
00406         inline int getHistoryStep() const
00407         {
00408             return histSaveTime;    
00409         }
00410 
00411         // -------------------------------------------------------------------------------
00412 
00413         inline std::shared_ptr<LogAgregator> logAgregator()
00414         {
00415             return loga;
00416         }
00417         inline std::shared_ptr<DebugStream> log()
00418         {
00419             return smlog;
00420         }
00421 
00422     protected:
00423         typedef std::list<Restorer_XML::ReaderSlot> ReadSlotList;
00424         ReadSlotList lstRSlot;
00425 
00426         virtual void sysCommand( const uniset::SystemMessage* sm ) override;
00427         virtual void timerInfo( const uniset::TimerMessage* tm ) override;
00428         virtual void askSensors( UniversalIO::UIOCommand cmd ) {};
00429         void sendEvent( uniset::SystemMessage& sm );
00430         void initFromReserv();
00431         bool initFromSM( uniset::ObjectId sm_id, uniset::ObjectId sm_node );
00432 
00433         // действия при завершении работы
00434         virtual void sigterm( int signo ) override;
00435         virtual bool activateObject() override;
00436         virtual bool deactivateObject() override;
00437         bool readItem( const std::shared_ptr<UniXML>& xml, UniXML::iterator& it, xmlNode* sec );
00438 
00439         void buildEventList( xmlNode* cnode );
00440         void readEventList( const std::string& oname );
00441 
00442         std::mutex mutexStart;
00443 
00444         class HeartBeatInfo
00445         {
00446             public:
00447                 HeartBeatInfo():
00448                     a_sid(uniset::DefaultObjectId),
00449                     d_sid(uniset::DefaultObjectId),
00450                     reboot_msec(UniSetTimer::WaitUpTime),
00451                     timer_running(false),
00452                     ptReboot(UniSetTimer::WaitUpTime)
00453                 {}
00454 
00455                 uniset::ObjectId a_sid; // аналоговый счётчик
00456                 uniset::ObjectId d_sid; // дискретный датчик состояния процесса
00457                 IOStateList::iterator a_it;
00458                 IOStateList::iterator d_it;
00459 
00460                 timeout_t reboot_msec; 
00465                 bool timer_running;
00466                 PassiveTimer ptReboot;
00467         };
00468 
00469         enum Timers
00470         {
00471             tmHeartBeatCheck,
00472             tmEvent,
00473             tmHistory,
00474             tmPulsar,
00475             tmLastOfTimerID
00476         };
00477 
00478         int heartbeatCheckTime;
00479         std::string heartbeat_node;
00480         int histSaveTime;
00481 
00482         void checkHeartBeat();
00483 
00484         typedef std::list<HeartBeatInfo> HeartBeatList;
00485         HeartBeatList hblist; // список датчиков "сердцебиения"
00486         std::shared_ptr<WDTInterface> wdt;
00487         std::atomic_bool activated;
00488         std::atomic_bool workready;
00489 
00490         typedef std::list<uniset::ObjectId> EventList;
00491         EventList elst;
00492         std::string e_filter;
00493         int evntPause;
00494         int activateTimeout;
00495 
00496         virtual void logging( uniset::SensorMessage& sm ) override;
00497         virtual void dumpOrdersList( const uniset::ObjectId sid, const IONotifyController::ConsumerListInfo& lst ) override {};
00498         virtual void dumpThresholdList( const uniset::ObjectId sid, const IONotifyController::ThresholdExtList& lst ) override {}
00499 
00500         bool dblogging = { false };
00501 
00504         // оптимизация с использованием userdata (IOController::USensorInfo::userdata) нужна
00505         // чтобы не использовать поиск в HistoryFuseMap (см. checkFuse)
00506         // т.к. 0,1 - использует IONotifyController (см. IONotifyController::UserDataID)
00507         // то используем не занятый "2" - в качестве элемента userdata
00508         static const size_t udataHistory = 2;
00509 
00510         History hist;
00511         HistoryFuseMap histmap;  
00513         virtual void checkFuse( std::shared_ptr<IOController::USensorInfo>& usi, IOController* );
00514         virtual void saveToHistory();
00515 
00516         void buildHistoryList( xmlNode* cnode );
00517         void checkHistoryFilter( UniXML::iterator& it );
00518 
00519         IOStateList::iterator itPulsar;
00520         uniset::ObjectId sidPulsar;
00521         int msecPulsar;
00522 
00523         xmlNode* confnode;
00524 
00525         std::shared_ptr<LogAgregator> loga;
00526         std::shared_ptr<DebugStream> smlog;
00527         std::shared_ptr<LogServer> logserv;
00528         std::string logserv_host = {""};
00529         int logserv_port = {0};
00530 
00531         VMonitor vmon;
00532 
00533     private:
00534         HistorySlot m_historySignal;
00535 };
00536 // --------------------------------------------------------------------------
00537 } // end of namespace uniset
00538 // -----------------------------------------------------------------------------
00539 #endif // SharedMemory_H_
00540 // -----------------------------------------------------------------------------