Browse Source

Unterstützung für das Blockieren von Signalen beim Locken eines globalen Mutex

Rind 3 years ago
parent
commit
8029b74b76
9 changed files with 165 additions and 14 deletions
  1. 9 0
      gfasysinfo/src/procfile.cpp
  2. 30 7
      src/appctrl.cpp
  3. 4 0
      src/appctrl.h
  4. 7 1
      src/gfaipc.h
  5. 56 4
      src/ipcshm.cpp
  6. 40 1
      src/mutex.cpp
  7. 6 0
      src/mutex.h
  8. 11 1
      src/shm.cpp
  9. 2 0
      src/shm.h

+ 9 - 0
gfasysinfo/src/procfile.cpp

@@ -46,6 +46,9 @@ std::string CProcFile::FormatString(const char *fmt, ...)
 	return s;
 	return s;
 }
 }
 
 
+/////////////////////////////////////////////////////////////////////////////
+//
+
 int CProcFile::SplitLine(const std::string &str, std::vector<std::string> &vec, const char *rxe)
 int CProcFile::SplitLine(const std::string &str, std::vector<std::string> &vec, const char *rxe)
 {
 {
 	if(str.empty())
 	if(str.empty())
@@ -64,6 +67,9 @@ int CProcFile::SplitLine(const std::string &str, std::vector<std::string> &vec,
 	return nElems;
 	return nElems;
 }
 }
 
 
+/////////////////////////////////////////////////////////////////////////////
+//
+
 long long CProcFile::StrToIntegral(const std::string &str, long long nDefault, int nBase)
 long long CProcFile::StrToIntegral(const std::string &str, long long nDefault, int nBase)
 {
 {
 	if(str.empty())
 	if(str.empty())
@@ -78,6 +84,9 @@ long long CProcFile::StrToIntegral(const std::string &str, long long nDefault, i
 	return val;
 	return val;
 }
 }
 
 
+/////////////////////////////////////////////////////////////////////////////
+//
+
 double CProcFile::StrToReal(const std::string &str, double fDefault)
 double CProcFile::StrToReal(const std::string &str, double fDefault)
 {
 {
 	if(str.empty())
 	if(str.empty())

+ 30 - 7
src/appctrl.cpp

@@ -85,7 +85,9 @@ CAppCtrl::CAppCtrl(void) :	m_pAppCtrl(NULL),
 							m_nSlotIdx(_INVALID_SLOT_INDEX),
 							m_nSlotIdx(_INVALID_SLOT_INDEX),
 							m_nAppID(0),
 							m_nAppID(0),
 							m_nLockCount(0),
 							m_nLockCount(0),
-							m_nLastTimesCallUs(0)
+							m_nLastTimesCallUs(0),
+							m_pfnLockSHM(::GfaIpcLockSHM),
+							m_pfnUnlockSHM(::GfaIpcUnlockSHM)
 {
 {
 	struct timespec	ts;
 	struct timespec	ts;
 	::clock_gettime(CLOCK_MONOTONIC, &ts);
 	::clock_gettime(CLOCK_MONOTONIC, &ts);
@@ -1397,9 +1399,7 @@ void CAppCtrl::Lock(void)
 	if(m_hShm)
 	if(m_hShm)
 	{
 	{
 		if(::GfaIpcInterlockedIncrement(m_hShm, &m_nLockCount) == 1)
 		if(::GfaIpcInterlockedIncrement(m_hShm, &m_nLockCount) == 1)
-		{
-			::GfaIpcLockSHM(m_hShm);
-		}
+			(*m_pfnLockSHM)(m_hShm);
 	}
 	}
 }
 }
 
 
@@ -1408,9 +1408,21 @@ void CAppCtrl::Unlock(void)
 	if(m_hShm)
 	if(m_hShm)
 	{
 	{
 		if(::GfaIpcInterlockedDecrement(m_hShm, &m_nLockCount) == 0)
 		if(::GfaIpcInterlockedDecrement(m_hShm, &m_nLockCount) == 0)
-		{
-			::GfaIpcUnlockSHM(m_hShm);
-		}
+			(*m_pfnUnlockSHM)(m_hShm);
+	}
+}
+
+void CAppCtrl::SetLockUnlockFunctions(PFN_GFA_IPC_LOCK_SHM pfnLockSHM, PFN_GFA_IPC_UNLOCK_SHM pfnUnlockSHM)
+{
+	if(pfnLockSHM && pfnUnlockSHM)
+	{
+		m_pfnLockSHM = pfnLockSHM;
+		m_pfnUnlockSHM = pfnUnlockSHM;
+	}
+	else
+	{
+		m_pfnLockSHM = ::GfaIpcLockSHM;
+		m_pfnUnlockSHM = ::GfaIpcUnlockSHM;
 	}
 	}
 }
 }
 
 
@@ -1776,6 +1788,17 @@ bool GfaIpcAppCtrlKillApp(HAPPCTRL hAC, appid_t nAppID)
 	return false;
 	return false;
 }
 }
 
 
