Browse Source

fix im thread module. poll klasse hinzugefügt.

Rind 4 years ago
parent
commit
c041c643aa
5 changed files with 250 additions and 5 deletions
  1. 1 1
      gfasysinfo/src/spiinfo.h
  2. 0 1
      gfasysinfo/src/stgdevinfo.cpp
  3. 187 0
      src/pollf.cpp
  4. 53 0
      src/pollf.h
  5. 9 3
      src/thread.cpp

+ 1 - 1
gfasysinfo/src/spiinfo.h

@@ -7,7 +7,7 @@
 #include <gfa/gfaipc.h>
 #include <gfa/ipcpriv.h>
 #include <gfa/thread.h>
-#include "../../../gfaspidrv/gfaspi.h"
+#include <gfa/gfaspi.h>
 
 /////////////////////////////////////////////////////////////////////////////
 // spiinfo.h - Declarations:

+ 0 - 1
gfasysinfo/src/stgdevinfo.cpp

@@ -1,6 +1,5 @@
 #include <stdio.h>
 #include <stdio.h>
-#include <unistd.h>
 #include <string.h>
 #include <string>
 #include <vector>

+ 187 - 0
src/pollf.cpp

@@ -0,0 +1,187 @@
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <errno.h>
+#include "pollf.h"
+#include "defines.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+static CPollF g_pof;
+
+/////////////////////////////////////////////////////////////////////////////
+
+CPollF::CPollF(void) : m_bThreadExecuting(false), m_nNextJobID(0), m_mtx(PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP)
+{
+}
+
+CPollF::~CPollF(void)
+{
+	if(m_bThreadExecuting)
+	{
+	}
+
+	::pthread_mutex_destroy(&m_mtx);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+pjob_t CPollF::AddJob(const char *pszFilepath, int nEvents, PFN_POLLF_CALLBACK pfnCb, void *pParam)
+{
+	return g_pof.CreateJob(pszFilepath, nEvents, pfnCb, pParam);
+}
+
+int CPollF::CancelJob(pjob_t nJobID)
+{
+	return g_pof.ReleaseJob(nJobID);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+pjob_t CPollF::CreateJob(const char *pszFilepath, int nEvents, PFN_POLLF_CALLBACK pfnCb, void *pParam)
+{
+	if(!pszFilepath || !*pszFilepath || !pfnCb)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+
+	int fd = open(pszFilepath, O_RDONLY, 0);
+	
+	if(fd < 0)
+		return -1;
+	
+	int nJobID = ++m_nNextJobID;
+	m_nNextJobID &= 0x7FFFFFFF;
+
+	LPPOLLFJOB pJob = new POLLFJOB;
+	pJob->nJobID	= nJobID;
+	pJob->fd		= fd;
+	pJob->events	= nEvents;
+	pJob->pfnCb		= pfnCb;
+	pJob->pParam	= pParam;
+
+	::pthread_mutex_lock(&m_mtx);
+	m_jobs.push_back(pJob);
+	::pthread_mutex_unlock(&m_mtx);
+
+	if(!m_bThreadExecuting)
+	{
+		if(m_thread.Create(&CPollF::PollThreadRoutine, reinterpret_cast<void*>(this)) < 0)
+		{
+			close(fd);
+			delete pJob;
+			return -1;
+		}
+
+		::pthread_mutex_lock(&m_mtx);
+		m_bThreadExecuting = true;
+		::pthread_mutex_unlock(&m_mtx);
+	}
+	else
+	{
+	}
+
+	return nJobID;
+}
+
+int CPollF::ReleaseJob(pjob_t nJobID)
+{
+	UNUSED(nJobID);
+	::pthread_mutex_lock(&m_mtx);
+	::pthread_mutex_unlock(&m_mtx);
+	return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+LPPOLLFJOB CPollF::FindByFileDescriptor(int fd)
+{
+	for(auto it = m_jobs.begin(); it != m_jobs.end(); ++it)
+	{
+		LPPOLLFJOB pjob = *it;
+		if(pjob->fd == fd)
+			return pjob;
+	}
+	return NULL;
+}
+
+LPPOLLFJOB CPollF::FindByJobID(pjob_t jid)
+{
+	for(auto it = m_jobs.begin(); it != m_jobs.end(); ++it)
+	{
+		LPPOLLFJOB pjob = *it;
+		if(pjob->nJobID == jid)
+			return pjob;
+	}
+	return NULL;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+void* CPollF::PollThreadRoutine(void *pParam)
+{
+	int ret;
+	bool bRun = true;
+	CPollF *pThis = reinterpret_cast<CPollF*>(pParam);
+
+	while(bRun)
+	{
+		struct pollfd *pfd = NULL;
+
+		::pthread_mutex_lock(&pThis->m_mtx);
+		auto nSize = pThis->m_jobs.size();
+		pfd = new struct pollfd[nSize];
+		memset(pfd, 0, sizeof(struct pollfd) * nSize);
+
+		for(size_t i = 0; i < nSize; ++i)
+		{
+			const POLLFJOB &job = *pThis->m_jobs[i];
+			pfd[i].fd		= job.fd;
+			pfd[i].events	= (short)job.events;
+		}
+		::pthread_mutex_unlock(&pThis->m_mtx);
+
+		if((ret = ::poll(pfd, nSize, -1)) >= 0)
+		{
+			for(size_t i = 0; i < nSize; ++i)
+			{
+				int evt;
+				LPCPOLLFJOB pJob;
+				const struct pollfd &rpfd = pfd[i];
+				
+				if(!rpfd.revents)
+					continue;
+
+				::pthread_mutex_lock(&pThis->m_mtx);
+				if((pJob = pThis->FindByFileDescriptor(rpfd.fd)))
+				{
+					if(rpfd.revents & (POLLERR | POLLHUP | POLLNVAL))
+					{
+						pThis->ReleaseJob(pJob->nJobID);
+						(*pJob->pfnCb)(pJob->nJobID, -1, rpfd.revents, pJob->pParam);
+					}
+					else if((evt = rpfd.revents & (short)pJob->events))
+					{
+						(*pJob->pfnCb)(pJob->nJobID, pJob->fd, evt, pJob->pParam);
+					}
+				}
+				::pthread_mutex_unlock(&pThis->m_mtx);
+
+				if(!--ret)
+					break;
+			}
+		}
+		else
+		{
+			if(errno == EINTR)
+			{
+			}
+		}
+
+		delete pfd;
+	}
+
+	return NULL;
+}

+ 53 - 0
src/pollf.h

@@ -0,0 +1,53 @@
+// pollf.h :
+//
+
+#if !defined(AGD_POLLF_H__7DB9BF9A_25FD_41FB_8CD2_1FD9CC8FA6F1__INCLUDED_)
+#define AGD_POLLF_H__7DB9BF9A_25FD_41FB_8CD2_1FD9CC8FA6F1__INCLUDED_
+
+#include <vector>
+#include <poll.h>
+#include "thread.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// pollf.h - Declarations:
+
+typedef int pjob_t;
+typedef void (*PFN_POLLF_CALLBACK)(int /*cookie*/, int /*fd*/, int /*events*/, void* /*pParam*/);
+
+typedef struct _POLLFJOB
+{
+	pjob_t nJobID;
+	int fd;
+	int events;
+	PFN_POLLF_CALLBACK pfnCb;
+	void *pParam;
+}POLLFJOB, *LPPOLLFJOB;
+typedef const POLLFJOB *LPCPOLLFJOB;
+
+/////////////////////////////////////////////////////////////////////////////
+
+class CPollF
+{
+public:
+	CPollF(void);
+	~CPollF(void);
+	static pjob_t AddJob(const char *pszFilepath, int nEvents, PFN_POLLF_CALLBACK pfnCb, void *pParam);
+	static int CancelJob(pjob_t nJobID);
+
+private:
+	static void* PollThreadRoutine(void *pParam);
+	pjob_t CreateJob(const char *pszFilepath, int nEvents, PFN_POLLF_CALLBACK pfnCb, void *pParam);
+	int ReleaseJob(pjob_t nJobID);
+	LPPOLLFJOB FindByFileDescriptor(int fd);
+	LPPOLLFJOB FindByJobID(pjob_t jid);
+
+private:
+	bool m_bThreadExecuting;
+	CThread m_thread;
+	std::vector<LPPOLLFJOB> m_jobs;
+	pjob_t m_nNextJobID;
+	pthread_mutex_t m_mtx;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+#endif	//	!defined(AGD_POLLF_H__7DB9BF9A_25FD_41FB_8CD2_1FD9CC8FA6F1__INCLUDED_)

+ 9 - 3
src/thread.cpp

@@ -43,17 +43,23 @@ int CThread::Create(void *pParam)
 
 int CThread::Cancel(void)
 {
-	return ::pthread_cancel(m_tID);
+    if(m_tID != 0)
+        return ::pthread_cancel(m_tID);
+    return -1;
 }
 
 int CThread::Join(void **ppRetval)
 {
-	return ::pthread_join(m_tID, ppRetval);
+    if(m_tID != 0)
+        return ::pthread_join(m_tID, ppRetval);
+    return -1;
 }
 
 int CThread::Detach(void)
 {
-	return ::pthread_detach(m_tID);
+    if(m_tID != 0)
+        return ::pthread_detach(m_tID);
+    return -1;
 }
 
 int CThread::WaitSignal(int *pSignal)