barrier/lib/arch/CArchMultithreadPosix.h
crs 1ccb92b888 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.
2004-02-29 16:48:22 +00:00

114 lines
3.1 KiB
C++

/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2002 Chris Schoeneman
*
* This package is free software you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file COPYING that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef CARCHMULTITHREADPOSIX_H
#define CARCHMULTITHREADPOSIX_H
#include "IArchMultithread.h"
#include "stdlist.h"
#include <pthread.h>
#define ARCH_MULTITHREAD CArchMultithreadPosix
class CArchCondImpl {
public:
pthread_cond_t m_cond;
};
class CArchMutexImpl {
public:
pthread_mutex_t m_mutex;
};
//! Posix implementation of IArchMultithread
class CArchMultithreadPosix : public IArchMultithread {
public:
CArchMultithreadPosix();
virtual ~CArchMultithreadPosix();
//! @name manipulators
//@{
void setNetworkDataForCurrentThread(void*);
//@}
//! @name accessors
//@{
void* getNetworkDataForThread(CArchThread);
static CArchMultithreadPosix* getInstance();
//@}
// IArchMultithread overrides
virtual CArchCond newCondVar();
virtual void closeCondVar(CArchCond);
virtual void signalCondVar(CArchCond);
virtual void broadcastCondVar(CArchCond);
virtual bool waitCondVar(CArchCond, CArchMutex, double timeout);
virtual CArchMutex newMutex();
virtual void closeMutex(CArchMutex);
virtual void lockMutex(CArchMutex);
virtual void unlockMutex(CArchMutex);
virtual CArchThread newThread(ThreadFunc, void*);
virtual CArchThread newCurrentThread();
virtual CArchThread copyThread(CArchThread);
virtual void closeThread(CArchThread);
virtual void cancelThread(CArchThread);
virtual void setPriorityOfThread(CArchThread, int n);
virtual void testCancelThread();
virtual bool wait(CArchThread, double timeout);
virtual bool isSameThread(CArchThread, CArchThread);
virtual bool isExitedThread(CArchThread);
virtual void* getResultOfThread(CArchThread);
virtual ThreadID getIDOfThread(CArchThread);
virtual void setSignalHandler(ESignal, SignalFunc, void*);
virtual void raiseSignal(ESignal);
private:
void startSignalHandler();
CArchThreadImpl* find(pthread_t thread);
CArchThreadImpl* findNoRef(pthread_t thread);
void insert(CArchThreadImpl* thread);
void erase(CArchThreadImpl* thread);
void refThread(CArchThreadImpl* rep);
void testCancelThreadImpl(CArchThreadImpl* rep);
void doThreadFunc(CArchThread thread);
static void* threadFunc(void* vrep);
static void threadCancel(int);
static void* threadSignalHandler(void* vrep);
private:
typedef std::list<CArchThread> CThreadList;
static CArchMultithreadPosix* s_instance;
bool m_newThreadCalled;
CArchMutex m_threadMutex;
CArchThread m_mainThread;
CThreadList m_threadList;
ThreadID m_nextID;
pthread_t m_signalThread;
SignalFunc m_signalFunc[kNUM_SIGNALS];
void* m_signalUserData[kNUM_SIGNALS];
};
#endif