+bool GfaIpcAppCtrlSetLockUnlockFunctions(HAPPCTRL hAC, PFN_GFA_IPC_LOCK_SHM pfnLockSHM, PFN_GFA_IPC_UNLOCK_SHM pfnUnlockSHM)
+{
+	CAppCtrl *p = reinterpret_cast<CAppCtrl*>(hAC);
+	if(p)
+	{
+		p->SetLockUnlockFunctions(pfnLockSHM, pfnUnlockSHM);
+		return true;
+	}
+	return false;
+}
+
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////

+ 4 - 0
src/appctrl.h

@@ -172,6 +172,8 @@ public:
 	
 	
 	bool KillApp(appid_t nAppID);
 	bool KillApp(appid_t nAppID);
 
 
+	void SetLockUnlockFunctions(PFN_GFA_IPC_LOCK_SHM pfnLockSHM, PFN_GFA_IPC_UNLOCK_SHM pfnUnlockSHM);
+
 private:
 private:
 	int SlotIndexFromAppID(appid_t nAppID);
 	int SlotIndexFromAppID(appid_t nAppID);
 	void AppStateChanged(appid_t nAppID, GfaIpcAppStates oldState, GfaIpcAppStates newState);
 	void AppStateChanged(appid_t nAppID, GfaIpcAppStates oldState, GfaIpcAppStates newState);
@@ -193,6 +195,8 @@ private:
 	clock64_t m_nLastTimesCallUs;
 	clock64_t m_nLastTimesCallUs;
 	CProcMem m_procMem;
 	CProcMem m_procMem;
 	CSysInfo m_sysInfo;
 	CSysInfo m_sysInfo;
+	PFN_GFA_IPC_LOCK_SHM m_pfnLockSHM;
+	PFN_GFA_IPC_UNLOCK_SHM m_pfnUnlockSHM;
 };
 };
 
 
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////

+ 7 - 1
src/gfaipc.h

