#define Surface_TYPE SurfaceWin
#define Thread_TYPE ThreadWin
+ #define ThreadID_TYPE FIXME Marten
#define SNPRINTF _snprintf
#define VSNPRINTF _vsnprintf
#define Surface_TYPE SurfaceMVP
#define Thread_TYPE ThreadP
+ #include <pthread.h>
+ #define ThreadID_TYPE pthread_t
#define SNPRINTF snprintf
#define VSNPRINTF vsnprintf
#ifndef THREAD_H
#define THREAD_H
+#include "defines.h"
+
class Thread
{
protected:
virtual void threadSignal()=0; // releases a thread that has called threadWaitForSignal
virtual void threadSignalNoLock()=0; // same as above but without locking guarantees. probably not a good idea.
char threadIsActive(); // returns 1 if thread has been started but not stop() or cancel() 'd
+ virtual ThreadID_TYPE getThreadID()=0; // returns the ID of this thread
// Methods to use from inside the thread
virtual void threadSetKillable()=0; // allows threadCancel() to work
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
}
+pthread_t ThreadP::getThreadID() // returns the ID of this thread
+{
+ return pthread;
+}
+
+// Static functions
+
void ThreadP::threadSuicide()
{
if(!pthread_detach(pthread_self()))
pthread_exit(NULL);
}
+
+pthread_t ThreadP::thisThreadID() // returns the ID of the calling thread
+{
+ return pthread_self();
+}
// Internal bits and pieces
- private:
pthread_t pthread;
pthread_cond_t threadCond;
pthread_mutex_t threadCondMutex;
public:
+ pthread_t getThreadID(); // returns the ID of the thread represented by this object
+
+
+ static pthread_t thisThreadID(); // Self identification - returns ID of calling thread
static void threadSuicide(); // Self termination
};
Delete the timer normally, set resetFlag
2. The TimerEvent is found, running = true. This means the timer is currently firing,
timercall on the client is being called.
- In this case, this thread calling cancelTimer needs to unlock and wait for the
- timercall thread to get back. (sleeps or signalling)
+ a. Thread calling cancelTimer is an external thread: In this case, this thread
+ calling cancelTimer needs to unlock and wait for the timercall thread to get
+ back. (sleeps or signalling)
+ b. the timercall thread is calling cancelTimer. remove any restartAfterFinished
+ request, but otherwise ignore the request to cancelTimer because it has already
+ fired. The timercall thread will return to the calling code and eventually
+ terminate in threadEventFinished.
3. The TimerEvent is not found. Client error or the thread returned to
the Timers module in between client calling cancelTimer and cancelTimer actually
running. Do nothing, return normally.
}
else
{
- // Case 2. For now, use polling with a 50ms delay.
+ if (Thread_TYPE::thisThreadID() == currentTimerEvent->getThreadID())
+ {
+ // Case 2 b.
+ // The thread requesting cancelTimer is the timer thread itself, the timer has already fired.
+ logger->log("Timers", Log::DEBUG, "%p ref %i cancelTimer itself calling - ignore", client, clientReference);
+ currentTimerEvent->restartAfterFinish = false; // in case a restart had already been set.
+ threadUnlock();
+ return true;
+ }
+
+ // Case 2 a. For now, use polling with a 50ms delay.
// Don't delete a running timer.
// FIXME upgrade me to signalling