Fixed BSD unblockPollSocket(). Was signaling to break out of

poll() but there was a race condition where the thread trying
to unblock poll() could send the signal before the polling
thread had entered poll().  Now using a pipe and polling on
that and the client's sockets, and just writing a byte into
the pipe to unblock poll.  This persists until the next call
to poll() so we might force poll() to return once unnecessarily
but that's not a problem.  This change makes the BSD code
similar to the winsock code, which uses a winsock event instead
of a pipe.
This commit is contained in:
crs
2004-02-29 16:48:22 +00:00
parent d6ec331b09
commit 1ccb92b888
4 changed files with 203 additions and 110 deletions

View File

@@ -69,6 +69,7 @@ public:
bool m_cancelling;
bool m_exited;
void* m_result;
void* m_networkData;
};
CArchThreadImpl::CArchThreadImpl() :
@@ -79,7 +80,8 @@ CArchThreadImpl::CArchThreadImpl() :
m_cancel(false),
m_cancelling(false),
m_exited(false),
m_result(NULL)
m_result(NULL),
m_networkData(NULL)
{
// do nothing
}
@@ -149,9 +151,21 @@ CArchMultithreadPosix::~CArchMultithreadPosix()
}
void
CArchMultithreadPosix::unblockThread(CArchThread thread)
CArchMultithreadPosix::setNetworkDataForCurrentThread(void* data)
{
pthread_kill(thread->m_thread, SIGWAKEUP);
lockMutex(m_threadMutex);
CArchThreadImpl* thread = find(pthread_self());
thread->m_networkData = data;
unlockMutex(m_threadMutex);
}
void*
CArchMultithreadPosix::getNetworkDataForThread(CArchThread thread)
{
lockMutex(m_threadMutex);
void* data = thread->m_networkData;
unlockMutex(m_threadMutex);
return data;
}
CArchMultithreadPosix*
@@ -579,7 +593,7 @@ CArchMultithreadPosix::raiseSignal(ESignal signal)
lockMutex(m_threadMutex);
if (m_signalFunc[signal] != NULL) {
m_signalFunc[signal](signal, m_signalUserData[signal]);
unblockThread(m_mainThread);
pthread_kill(m_mainThread->m_thread, SIGWAKEUP);
}
else if (signal == kINTERRUPT || signal == kTERMINATE) {
ARCH->cancelThread(m_mainThread);