From b38cb344048d894eff4a2db436ff2c962e4c4ac5 Mon Sep 17 00:00:00 2001 From: Chris Tallon Date: Sun, 26 Mar 2006 21:29:06 +0000 Subject: [PATCH] Portability --- Makefile | 19 +++------ afeed.h | 9 +++- afeedr.h | 9 +++- defines.h | 2 + player.h | 9 +++- thread.cc | 86 +------------------------------------ thread.h | 32 ++++++-------- threadp.cc | 103 ++++++++++++++++++++++++++++++++++++++++++++ threadp.h | 59 ++++++++++++++++++++++++++ threadwin.cc | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++ threadwin.h | 65 ++++++++++++++++++++++++++++ timers.h | 9 +++- vconnect.h | 9 +++- vfeed.h | 9 +++- 14 files changed, 411 insertions(+), 127 deletions(-) create mode 100644 threadp.cc create mode 100644 threadp.h create mode 100644 threadwin.cc create mode 100644 threadwin.h diff --git a/Makefile b/Makefile index eef9158..3a47e85 100644 --- a/Makefile +++ b/Makefile @@ -21,18 +21,13 @@ OBJECTS1 = main.o command.o log.o tcp.o dsock.o thread.o timers.o i18n.o vchannellist.o vwelcome.o vvideolive.o vvideorec.o vepgsettimer.o \ vchannelselect.o vserverselect.o vconnect.o voptions.o vepg.o \ widget.o wselectlist.o wjpeg.o wsymbol.o wbutton.o woptionbox.o wtextbox.o \ - fonts/helvB24.o fonts/helvB18.o - -OBJECTS2 = remote.o led.o mtd.o video.o audio.o osd.o surface.o \ - remotemvp.o remotewin.o \ - ledmvp.o ledwin.o \ - mtdmvp.o mtdwin.o \ - videomvp.o videowin.o \ - audiomvp.o audiowin.o \ - osdmvp.o osdwin.o \ - surfacemvp.o surfacewin.o - -OBJECTS = $(OBJECTS1) $(OBJECTS2) + fonts/helvB24.o fonts/helvB18.o \ + remote.o led.o mtd.o video.o audio.o osd.o surface.o + +OBJECTSMVP = threadp.o remotemvp.o ledmvp.o mtdmvp.o videomvp.o audiomvp.o osdmvp.o surfacemvp.o +OBJECTSWIN = threadwin.o remotewin.o ledwin.o mtdwin.o videowin.o audiowin.o osdwin.o surfacewin.o + +OBJECTS = $(OBJECTS1) $(OBJECTSMVP) .PHONY: clean fresh all install strip diff --git a/afeed.h b/afeed.h index dfd4c61..d5739fb 100644 --- a/afeed.h +++ b/afeed.h @@ -25,11 +25,16 @@ #include #include "log.h" -#include "thread.h" #include "demuxer.h" #include "callback.h" -class AFeed : public Thread +#ifdef WIN32 +#include "threadwin.h" +#else +#include "threadp.h" +#endif + +class AFeed : public Thread_TYPE { public: AFeed(Callback* tcb); diff --git a/afeedr.h b/afeedr.h index 0d9d29e..8f12e20 100644 --- a/afeedr.h +++ b/afeedr.h @@ -25,11 +25,16 @@ #include #include "log.h" -#include "thread.h" #include "callback.h" #include "stream.h" -class AFeedR : public Thread +#ifdef WIN32 +#include "threadwin.h" +#else +#include "threadp.h" +#endif + +class AFeedR : public Thread_TYPE { public: AFeedR(Callback* tcb, Stream* tstream); diff --git a/defines.h b/defines.h index f95d286..d4c13bc 100644 --- a/defines.h +++ b/defines.h @@ -37,6 +37,7 @@ void MILLISLEEP(ULONG a); #ifdef WIN32 #define Surface_TYPE SurfaceWin + #define Thread_TYPE ThreadWin #define SNPRINTF _snprintf #define VSNPRINTF _vsnprintf @@ -48,6 +49,7 @@ void MILLISLEEP(ULONG a); #else #define Surface_TYPE SurfaceMVP + #define Thread_TYPE ThreadP #define SNPRINTF snprintf #define VSNPRINTF vsnprintf diff --git a/player.h b/player.h index 24f5e18..d7a5ec7 100644 --- a/player.h +++ b/player.h @@ -29,13 +29,18 @@ #include "vfeed.h" #include "afeed.h" #include "remote.h" -#include "thread.h" #include "vdr.h" #include "callback.h" #include "message.h" #include "messagequeue.h" -class Player : public Thread, public Callback +#ifdef WIN32 +#include "threadwin.h" +#else +#include "threadp.h" +#endif + +class Player : public Thread_TYPE, public Callback { public: Player(MessageQueue* messageQueue, UCHAR isRecording, UCHAR isRadio); diff --git a/thread.cc b/thread.cc index 6e210a5..7644075 100644 --- a/thread.cc +++ b/thread.cc @@ -20,94 +20,12 @@ #include "thread.h" -// Undeclared functions, only for use in this file to start the thread -void threadInternalStart(void *arg) -{ - // I don't want signals - sigset_t sigs; - sigfillset(&sigs); - pthread_sigmask(SIG_BLOCK, &sigs, NULL); - - Thread *t = (Thread *)arg; - t->threadInternalStart2(); -} - -void Thread::threadInternalStart2() -{ - threadMethod(); -} - -int Thread::threadStart() -{ - pthread_cond_init(&threadCond, NULL); - pthread_mutex_init(&threadCondMutex, NULL); - - threadActive = 1; - if (pthread_create(&pthread, NULL, (void*(*)(void*))threadInternalStart, (void *)this) == -1) return 0; - return 1; -} - -void Thread::threadStop() -{ - threadActive = 0; - // Signal thread here in case it's waiting - threadSignal(); - pthread_join(pthread, NULL); - this->threadPostStopCleanup(); -} - -void Thread::threadCancel() -{ - threadActive = 0; - pthread_cancel(pthread); - pthread_join(pthread, NULL); - this->threadPostStopCleanup(); -} - -void Thread::threadCheckExit() -{ - if (!threadActive) pthread_exit(NULL); -} - char Thread::threadIsActive() { return threadActive; } -void Thread::threadLock() -{ - pthread_mutex_lock(&threadCondMutex); -} - -void Thread::threadUnlock() -{ - pthread_mutex_unlock(&threadCondMutex); -} - -void Thread::threadSignal() -{ - pthread_mutex_lock(&threadCondMutex); - pthread_cond_signal(&threadCond); - pthread_mutex_unlock(&threadCondMutex); -} - -void Thread::threadSignalNoLock() -{ - pthread_cond_signal(&threadCond); -} - -void Thread::threadWaitForSignal() -{ - pthread_cond_wait(&threadCond, &threadCondMutex); -} - -void Thread::threadWaitForSignalTimed(struct timespec* ts) -{ - pthread_cond_timedwait(&threadCond, &threadCondMutex, ts); -} - -void Thread::threadSetKillable() +void Thread::threadInternalStart2() { - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); - pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + threadMethod(); } diff --git a/thread.h b/thread.h index 544d345..12da488 100644 --- a/thread.h +++ b/thread.h @@ -21,39 +21,33 @@ #ifndef THREAD_H #define THREAD_H -#include -#include - class Thread { protected: - // Override this method in derived classes + // Override this method in classes derived from ThreadP or ThreadWin virtual void threadMethod()=0; virtual void threadPostStopCleanup()=0; // Methods to use from outside the thread - int threadStart(); // start the thread. threadMethod() will be called in derived class - void threadStop(); // stop the thread nicely. thread will be stopped when it next calls threadCheckExit() - void threadCancel(); // stop thread immediately. thread will be stopped at the next cancellation point - void threadSignal(); // releases a thread that has called threadWaitForSignal - void threadSignalNoLock(); // same as above but without locking guarantees. probably not a good idea. + virtual int threadStart()=0; // start the thread. threadMethod() will be called in derived class + virtual void threadStop()=0; // stop the thread nicely. thread will be stopped when it next calls threadCheckExit() + virtual void threadCancel()=0; // stop thread immediately. thread will be stopped at the next cancellation point + 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 // Methods to use from inside the thread - void threadSetKillable(); // allows threadCancel() to work - void threadCheckExit(); // terminates thread if threadStop() has been called - void threadWaitForSignal(); // pauses thread until threadSignal() is called - void threadWaitForSignalTimed(struct timespec*); // pauses thread until threadSignal() is called or timer expires - void threadLock(); // locks the mutex used for internal cond/signal stuff - void threadUnlock(); // unlocks. + virtual void threadSetKillable()=0; // allows threadCancel() to work + virtual void threadCheckExit()=0; // terminates thread if threadStop() has been called + virtual void threadWaitForSignal()=0; // pauses thread until threadSignal() is called + virtual void threadWaitForSignalTimed(struct timespec*)=0; // pauses thread until threadSignal() is called or timer expires + virtual void threadLock()=0; // locks the mutex used for internal cond/signal stuff + virtual void threadUnlock()=0; // unlocks. // Internal bits and pieces - private: + protected: char threadActive; - pthread_t pthread; - pthread_cond_t threadCond; - pthread_mutex_t threadCondMutex; public: void threadInternalStart2(); diff --git a/threadp.cc b/threadp.cc new file mode 100644 index 0000000..019c54d --- /dev/null +++ b/threadp.cc @@ -0,0 +1,103 @@ +/* + Copyright 2004-2005 Chris Tallon + + This file is part of VOMP. + + VOMP is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + VOMP 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. + + You should have received a copy of the GNU General Public License + along with VOMP; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "threadp.h" + +// Undeclared functions, only for use in this file to start the thread +void threadPInternalStart(void *arg) +{ + // I don't want signals + sigset_t sigs; + sigfillset(&sigs); + pthread_sigmask(SIG_BLOCK, &sigs, NULL); + + Thread *t = (Thread *)arg; + t->threadInternalStart2(); +} + +int ThreadP::threadStart() +{ + pthread_cond_init(&threadCond, NULL); + pthread_mutex_init(&threadCondMutex, NULL); + + threadActive = 1; + if (pthread_create(&pthread, NULL, (void*(*)(void*))threadPInternalStart, (void *)this) == -1) return 0; + return 1; +} + +void ThreadP::threadStop() +{ + threadActive = 0; + // Signal thread here in case it's waiting + threadSignal(); + pthread_join(pthread, NULL); + this->threadPostStopCleanup(); +} + +void ThreadP::threadCancel() +{ + threadActive = 0; + pthread_cancel(pthread); + pthread_join(pthread, NULL); + this->threadPostStopCleanup(); +} + +void ThreadP::threadCheckExit() +{ + if (!threadActive) pthread_exit(NULL); +} + +void ThreadP::threadLock() +{ + pthread_mutex_lock(&threadCondMutex); +} + +void ThreadP::threadUnlock() +{ + pthread_mutex_unlock(&threadCondMutex); +} + +void ThreadP::threadSignal() +{ + pthread_mutex_lock(&threadCondMutex); + pthread_cond_signal(&threadCond); + pthread_mutex_unlock(&threadCondMutex); +} + +void ThreadP::threadSignalNoLock() +{ + pthread_cond_signal(&threadCond); +} + +void ThreadP::threadWaitForSignal() +{ + pthread_cond_wait(&threadCond, &threadCondMutex); +} + +void ThreadP::threadWaitForSignalTimed(struct timespec* ts) +{ + pthread_cond_timedwait(&threadCond, &threadCondMutex, ts); +} + +void ThreadP::threadSetKillable() +{ + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); +} diff --git a/threadp.h b/threadp.h new file mode 100644 index 0000000..5461f86 --- /dev/null +++ b/threadp.h @@ -0,0 +1,59 @@ +/* + Copyright 2004-2005 Chris Tallon + + This file is part of VOMP. + + VOMP is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + VOMP 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. + + You should have received a copy of the GNU General Public License + along with VOMP; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef THREADP_H +#define THREADP_H + +#include +#include + +#include "thread.h" + +class ThreadP : public Thread +{ + protected: + // Override this method in derived classes + virtual void threadMethod()=0; + virtual void threadPostStopCleanup()=0; + + // Methods to use from outside the thread + int threadStart(); // start the thread. threadMethod() will be called in derived class + void threadStop(); // stop the thread nicely. thread will be stopped when it next calls threadCheckExit() + void threadCancel(); // stop thread immediately. thread will be stopped at the next cancellation point + void threadSignal(); // releases a thread that has called threadWaitForSignal + void threadSignalNoLock(); // same as above but without locking guarantees. probably not a good idea. + + // Methods to use from inside the thread + void threadSetKillable(); // allows threadCancel() to work + void threadCheckExit(); // terminates thread if threadStop() has been called + void threadWaitForSignal(); // pauses thread until threadSignal() is called + void threadWaitForSignalTimed(struct timespec*); // pauses thread until threadSignal() is called or timer expires + void threadLock(); // locks the mutex used for internal cond/signal stuff + void threadUnlock(); // unlocks. + + // Internal bits and pieces + + private: + pthread_t pthread; + pthread_cond_t threadCond; + pthread_mutex_t threadCondMutex; +}; + +#endif diff --git a/threadwin.cc b/threadwin.cc new file mode 100644 index 0000000..e42b989 --- /dev/null +++ b/threadwin.cc @@ -0,0 +1,118 @@ +/* + Copyright 2004-2005 Chris Tallon + + This file is part of VOMP. + + VOMP is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + VOMP 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. + + You should have received a copy of the GNU General Public License + along with VOMP; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "threadwin.h" + +// Undeclared functions, only for use in this file to start the thread +DWORD WINAPI threadInternalStart(void *arg) +{ + Thread *t = (Thread *)arg; + t->threadInternalStart2(); + return 0; +} + +int ThreadP::threadStart() +{ + threadCond = CreateEvent(NULL,FALSE,FALSE,NULL); + if (threadCond == NULL) return 0; + threadCondMutex = CreateMutex(NULL,TRUE,NULL); + if (threadCondMutex == NULL) + { + CloseHandle(threadCond); + return 0; + } + + threadActive = 1; + DWORD threadId; + pthread = CreateThread(NULL, 0, threadInternalStart, (void*)this,0, &threadId); + if (pthread == NULL) + { + CloseHandle(threadCond); + CloseHandle(threadCondMutex); + return 0; + } + return 1; +} + +void ThreadP::threadStop() +{ + threadActive = 0; + // Signal thread here in case it's waiting + threadSignal(); + WaitForSingleObject(pthread, INFINITE); + this->threadPostStopCleanup(); +} + +void ThreadP::threadCancel() +{ + threadActive = 0; + TerminateThread(pthread, 0); + WaitForSingleObject(pthread, INFINITE); + this->threadPostStopCleanup(); +} + +void ThreadP::threadCheckExit() +{ + if (!threadActive) ExitThread(NULL); +} + +void ThreadP::threadLock() +{ + WaitForSingleObject(threadCondMutex, INFINITE); +} + +void ThreadP::threadUnlock() +{ + ReleaseMutex(threadCondMutex); +} + +void ThreadP::threadSignal() +{ + WaitForSingleObject(threadCondMutex, INFINITE); + SetEvent(threadCond); + ReleaseMutex(threadCondMutex); +} + +void ThreadP::threadSignalNoLock() +{ + SetEvent(threadCond); +} + +void ThreadP::threadWaitForSignal() +{ + WaitForSingleObject(threadCond,INFINITE); +} + +void ThreadP::threadWaitForSignalTimed(struct timespec* ts) +{ + HANDLE handles[2] ={threadCond, NULL}; + LARGE_INTEGER duration; + duration.QuadPart=ts->tv_sec*1000*1000*10+ts->tv_nsec/100; + + handles[1]=CreateWaitableTimer(NULL,TRUE,NULL); + /* SetWaitableTimer(handles[1], &duration, 0, NULL, NULL, 0); + WaitForMultipleObject(2,handles,INFINITE);*/ + CloseHandle(handles[1]); +} + +void ThreadP::threadSetKillable() +{ + //WIN32:Ignore or use a separate Event Object to simulate this +} diff --git a/threadwin.h b/threadwin.h new file mode 100644 index 0000000..1e55507 --- /dev/null +++ b/threadwin.h @@ -0,0 +1,65 @@ +/* + Copyright 2004-2005 Chris Tallon + + This file is part of VOMP. + + VOMP is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + VOMP 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. + + You should have received a copy of the GNU General Public License + along with VOMP; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef THREADWIN_H +#define THREADWIN_H + +#define _WIN32_WINNT 0x400 +#include +#include +typedef struct timespec +{ + long tv_sec; /* seconds */ + long tv_nsec; /* nanoseconds */ +} timespec; + +#include "thread.h" + +class ThreadWin : public Thread +{ + protected: + // Override this method in derived classes + virtual void threadMethod()=0; + virtual void threadPostStopCleanup()=0; + + // Methods to use from outside the thread + int threadStart(); // start the thread. threadMethod() will be called in derived class + void threadStop(); // stop the thread nicely. thread will be stopped when it next calls threadCheckExit() + void threadCancel(); // stop thread immediately. thread will be stopped at the next cancellation point + void threadSignal(); // releases a thread that has called threadWaitForSignal + void threadSignalNoLock(); // same as above but without locking guarantees. probably not a good idea. + + // Methods to use from inside the thread + void threadSetKillable(); // allows threadCancel() to work + void threadCheckExit(); // terminates thread if threadStop() has been called + void threadWaitForSignal(); // pauses thread until threadSignal() is called + void threadWaitForSignalTimed(struct timespec*); // pauses thread until threadSignal() is called or timer expires + void threadLock(); // locks the mutex used for internal cond/signal stuff + void threadUnlock(); // unlocks. + + // Internal bits and pieces + + private: + HANDLE pthread; + HANDLE threadCondMutex; + HANDLE threadCond; +}; + +#endif diff --git a/timers.h b/timers.h index 0aac2e7..7878b98 100755 --- a/timers.h +++ b/timers.h @@ -27,10 +27,15 @@ #include "defines.h" #include "log.h" -#include "thread.h" #include "command.h" #include "timerreceiver.h" +#ifdef WIN32 +#include "threadwin.h" +#else +#include "threadp.h" +#endif + /* Timers documentation @@ -64,7 +69,7 @@ using namespace std; //using namespace __gnu_cxx; typedef list TimerList; -class Timers : public Thread +class Timers : public Thread_TYPE { public: Timers(); diff --git a/vconnect.h b/vconnect.h index 139550e..bc4cdf4 100644 --- a/vconnect.h +++ b/vconnect.h @@ -32,10 +32,15 @@ #include "message.h" #include "colour.h" #include "video.h" -#include "thread.h" #include "i18n.h" -class VConnect : public VInfo, public Thread +#ifdef WIN32 +#include "threadwin.h" +#else +#include "threadp.h" +#endif + +class VConnect : public VInfo, public Thread_TYPE { public: VConnect(); diff --git a/vfeed.h b/vfeed.h index 93117ce..c8e6b0c 100644 --- a/vfeed.h +++ b/vfeed.h @@ -25,11 +25,16 @@ #include #include "log.h" -#include "thread.h" #include "demuxer.h" #include "callback.h" -class VFeed : public Thread +#ifdef WIN32 +#include "threadwin.h" +#else +#include "threadp.h" +#endif + +class VFeed : public Thread_TYPE { public: VFeed(Callback* tcb); -- 2.39.2