bool SendHeartbeat (bool bWithStash) { LOGDEBUG (TEXT ("Sending heartbeat message")); FudgeStatus status; FudgeMsg msg; if ((status = FudgeMsg_create (&msg)) != FUDGE_OK) { LOGFATAL (TEXT ("Couldn't create message, status ") << status); assert (0); return false; } if ((status = ConnectorMessage_setOperation (msg, HEARTBEAT)) != FUDGE_OK) { FudgeMsg_release (msg); LOGFATAL (TEXT ("Couldn't create message, status ") << status); assert (0); return false; } if (bWithStash) { m_oStashMutex.Enter (); if (m_msgStash) { if ((status = ConnectorMessage_setStash (msg, m_msgStash)) != FUDGE_OK) { LOGFATAL (TEXT ("Couldn't create message, status ") << status); assert (0); status = FUDGE_OK; // Not good, but can carry on } } m_oStashMutex.Leave (); } bool bResult = m_poService->Send (MESSAGE_DIRECTIVES_CLIENT, msg); FudgeMsg_release (msg); return bResult; }
AFS_API int32 PrintErrorV(const char* sFormat, CVaList& pArgList) { g_oStdOutMutex.Enter(); int32 nRet = CSingleInstance<CStdErrFormatter>::GetInstance()->oFormatter.PrintV(sFormat, pArgList); g_oStdOutMutex.Leave(); return nRet; }
AFS_API int32 ScanV(const char* sFormat, CVaList& pArgList) { g_oStdInMutex.Enter(); int32 nRet = CSingleInstance<CStdInFormatter>::GetInstance()->oFormatter.ScanV(sFormat, pArgList); g_oStdInMutex.Leave(); return nRet; }
CAcmUdp::~CAcmUdp() { if(m_bRegistered) { g_oMutex.Enter(); g_oUdpTable.Remove(m_nDomain); g_oMutex.Leave(); } }
void SetStash (FudgeMsg msgStash) { m_oStashMutex.Enter (); if (m_msgStash) { LOGDEBUG (TEXT ("Discarding old stash message")); FudgeMsg_release (m_msgStash); } FudgeMsg_retain (msgStash); m_msgStash = msgStash; m_oStashMutex.Leave (); }
/// Attempts to stop the service. /// /// @param[in] bForce TRUE to stop the service immediately by closing the IPC, FALSE to initiate a /// lazy close when the IPC goes idle. void ServiceStop (bool bForce) { g_oMutex.Enter (); if (bForce) { _ReportStateStopping (); g_poPipe->Close (); } else { g_poPipe->LazyClose (); } g_oMutex.Leave (); }
/// Returns the binary encoding of the message. /// /// @return the encoding const void *CFudgeMsgInfo::GetData () { if (!m_pData) { g_oMutex.Enter (); if (!m_pData) { m_pData = _EncodeFudgeMsg (m_msg, &m_cbData); } g_oMutex.Leave (); } return m_pData; }
CAcmUdp* CAcmUdp::QueryUdp(uint32 nDomain) { CAcmUdp* pUdp = NULL; g_oMutex.Enter(); CRbTreeNode* pIt = g_oUdpTable.Find(nDomain); if(pIt != g_oUdpTable.End()) pUdp = g_oUdpTable.GetItem(pIt); g_oMutex.Leave(); return pUdp; }
/// Returns the length of the binary encoding of the message in bytes. /// /// @return the length if bytes size_t CFudgeMsgInfo::GetLength () { if (!m_pData) { g_oMutex.Enter (); if (!m_pData) { m_pData = _EncodeFudgeMsg (m_msg, &m_cbData); } g_oMutex.Leave (); } return m_cbData; }
CMdb* CMdb::GetMdb(const char* sDbName) { CMdb* pDb = NULL; CRbTreeNode* pEnd = m_oMdbTable.End(); g_oMdbMutex.Enter(); CRbTreeNode* pIt = m_oMdbTable.Find(sDbName); if(pIt != pEnd) pDb = m_oMdbTable.GetItem(pIt); g_oMdbMutex.Leave(); return pDb; }
/// Finds an existing message entry in the map, or creates a new entry if none is found. /// The message is returned with an incremented reference count - the caller should call /// Release when finished with it (unless the reference is offloaded to R). /// /// @param[in] the message to look up /// @return the message entry CFudgeMsgInfo *CFudgeMsgInfo::GetMessage (FudgeMsg msg) { CFudgeMsgInfo *poMessage; g_oMutex.Enter (); TFudgeMsgMap::const_iterator itr = g_oMap.find (msg); if (itr != g_oMap.end ()) { poMessage = itr->second; poMessage->m_nRefCount++; g_oMutex.Leave (); return poMessage; } poMessage = new CFudgeMsgInfo (msg, NULL, 0); if (poMessage) { LOGDEBUG (TEXT ("Adding message to map (size = ") << (g_oMap.size () + 1) << TEXT (")")); g_oMap.insert (TFudgeMsgMap::value_type (msg, poMessage)); g_cbData += MESSAGE_INFO_OVERHEAD; } else { LOGFATAL (TEXT ("Out of memory")); } g_oMutex.Leave (); return poMessage; }
void UnLoad(CShareLibrary* pLib) { if(pLib) { CRbTreeNode* pEnd = m_oLibs.End(); m_oMutex.Enter(); CRbTreeNode* pIt = m_oLibs.Find(pLib->GetFileName()); if( (pIt != pEnd) && (pLib == m_oLibs.GetItem(pIt)) && pLib->Release()) m_oLibs.Remove(pIt); m_oMutex.Leave(); } }
void CMdb::RemoveAll() { RemoveAccessTable(); g_oMdbMutex.Enter(); while(m_oMdbTable.GetSize()) { CRbTreeNode* pIt = m_oMdbTable.First(); CMdb* pDb = m_oMdbTable.GetItem(pIt); delete pDb; } g_oMdbMutex.Leave(); }
/// Decrements the R reference count, destroying the object when the count reaches zero. void CFudgeMsgInfo::Release (CFudgeMsgInfo *poMessage) { g_oMutex.Enter (); LOGDEBUG (TEXT ("Releasing CFudgeMsgInfo, rc=") << poMessage->m_nRefCount); if (--poMessage->m_nRefCount == 0) { TFudgeMsgMap::iterator itr = g_oMap.find (poMessage->m_msg); if (itr != g_oMap.end ()) { LOGDEBUG (TEXT ("Removing message from map (size = ") << (g_oMap.size () - 1) << TEXT (")")); g_oMap.erase (itr); g_cbData -= MESSAGE_INFO_OVERHEAD; } delete poMessage; } g_oMutex.Leave (); }
void CAcmUdp::GetAllDomains(CVector<uint32> &oDomains) { oDomains.Clear(); CRbTreeNode* pEnd = g_oUdpTable.End(); g_oMutex.Enter(); CRbTreeNode* pIt = g_oUdpTable.First(); for(uint32 nIdx=0; pIt!=pEnd; pIt=g_oUdpTable.GetNext(pIt)) { uint32 nDomain = g_oUdpTable.GetKey(pIt); oDomains.Insert(nIdx, nDomain); ++nIdx; } g_oMutex.Leave(); }
CMdb::CMdb(const char* sName) { CRbTreeNode* pEnd = m_oMdbTable.End(); g_oMdbMutex.Enter(); CRbTreeNode* pIt = m_oMdbTable.Find(sName); if(pIt != pEnd) FocpAbort(("CMdb::CMdb(%s) failure: repeate register dbname", sName)); pIt = m_oMdbTable.Insert(CString(sName), this); m_sDbName = m_oMdbTable.GetKey(pIt).GetStr(); if(g_oDbList.GetSize()) g_oDbList += ","; g_oDbList += sName; g_oMdbMutex.Leave(); }
MCI_API const char* GetMdbError(uint32 nCode) { const char* sInfo = NULL; if(nCode) { CRbTreeNode* pEnd = m_oErrorTable.End(); g_oErrorMutex.Enter(); CRbTreeNode* pIt = m_oErrorTable.Find(nCode); if(pIt != pEnd) sInfo = m_oErrorTable.GetItem(pIt); g_oErrorMutex.Leave(); } return sInfo; }
MCI_API bool RegMdbError(uint32 nCode, const char* sInfo) { if(nCode == 0 || sInfo == NULL || sInfo[0] == '\0') return false; bool bRet = true; CRbTreeNode* pEnd = m_oErrorTable.End(); g_oErrorMutex.Enter(); CRbTreeNode* pIt = m_oErrorTable.Find(nCode); if(pIt == pEnd) m_oErrorTable[nCode] = sInfo; else bRet = false; g_oErrorMutex.Leave(); return bRet; }
/// Finds an existing message entry in the map, or creates a new entry if none is found. /// The message is returned with an incremented reference count - the caller should call /// Release when finished with it (unless the reference is offloaded to R). /// /// @param[in] pData the binary encoding of the message to lock up /// @param[in] cbData the length of the binary encoding in bytes CFudgeMsgInfo *CFudgeMsgInfo::GetMessage (const void *pData, size_t cbData) { g_oMutex.Enter (); FudgeMsg msg = NULL; CFudgeMsgInfo *poMessage = NULL; void *pDataCopy = NULL; do { msg = _DecodeFudgeMsg (pData, cbData); if (!msg) { break; } TFudgeMsgMap::const_iterator itr = g_oMap.find (msg); if (itr != g_oMap.end ()) { poMessage = itr->second; poMessage->m_nRefCount++; break; } pDataCopy = malloc (cbData); if (!pDataCopy) { LOGFATAL (TEXT ("Out of memory")); break; } memcpy (pDataCopy, pData, cbData); poMessage = new CFudgeMsgInfo (msg, pDataCopy, cbData); if (!poMessage) { LOGFATAL (TEXT ("Out of memory")); break; } LOGDEBUG (TEXT ("Adding message to map (size = ") << (g_oMap.size () + 1) << TEXT (")")); g_oMap.insert (TFudgeMsgMap::value_type (msg, poMessage)); g_cbData += cbData + MESSAGE_INFO_OVERHEAD; pDataCopy = NULL; } while (false); g_oMutex.Leave (); if (msg) FudgeMsg_release (msg); if (pDataCopy) free (pDataCopy); return poMessage; }
CAcmUdp::CAcmUdp(CAcmContext* pContext, uint32 nDomain, uint32 nNode, bool bMultiCast, bool bReg) :m_oRecvThread(this), m_oProcThread(this), m_oRecvThread2(this) { m_bRegistered = bReg; if(m_bRegistered) { g_oMutex.Enter(); CRbTreeNode* pIt = g_oUdpTable.Find(nDomain); if(pIt != g_oUdpTable.End()) FocpAbort(("CAcmUdp::CAcmUdp(%u), the domain is registered", nDomain)); g_oUdpTable[nDomain] = this; g_oMutex.Leave(); } m_bMultiCast = bMultiCast; m_bChecked = false; m_pContext = pContext; m_nPid = GetPid(); m_nMultiCastAddr = (uint32)(-1); m_nItfAddr = (uint32)(-1); m_nDomain = nDomain; m_nNode = nNode; m_nUniCastPort = 0; m_nPort = 0; }
/// Increments the R reference count. void CFudgeMsgInfo::Retain () { g_oMutex.Enter (); m_nRefCount++; g_oMutex.Leave (); }
/// Run the service, returning when it has stopped. /// /// @param[in] nReason how the service is running, e.g. SERVICE_RUN_INLINE, in case actions are different depending /// on how it was started. void ServiceRun (int nReason) { _ServiceStartup (nReason); g_poJVM = CJVM::Create (); if (!g_poJVM) { LOGERROR (TEXT ("Couldn't create JVM")); _ReportStateErrored (); return; } g_poJVM->Start (); g_poPipe = CConnectionPipe::Create (); if (!g_poPipe) { LOGERROR (TEXT ("Couldn't create IPC pipe")); } while (g_poJVM->IsBusy (g_lBusyTimeout)) { _ReportStateStarting (); } if (g_poPipe && g_poJVM->IsRunning ()) { _ReportStateRunning (); do { LOGDEBUG (TEXT ("Waiting for user connection")); ClientConnect *pcc = g_poPipe->ReadMessage (); if (pcc) { LOGINFO (TEXT ("Connection received from ") << pcc->_userName); LOGDEBUG (TEXT ("C++ -> Java = ") << pcc->_CPPToJavaPipe); LOGDEBUG (TEXT ("Java -> C++ = ") << pcc->_JavaToCPPPipe); // TODO [PLAT-1117] Use challenge/response to verify the user name g_poJVM->UserConnection (pcc->_userName, pcc->_CPPToJavaPipe, pcc->_JavaToCPPPipe, pcc->_languageID); ClientConnect_free (pcc); if (!g_poJVM->IsStopped ()) { g_poPipe->CancelLazyClose (); if (g_poJVM->IsStopped ()) { // Stop might have occurred between the check and the cancel, so restore the cancel ServiceStop (false); } } g_oMutex.Enter (); if (g_poPipe->IsClosed ()) { LOGINFO (TEXT ("Pipe closed with pending connection - reopening")); delete g_poPipe; g_poPipe = CConnectionPipe::Create (); if (g_poPipe) { _ReportStateRunning (); } else { LOGERROR (TEXT ("Couldn't create IPC pipe - shutting down JVM")); g_poJVM->Stop (); } } g_oMutex.Leave (); } else { LOGERROR (TEXT ("Shutting down JVM after failing to read from pipe")); g_poJVM->Stop (); } } while (!g_poJVM->IsBusy (g_lBusyTimeout) && g_poJVM->IsRunning ()); _ReportStateStopping (); while (g_poJVM->IsBusy (g_lBusyTimeout)) { _ReportStateStopping (); } _ReportStateStopped (); } else { _ReportStateErrored (); } if (g_poPipe) { delete g_poPipe; g_poPipe = NULL; } delete g_poJVM; g_poJVM = NULL; }
CShareLibrary* Load(const char* sLibName, bool bTry=false) { char sLibName2[FOCP_MAX_PATH]; if(sLibName == NULL || !sLibName[0]) sLibName2[0] = '\0'; else { CDiskFileSystem* pFileSystem = CDiskFileSystem::GetInstance(); if(CString::CharOfString(sLibName, '/') || CString::CharOfString(sLibName, '\\')) { if(!pFileSystem->GetFullPath(sLibName, sLibName2)) { FocpLog(bTry?FOCP_LOG_WARNING:FOCP_LOG_ERROR, ("Load(%s) failure", sLibName)); return NULL; } } else { const char* sPrefixName,* sPostfixName; #if defined(WINDOWS)// || defined(CYGWIN_NT) sPrefixName = NULL; sPostfixName = ".dll"; #elif defined(CYGWIN_NT) sPrefixName = "cyg"; sPostfixName = ".dll"; #else sPrefixName = "lib"; sPostfixName = ".so"; #endif if(!pFileSystem->SearchFile("FOCP_LIBRARY_PATH", sLibName, sLibName2, sPrefixName, sPostfixName)) { FocpLog(bTry?FOCP_LOG_WARNING:FOCP_LOG_ERROR, ("Load(%s) failure", sLibName)); return NULL; } } } CShareLibrary* pLib = NULL; CRbTreeNode* pEnd = m_oLibs.End(); m_oMutex.Enter(); CRbTreeNode* pIt = m_oLibs.Find(sLibName2); if(pIt != pEnd) { pLib = m_oLibs.GetItem(pIt); pLib->AddRef(); } else { pLib = new CShareLibrary(); if(!pLib->Load(sLibName2, bTry)) { delete pLib; pLib = NULL; } m_oLibs.Insert(pLib); } m_oMutex.Leave(); return pLib; }
CMdb::~CMdb() { g_oMdbMutex.Enter(); m_oMdbTable.Remove(m_sDbName); g_oMdbMutex.Leave(); }
/// Returns the number of messages currently in the buffer. /// /// @return the number of messages size_t CFudgeMsgInfo::GetBufferCount () { g_oMutex.Enter (); size_t count = g_oMap.size (); g_oMutex.Leave (); return count; }
void CMdb::CreateCppCode() { char sHppFile[256]; char sCppFile[256]; CFormatFile oHppFile; CFormatFile oCppFile; CRbTreeNode* pEnd = m_oMdbTable.End(); g_oMdbMutex.Enter(); CRbTreeNode* pIt = m_oMdbTable.First(); for(; pIt!=pEnd; pIt=m_oMdbTable.GetNext(pIt)) { CMdb* pMdb = m_oMdbTable.GetItem(pIt); const char* sMdbName = pMdb->GetDbName(); CString oUpperMdbName(sMdbName); oUpperMdbName.ToUpper(); StringPrint(sHppFile, "Mdb%s.hpp", sMdbName); StringPrint(sCppFile, "Mdb%s.cpp", sMdbName); oHppFile.Open(sHppFile, "wcd"); oCppFile.Open(sCppFile, "wcd"); oHppFile.SetLineBuf(false); oCppFile.SetLineBuf(false); oHppFile.Print("\n"); oHppFile.Print("#include \"MdbApi.hpp\"\n"); oHppFile.Print("\n"); oHppFile.Print("#ifndef _MDB_%s_HPP_\n", oUpperMdbName.GetStr()); oHppFile.Print("#define _MDB_%s_HPP_\n", oUpperMdbName.GetStr()); oHppFile.Print("\n"); oHppFile.Print("#define MDB_%s_BEGIN() namespace MDB_%s{\n", oUpperMdbName.GetStr(), oUpperMdbName.GetStr()); oHppFile.Print("#define MDB_%s_END() }\n", oUpperMdbName.GetStr()); oHppFile.Print("\n"); oHppFile.Print("FOCP_BEGIN();\n"); oHppFile.Print("MDB_%s_BEGIN();\n", oUpperMdbName.GetStr()); oHppFile.Print("\n"); oCppFile.Print("\n"); oCppFile.Print("#include \"Mdb%s.hpp\"\n", sMdbName); oCppFile.Print("\n"); oCppFile.Print("FOCP_BEGIN();\n"); oCppFile.Print("MDB_%s_BEGIN();\n", oUpperMdbName.GetStr()); oCppFile.Print("\n"); CString oTabList(pMdb->GetTableList()); char *pShift, *sTableName = (char*)oTabList.GetStr(); while(sTableName) { pShift = (char*)CString::CharOfString(sTableName, ','); if(pShift) pShift[0] = 0; CMdbTableDef* pTabDef = pMdb->GetTableDefine(sTableName); CreateTableHppCode(sMdbName, pTabDef, oHppFile); CreateTableCppCode(sMdbName, pTabDef, oCppFile); sTableName = pShift; if(sTableName) { sTableName[0] = ','; ++sTableName; } } oHppFile.Print("\n"); oHppFile.Print("MDB_%s_END();\n", oUpperMdbName.GetStr()); oHppFile.Print("FOCP_END();\n"); oHppFile.Print("\n"); oHppFile.Print("#endif\n"); oHppFile.Print("\n"); oCppFile.Print("\n"); oCppFile.Print("MDB_%s_END();\n", oUpperMdbName.GetStr()); oCppFile.Print("FOCP_END();\n"); oCppFile.Print("\n"); oHppFile.Close(); oCppFile.Close(); } g_oMdbMutex.Leave(); }