/* Copyright (c) 20011 Hovanes Egiyan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifndef _BaseIUMgr_HH_ #define _BaseIUMgr_HH_ extern "C" { #include #include #include #include } #include #include #include #include #include #include "BaseIUVirtBus.hh" #include "BaseIUBaseBus.hh" #include "BaseIUChassisBus.hh" using namespace std; /* * This class is to manage the multiple instances of the FCAL buses. * There will only be one object of this class in the IOC. This class * will be launching a thread for each instance of the FCAL C-W base bus. * Note that when starting the bus it will loop through the boards in the * bus to read back the content of the bus. Only after that it will launch * the main loop. */ class BaseIUMgr { private: // No instances of this class will be allowed BaseIUMgr(); BaseIUMgr( const BaseIUMgr& mgr ); BaseIUMgr& operator=( const BaseIUMgr& mgr ); public: static unsigned bmgDebFlag; //! Debug flag for this class static pthread_mutex_t bmgGlobMutex; //! Global mutex for this class static pthread_mutexattr_t bmgGlobMtxAttr; //! Global mutex attributes static pthread_cond_t bmgThrdStop; //! Condition variable for stopping thread static unsigned long bmgSleepTime; //! Sleep time between scans static unsigned long bmgResetSleepTime; //! Sleep time between bus restarts static unsigned long bmgFailureCount; //! Number of communication errors //! Maximum number of communication failure for a bus before the bus restarts static unsigned long bmgMaxFailureCount; //! Maximum number of communication failure for a bus before the bus restarts static unsigned long bmgMaxBusFailureCount; //! Map of all CW base buses including the exit request bit and the pointer to CANbus object static map > bmgBusMap; static int StartBusThread( BaseIUVirtBusID& busID ); static int StopBus( string portName ); static int StartThreads4Buses( BaseIUVirtBusID& busID, unsigned nBusses = 4 ); static void* Thread( void* argPtr ); //! The function that gets executed in the new threads static BaseIUVirtBus* CreateNewBus( BaseIUVirtBusID* busID ); static void Loop( string portName, long nMaxSyncs = -1, bool dir = false ) ; //! Main loop method static int InitGlobalMutex(); // Initialize global mutex inline static map > GetBusMap() { MtxLock classLock(bmgGlobMutex); return bmgBusMap; } inline static int GlobLock() // Lock static structures access { return pthread_mutex_lock( &bmgGlobMutex ); } inline static int GlobUnlock() // Unlock static structures access { return pthread_mutex_unlock( &bmgGlobMutex ); } // Add the bus pointer to the map inline static void AddNewBus( string portName, BaseIUVirtBus* bus ) { MtxLock classLock(bmgGlobMutex); if ( bmgBusMap.find(portName) == bmgBusMap.end() ) { pair tmpPair( false, bus ); bmgBusMap[portName] = tmpPair; return; } cerr << "Warning from AddNewBus: Bus for port " << portName << " already exist, not adding" << endl; return; } // Remove the bus from the map inline static void RemoveBus( string portName ) { MtxLock classLock(bmgGlobMutex); if ( bmgBusMap.find(portName) != bmgBusMap.end() ) { bmgBusMap.erase( portName ); return; } cerr << "Warning from RemoveBus: Bus for port " << portName << " does not exist, cannot remove" << endl; return; } // Return the bus pointer for the port name inline static BaseIUVirtBus* GetBus( string portName ) { MtxLock classLock(bmgGlobMutex); if ( bmgBusMap.find(portName) != bmgBusMap.end() ) return bmgBusMap[portName].second; return 0; } // Set the bus pointer for the port name inline static BaseIUVirtBus* SetBus( string portName, BaseIUVirtBus* bus ) { MtxLock classLock(bmgGlobMutex); if ( bmgBusMap.find(portName) != bmgBusMap.end() ) return (bmgBusMap[portName].second = bus); cerr << "Warning from SetBus: Bus for port " << portName << " does not exist, cannot remove" << endl; return 0; } // Return the exit flag for the bus on the port inline static bool GetBusExitFlag( string portName ) { MtxLock classLock(bmgGlobMutex); if ( bmgBusMap.find(portName) != bmgBusMap.end() ) return bmgBusMap[portName].first; return false; } // Set the exit flag for the bus on the port inline static bool SetBusExitFlag( string portName, bool flag ) { MtxLock classLock(bmgGlobMutex); if ( bmgBusMap.find(portName) != bmgBusMap.end() ) return ( bmgBusMap[portName].first = flag ); cerr << "Warning from SetBusExitFlag: Bus for port " << portName << " does not exist, cannot remove" << endl; return false; } inline static int GetFailureCount(){ MtxLock classLock(bmgGlobMutex); return bmgFailureCount; } }; #endif // _BaseIUMgr_HH_