@@ -18,7 +18,9 @@ extern "C" {
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
 // gfaipc.h - Declarations:
 // gfaipc.h - Declarations:
 
 
-typedef void				*HSHM;
+typedef void							*HSHM;
+typedef void (*PFN_GFA_IPC_LOCK_SHM)	(HSHM);
+typedef void (*PFN_GFA_IPC_UNLOCK_SHM)	(HSHM);
 
 
 HSHM	GfaIpcAcquireSHM	(const char *pszUuid, size_t nSizeElement, size_t nCntElements, const char *pszDescName);
 HSHM	GfaIpcAcquireSHM	(const char *pszUuid, size_t nSizeElement, size_t nCntElements, const char *pszDescName);
 void	GfaIpcReleaseSHM	(HSHM hShm);
 void	GfaIpcReleaseSHM	(HSHM hShm);
@@ -26,6 +28,9 @@ void*	GfaIpcAcquirePointer(HSHM hShm);
 void	GfaIpcReleasePointer(HSHM hShm, const void *p);
 void	GfaIpcReleasePointer(HSHM hShm, const void *p);
 void	GfaIpcLockSHM		(HSHM hShm);
 void	GfaIpcLockSHM		(HSHM hShm);
 void	GfaIpcUnlockSHM		(HSHM hShm);
 void	GfaIpcUnlockSHM		(HSHM hShm);
+int		GfaIpcLockSHMAndSigBlock	(HSHM hShm, sigset_t *pss);
+int		GfaIpcUnlockSHMAndSigUnblock(HSHM hShm, sigset_t *pss);
+
 void	GfaIpcDumpSHMROT	(void);
 void	GfaIpcDumpSHMROT	(void);
 
 
 long	GfaIpcInterlockedIncrement(HSHM hShm, volatile long *pl);
 long	GfaIpcInterlockedIncrement(HSHM hShm, volatile long *pl);
@@ -431,6 +436,7 @@ bool			GfaIpcAppCtrlGetDbInfo				(HAPPCTRL hAC, LPGFA_SYSINFO_DATABASE psdb);
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
 
 
 bool			GfaIpcAppCtrlKillApp				(HAPPCTRL hAC, appid_t nAppID);
 bool			GfaIpcAppCtrlKillApp				(HAPPCTRL hAC, appid_t nAppID);
+bool			GfaIpcAppCtrlSetLockUnlockFunctions	(HAPPCTRL hAC, PFN_GFA_IPC_LOCK_SHM pfnLockSHM, PFN_GFA_IPC_UNLOCK_SHM pfnUnlockSHM);
 
 
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////

+ 56 - 4
src/ipcshm.cpp

@@ -76,6 +76,16 @@ CShm* CShmHandleMap::LookupShm(const uuid_t &uuid)
 static CShmROT g_shmRot;
 static CShmROT g_shmRot;
 static CShmHandleMap g_shmHandleMap;
 static CShmHandleMap g_shmHandleMap;
 
 
+__attribute__ ((constructor)) void _OnSoLoad(void)
+{
+	TRACE("Loading Module GfaIpc.\n");
+}
+
+__attribute__ ((destructor)) void _OnSoUnload(void)
+{
+	TRACE("Unloading Module GfaIpc.\n");
+}
+
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
 
 
 void GfaIpcForceReleaseMutex(void)
 void GfaIpcForceReleaseMutex(void)
@@ -180,7 +190,7 @@ void GfaIpcLockSHM(HSHM hShm)
 {
 {
 	if(!hShm)
 	if(!hShm)
 	{
 	{
-		TRACE("GfaIpcReleasePointer: Invalid Handle!\n");
+		TRACE("GfaIpcLockSHM: Invalid Handle!\n");
 		return;
 		return;
 	}
 	}
 
 
@@ -188,7 +198,7 @@ void GfaIpcLockSHM(HSHM hShm)
 
 
 	if(!ph->pShm)
 	if(!ph->pShm)
 	{
 	{
-		TRACE("GfaIpcReleasePointer: Invalid Handle!\n");
+		TRACE("GfaIpcLockSHM: Invalid Handle!\n");
 		return;
 		return;
 	}
 	}
 
 
@@ -201,7 +211,7 @@ void GfaIpcUnlockSHM(HSHM hShm)
 {
 {
 	if(!hShm)
 	if(!hShm)
 	{
 	{
-		TRACE("GfaIpcReleasePointer: Invalid Handle!\n");
+		TRACE("GfaIpcUnlockSHM: Invalid Handle!\n");
 		return;
 		return;
 	}
 	}
 
 
@@ -209,7 +219,7 @@ void GfaIpcUnlockSHM(HSHM hShm)
 
 
 	if(!ph->pShm)
 	if(!ph->pShm)
 	{
 	{
-		TRACE("GfaIpcReleasePointer: Invalid Handle!\n");
+		TRACE("GfaIpcUnlockSHM: Invalid Handle!\n");
 		return;
 		return;
 	}
 	}
 
 
@@ -218,6 +228,48 @@ void GfaIpcUnlockSHM(HSHM hShm)
 
 
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
 
 
+int GfaIpcLockSHMAndSigBlock(HSHM hShm, sigset_t *pss)
+{
+	if(!hShm)
+	{
+		TRACE("GfaIpcLockSHMAndSigBlock: Invalid Handle!\n");
+		return 0;
+	}
+
+	LPSHM_HANDLE ph = (LPSHM_HANDLE)hShm;
+
+	if(!ph->pShm)
+	{
+		TRACE("GfaIpcLockSHMAndSigBlock: Invalid Handle!\n");
+		return 0;
+	}
+
+	return ph->pShm->LockAndSigBlock(pss);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+int GfaIpcUnlockSHMAndSigUnblock(HSHM hShm, sigset_t *pss)
+{
+	if(!hShm)
+	{
+		TRACE("GfaIpcLockSHMAndSigBlock: Invalid Handle!\n");
+		return 0;
+	}
+
+	LPSHM_HANDLE ph = (LPSHM_HANDLE)hShm;
+
+	if(!ph->pShm)
+	{
+		TRACE("GfaIpcLockSHMAndSigBlock: Invalid Handle!\n");
+		return 0;
+	}
+
+	return ph->pShm->UnlockAndSigUnblock(pss);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
 void GfaIpcDumpSHMROT(void)
 void GfaIpcDumpSHMROT(void)
 {
 {
 	if(!g_shmRot.Created())
 	if(!g_shmRot.Created())

+ 40 - 1
src/mutex.cpp

@@ -29,7 +29,7 @@
 
 
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
 
 
-CGlobalMutex::CGlobalMutex(void) :	m_nShmID(_INVALID_ID), m_pMutex(NULL)
+CGlobalMutex::CGlobalMutex(void) :	m_nShmID(_INVALID_ID), m_nSigRefCount(0), m_pMutex(NULL)
 {
 {
 	memset(&m_mutexAttr, 0, sizeof(m_mutexAttr));
 	memset(&m_mutexAttr, 0, sizeof(m_mutexAttr));
 	::pthread_mutexattr_init(&m_mutexAttr);
 	::pthread_mutexattr_init(&m_mutexAttr);
@@ -220,3 +220,42 @@ bool CGlobalMutex::Unlock(void)
 		return false;
 		return false;
 	}
 	}
 }
 }
+
+bool CGlobalMutex::LockAndSigBlock(sigset_t *pss)
+{
+	if(m_pMutex && pss)
+	{
+		if(m_nSigRefCount++ == 0)
+		{
+			::sigprocmask(SIG_BLOCK, pss, NULL);
+//			TRACE("Block: %lu\n", ::pthread_self());
+		}
+		return Lock();
+	}
+	else
+	{
+		TRACE("CGlobalMutex::LockAndSigBlock: Invalid Mutex or sigset: %p!\n", pss);
+		errno = EINVAL;
+	}
+	return false;
+}
+
+bool CGlobalMutex::UnlockAndSigUnblock(sigset_t *pss)
+{
+	if(m_pMutex && pss)
+	{
+		bool ret = Unlock();
+		if(--m_nSigRefCount == 0)
+		{
+			::sigprocmask(SIG_UNBLOCK, pss, NULL);
+//			TRACE("Unblock: %lu\n", ::pthread_self());
+		}
+		return ret;
+	}
+	else
+	{
+		TRACE("CGlobalMutex::UnlockAndSigBlock: Invalid Mutex or sigset: %p!\n", pss);
+		errno = EINVAL;
+	}
+	return false;
+}

+ 6 - 0
src/mutex.h

@@ -7,6 +7,8 @@
 #include <inttypes.h>
 #include <inttypes.h>
 #include <stdlib.h>
 #include <stdlib.h>
 #include <pthread.h>
 #include <pthread.h>
+#include <signal.h>
+#include <atomic>
 #include "uuid.h"
 #include "uuid.h"
 
 
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
@@ -35,8 +37,12 @@ public:
 	bool TryLock(void);
 	bool TryLock(void);
 	bool Unlock(void);
 	bool Unlock(void);
 
 
+	bool LockAndSigBlock(sigset_t *pss);
+	bool UnlockAndSigUnblock(sigset_t *pss);
+
 private:
 private:
 	int m_nShmID;
 	int m_nShmID;
+	std::atomic_long m_nSigRefCount;
 	pthread_mutexattr_t m_mutexAttr;
 	pthread_mutexattr_t m_mutexAttr;
 	pthread_mutex_t *m_pMutex;
 	pthread_mutex_t *m_pMutex;
 };
 };

+ 11 - 1
src/shm.cpp

@@ -120,7 +120,7 @@ int CShm::Create(const uuid_t &ruuid, size_t nCbShm, const char *pszDir)
 			}
 			}
 			else
 			else
 			{
 			{
-				TRACE("CShm::Create: Failed to create SHM on Key: 0x%08X - errno: %d!\n", shmKey, errno);
+				TRACE("CShm::Create: Failed to create SHM on Key: 0x%08X - %s!\n", shmKey, strerror(errno));
 			}
 			}
 		}
 		}
 		else
 		else
@@ -285,6 +285,16 @@ int CShm::Unlock(void)
 	return m_mutex.Unlock();
 	return m_mutex.Unlock();
 }
 }
 
 
+int CShm::LockAndSigBlock(sigset_t *pss)
+{
+	return m_mutex.LockAndSigBlock(pss);
+}
+
+int CShm::UnlockAndSigUnblock(sigset_t *pss)
+{
+	return m_mutex.UnlockAndSigUnblock(pss);
+}
+
 long CShm::InterlockedIncrement(volatile long *pl)
 long CShm::InterlockedIncrement(volatile long *pl)
 {
 {
 	if(!pl)
 	if(!pl)

+ 2 - 0
src/shm.h

@@ -48,6 +48,8 @@ public:
 
 
 	int Lock(void);
 	int Lock(void);
 	int Unlock(void);
 	int Unlock(void);
+	int LockAndSigBlock(sigset_t *pss);
+	int UnlockAndSigUnblock(sigset_t *pss);
 
 
 	const uuid_t& Uuid() const {
 	const uuid_t& Uuid() const {
 		return m_uuid;}
 		return m_uuid;}