| 1 | /* | 
|---|
| 2 | * synergy -- mouse and keyboard sharing utility | 
|---|
| 3 | * Copyright (C) 2002 Chris Schoeneman | 
|---|
| 4 | * | 
|---|
| 5 | * This package is free software; you can redistribute it and/or | 
|---|
| 6 | * modify it under the terms of the GNU General Public License | 
|---|
| 7 | * found in the file COPYING that should have accompanied this file. | 
|---|
| 8 | * | 
|---|
| 9 | * This package is distributed in the hope that it will be useful, | 
|---|
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|---|
| 12 | * GNU General Public License for more details. | 
|---|
| 13 | */ | 
|---|
| 14 |  | 
|---|
| 15 | #ifndef IARCHMULTITHREAD_H | 
|---|
| 16 | #define IARCHMULTITHREAD_H | 
|---|
| 17 |  | 
|---|
| 18 | #include "IInterface.h" | 
|---|
| 19 |  | 
|---|
| 20 | /*! | 
|---|
| 21 | \class CArchCondImpl | 
|---|
| 22 | \brief Internal condition variable data. | 
|---|
| 23 | An architecture dependent type holding the necessary data for a | 
|---|
| 24 | condition variable. | 
|---|
| 25 | */ | 
|---|
| 26 | class CArchCondImpl; | 
|---|
| 27 |  | 
|---|
| 28 | /*! | 
|---|
| 29 | \var CArchCond | 
|---|
| 30 | \brief Opaque condition variable type. | 
|---|
| 31 | An opaque type representing a condition variable. | 
|---|
| 32 | */ | 
|---|
| 33 | typedef CArchCondImpl* CArchCond; | 
|---|
| 34 |  | 
|---|
| 35 | /*! | 
|---|
| 36 | \class CArchMutexImpl | 
|---|
| 37 | \brief Internal mutex data. | 
|---|
| 38 | An architecture dependent type holding the necessary data for a mutex. | 
|---|
| 39 | */ | 
|---|
| 40 | class CArchMutexImpl; | 
|---|
| 41 |  | 
|---|
| 42 | /*! | 
|---|
| 43 | \var CArchMutex | 
|---|
| 44 | \brief Opaque mutex type. | 
|---|
| 45 | An opaque type representing a mutex. | 
|---|
| 46 | */ | 
|---|
| 47 | typedef CArchMutexImpl* CArchMutex; | 
|---|
| 48 |  | 
|---|
| 49 | /*! | 
|---|
| 50 | \class CArchThreadImpl | 
|---|
| 51 | \brief Internal thread data. | 
|---|
| 52 | An architecture dependent type holding the necessary data for a thread. | 
|---|
| 53 | */ | 
|---|
| 54 | class CArchThreadImpl; | 
|---|
| 55 |  | 
|---|
| 56 | /*! | 
|---|
| 57 | \var CArchThread | 
|---|
| 58 | \brief Opaque thread type. | 
|---|
| 59 | An opaque type representing a thread. | 
|---|
| 60 | */ | 
|---|
| 61 | typedef CArchThreadImpl* CArchThread; | 
|---|
| 62 |  | 
|---|
| 63 | //! Interface for architecture dependent multithreading | 
|---|
| 64 | /*! | 
|---|
| 65 | This interface defines the multithreading operations required by | 
|---|
| 66 | synergy.  Each architecture must implement this interface. | 
|---|
| 67 | */ | 
|---|
| 68 | class IArchMultithread : public IInterface { | 
|---|
| 69 | public: | 
|---|
| 70 | //! Type of thread entry point | 
|---|
| 71 | typedef void* (*ThreadFunc)(void*); | 
|---|
| 72 | //! Type of thread identifier | 
|---|
| 73 | typedef unsigned int ThreadID; | 
|---|
| 74 | //! Types of signals | 
|---|
| 75 | /*! | 
|---|
| 76 | Not all platforms support all signals.  Unsupported signals are | 
|---|
| 77 | ignored. | 
|---|
| 78 | */ | 
|---|
| 79 | enum ESignal { | 
|---|
| 80 | kINTERRUPT,             //!< Interrupt (e.g. Ctrl+C) | 
|---|
| 81 | kTERMINATE,             //!< Terminate (e.g. Ctrl+Break) | 
|---|
| 82 | kHANGUP,                //!< Hangup (SIGHUP) | 
|---|
| 83 | kUSER,                  //!< User (SIGUSR2) | 
|---|
| 84 | kNUM_SIGNALS | 
|---|
| 85 | }; | 
|---|
| 86 | //! Type of signal handler function | 
|---|
| 87 | typedef void            (*SignalFunc)(ESignal, void* userData); | 
|---|
| 88 |  | 
|---|
| 89 | //! @name manipulators | 
|---|
| 90 | //@{ | 
|---|
| 91 |  | 
|---|
| 92 | // | 
|---|
| 93 | // condition variable methods | 
|---|
| 94 | // | 
|---|
| 95 |  | 
|---|
| 96 | //! Create a condition variable | 
|---|
| 97 | /*! | 
|---|
| 98 | The condition variable is an opaque data type. | 
|---|
| 99 | */ | 
|---|
| 100 | virtual CArchCond       newCondVar() = 0; | 
|---|
| 101 |  | 
|---|
| 102 | //! Destroy a condition variable | 
|---|
| 103 | virtual void            closeCondVar(CArchCond) = 0; | 
|---|
| 104 |  | 
|---|
| 105 | //! Signal a condition variable | 
|---|
| 106 | /*! | 
|---|
| 107 | Signalling a condition variable releases one waiting thread. | 
|---|
| 108 | */ | 
|---|
| 109 | virtual void            signalCondVar(CArchCond) = 0; | 
|---|
| 110 |  | 
|---|
| 111 | //! Broadcast a condition variable | 
|---|
| 112 | /*! | 
|---|
| 113 | Broadcasting a condition variable releases all waiting threads. | 
|---|
| 114 | */ | 
|---|
| 115 | virtual void            broadcastCondVar(CArchCond) = 0; | 
|---|
| 116 |  | 
|---|
| 117 | //! Wait on a condition variable | 
|---|
| 118 | /*! | 
|---|
| 119 | Wait on a conditation variable for up to \c timeout seconds. | 
|---|
| 120 | If \c timeout is < 0 then there is no timeout.  The mutex must | 
|---|
| 121 | be locked when this method is called.  The mutex is unlocked | 
|---|
| 122 | during the wait and locked again before returning.  Returns | 
|---|
| 123 | true if the condition variable was signalled and false on | 
|---|
| 124 | timeout. | 
|---|
| 125 |  | 
|---|
| 126 | (Cancellation point) | 
|---|
| 127 | */ | 
|---|
| 128 | virtual bool            waitCondVar(CArchCond, CArchMutex, double timeout) = 0; | 
|---|
| 129 |  | 
|---|
| 130 | // | 
|---|
| 131 | // mutex methods | 
|---|
| 132 | // | 
|---|
| 133 |  | 
|---|
| 134 | //! Create a recursive mutex | 
|---|
| 135 | /*! | 
|---|
| 136 | Creates a recursive mutex.  A thread may lock a recursive mutex | 
|---|
| 137 | when it already holds a lock on that mutex.  The mutex is an | 
|---|
| 138 | opaque data type. | 
|---|
| 139 | */ | 
|---|
| 140 | virtual CArchMutex      newMutex() = 0; | 
|---|
| 141 |  | 
|---|
| 142 | //! Destroy a mutex | 
|---|
| 143 | virtual void            closeMutex(CArchMutex) = 0; | 
|---|
| 144 |  | 
|---|
| 145 | //! Lock a mutex | 
|---|
| 146 | virtual void            lockMutex(CArchMutex) = 0; | 
|---|
| 147 |  | 
|---|
| 148 | //! Unlock a mutex | 
|---|
| 149 | virtual void            unlockMutex(CArchMutex) = 0; | 
|---|
| 150 |  | 
|---|
| 151 | // | 
|---|
| 152 | // thread methods | 
|---|
| 153 | // | 
|---|
| 154 |  | 
|---|
| 155 | //! Start a new thread | 
|---|
| 156 | /*! | 
|---|
| 157 | Creates and starts a new thread, using \c func as the entry point | 
|---|
| 158 | and passing it \c userData.  The thread is an opaque data type. | 
|---|
| 159 | */ | 
|---|
| 160 | virtual CArchThread     newThread(ThreadFunc func, void* userData) = 0; | 
|---|
| 161 |  | 
|---|
| 162 | //! Get a reference to the calling thread | 
|---|
| 163 | /*! | 
|---|
| 164 | Returns a thread representing the current (i.e. calling) thread. | 
|---|
| 165 | */ | 
|---|
| 166 | virtual CArchThread     newCurrentThread() = 0; | 
|---|
| 167 |  | 
|---|
| 168 | //! Copy a thread object | 
|---|
| 169 | /*! | 
|---|
| 170 | Returns a reference to to thread referred to by \c thread. | 
|---|
| 171 | */ | 
|---|
| 172 | virtual CArchThread     copyThread(CArchThread thread) = 0; | 
|---|
| 173 |  | 
|---|
| 174 | //! Release a thread reference | 
|---|
| 175 | /*! | 
|---|
| 176 | Deletes the given thread object.  This does not destroy the thread | 
|---|
| 177 | the object referred to, even if there are no remaining references. | 
|---|
| 178 | Use cancelThread() and waitThread() to stop a thread and wait for | 
|---|
| 179 | it to exit. | 
|---|
| 180 | */ | 
|---|
| 181 | virtual void            closeThread(CArchThread) = 0; | 
|---|
| 182 |  | 
|---|
| 183 | //! Force a thread to exit | 
|---|
| 184 | /*! | 
|---|
| 185 | Causes \c thread to exit when it next calls a cancellation point. | 
|---|
| 186 | A thread avoids cancellation as long as it nevers calls a | 
|---|
| 187 | cancellation point.  Once it begins the cancellation process it | 
|---|
| 188 | must always let cancellation go to completion but may take as | 
|---|
| 189 | long as necessary to clean up. | 
|---|
| 190 | */ | 
|---|
| 191 | virtual void            cancelThread(CArchThread thread) = 0; | 
|---|
| 192 |  | 
|---|
| 193 | //! Change thread priority | 
|---|
| 194 | /*! | 
|---|
| 195 | Changes the priority of \c thread by \c n.  If \c n is positive | 
|---|
| 196 | the thread has a lower priority and if negative a higher priority. | 
|---|
| 197 | Some architectures may not support either or both directions. | 
|---|
| 198 | */ | 
|---|
| 199 | virtual void            setPriorityOfThread(CArchThread, int n) = 0; | 
|---|
| 200 |  | 
|---|
| 201 | //! Cancellation point | 
|---|
| 202 | /*! | 
|---|
| 203 | This method does nothing but is a cancellation point.  Clients | 
|---|
| 204 | can make their own functions cancellation points by calling this | 
|---|
| 205 | method at appropriate times. | 
|---|
| 206 |  | 
|---|
| 207 | (Cancellation point) | 
|---|
| 208 | */ | 
|---|
| 209 | virtual void            testCancelThread() = 0; | 
|---|
| 210 |  | 
|---|
| 211 | //! Wait for a thread to exit | 
|---|
| 212 | /*! | 
|---|
| 213 | Waits for up to \c timeout seconds for \c thread to exit (normally | 
|---|
| 214 | or by cancellation).  Waits forever if \c timeout < 0.  Returns | 
|---|
| 215 | true if the thread exited, false otherwise.  Waiting on the current | 
|---|
| 216 | thread returns immediately with false. | 
|---|
| 217 |  | 
|---|
| 218 | (Cancellation point) | 
|---|
| 219 | */ | 
|---|
| 220 | virtual bool            wait(CArchThread thread, double timeout) = 0; | 
|---|
| 221 |  | 
|---|
| 222 | //! Compare threads | 
|---|
| 223 | /*! | 
|---|
| 224 | Returns true iff two thread objects refer to the same thread. | 
|---|
| 225 | Note that comparing thread objects directly is meaningless. | 
|---|
| 226 | */ | 
|---|
| 227 | virtual bool            isSameThread(CArchThread, CArchThread) = 0; | 
|---|
| 228 |  | 
|---|
| 229 | //! Test if thread exited | 
|---|
| 230 | /*! | 
|---|
| 231 | Returns true iff \c thread has exited. | 
|---|
| 232 | */ | 
|---|
| 233 | virtual bool            isExitedThread(CArchThread thread) = 0; | 
|---|
| 234 |  | 
|---|
| 235 | //! Returns the exit code of a thread | 
|---|
| 236 | /*! | 
|---|
| 237 | Waits indefinitely for \c thread to exit (if it hasn't yet) then | 
|---|
| 238 | returns the thread's exit code. | 
|---|
| 239 |  | 
|---|
| 240 | (Cancellation point) | 
|---|
| 241 | */ | 
|---|
| 242 | virtual void*           getResultOfThread(CArchThread thread) = 0; | 
|---|
| 243 |  | 
|---|
| 244 | //! Returns an ID for a thread | 
|---|
| 245 | /*! | 
|---|
| 246 | Returns some ID number for \c thread.  This is for logging purposes. | 
|---|
| 247 | All thread objects referring to the same thread return the same ID. | 
|---|
| 248 | However, clients should us isSameThread() to compare thread objects | 
|---|
| 249 | instead of comparing IDs. | 
|---|
| 250 | */ | 
|---|
| 251 | virtual ThreadID        getIDOfThread(CArchThread thread) = 0; | 
|---|
| 252 |  | 
|---|
| 253 | //! Set the interrupt handler | 
|---|
| 254 | /*! | 
|---|
| 255 | Sets the function to call on receipt of an external interrupt. | 
|---|
| 256 | By default and when \p func is NULL, the main thread is cancelled. | 
|---|
| 257 | */ | 
|---|
| 258 | virtual void            setSignalHandler(ESignal, SignalFunc func, | 
|---|
| 259 | void* userData) = 0; | 
|---|
| 260 |  | 
|---|
| 261 | //! Invoke the signal handler | 
|---|
| 262 | /*! | 
|---|
| 263 | Invokes the signal handler for \p signal, if any.  If no handler | 
|---|
| 264 | cancels the main thread for \c kINTERRUPT and \c kTERMINATE and | 
|---|
| 265 | ignores the call otherwise. | 
|---|
| 266 | */ | 
|---|
| 267 | virtual void            raiseSignal(ESignal signal) = 0; | 
|---|
| 268 |  | 
|---|
| 269 | //@} | 
|---|
| 270 | }; | 
|---|
| 271 |  | 
|---|
| 272 | #endif | 
|---|