aswang
1.0
|
00001 /* 00002 Copyright 2003 Joseph Alvis 00003 00004 This file is part of Aswang. 00005 00006 Aswang is free software: you can redistribute it and/or modify 00007 it under the terms of the GNU Lesser General Public License as published by 00008 the Free Software Foundation, either version 3 of the License, or 00009 (at your option) any later version. 00010 00011 Aswang is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU Lesser General Public License for more details. 00015 00016 You should have received a copy of the GNU Lesser General Public License 00017 along with Aswang. If not, see <http://www.gnu.org/licenses/>. 00018 */ 00019 00020 #pragma once 00021 #include "window.h" 00022 #include "process.h" 00023 00024 namespace aswang { 00025 extern "C" { 00026 typedef void(*entryFunc)(void *); 00027 }; 00036 template<typename Class,typename Arg=void *> 00037 class ThreadFunc { 00038 private: 00039 struct func_base { 00040 func_base(Class *c) : cptr(c),count(0),destroy(false) { 00041 refMut = CreateMutex(0,false,0); 00042 } 00043 virtual ~func_base() { 00044 CloseHandle(refMut); 00045 } 00046 virtual void operator ()() = 0; 00047 Class *cptr; 00048 volatile unsigned long count; 00049 volatile bool destroy; 00050 HANDLE refMut; 00051 void inc() { 00052 WaitForSingleObject(refMut,INFINITE); 00053 ++count; 00054 ReleaseMutex(refMut); 00055 } 00056 bool dec() { 00057 WaitForSingleObject(refMut,INFINITE); 00058 bool d = (!--count)&&destroy; 00059 ReleaseMutex(refMut); 00060 return d; 00061 } 00062 bool setDestroy() { 00063 WaitForSingleObject(refMut,INFINITE); 00064 if(count!=0) 00065 destroy=true; 00066 ReleaseMutex(refMut); 00067 return destroy; 00068 } 00069 } *myFunc; 00070 struct func_noarg : public func_base { 00071 func_noarg(Class *c,void(Class::*p)()) : func_base(c),pfunc(p) {} 00072 void(Class::*pfunc)(); 00073 void operator()() {(cptr->*pfunc)();} 00074 }; 00075 struct func_arg : public func_base { 00076 func_arg(Class *c,void(Class::*p)(Arg),Arg a) : func_base(c),pfunc(p),arg(a) {} 00077 void(Class::*pfunc)(Arg); 00078 Arg arg; 00079 void operator()() {(cptr->*pfunc)(arg);} 00080 }; 00081 ThreadFunc(const ThreadFunc &){} 00082 const ThreadFunc &operator = (const ThreadFunc &) {} 00083 static void start(void *arg) { 00084 ThreadFunc<Class,Arg>::func_base *ptr = reinterpret_cast<ThreadFunc<Class,Arg>::func_base *>(arg); 00085 (*ptr)(); 00086 if(ptr->dec()) 00087 delete ptr; 00088 } 00089 public: 00090 ThreadFunc(Class *c,void(Class::*p)()) : myFunc(new func_noarg(c,p)) {} 00091 ThreadFunc(Class *c,void(Class::*p)(Arg),Arg a=0) : myFunc(new func_arg(c,p,a)) {} 00092 ~ThreadFunc() { 00093 if(!myFunc->setDestroy()) 00094 delete myFunc; 00095 } 00096 void operator () () { 00097 entryFunc ptr = (entryFunc)&start; 00098 myFunc->inc(); 00099 _beginthread(ptr,0,myFunc); 00100 } 00101 void operator () (Arg p) { 00102 static_cast<func_arg *>(myFunc)->arg = p; 00103 entryFunc ptr = (entryFunc)&start; 00104 myFunc->inc(); 00105 _beginthread(ptr,0,myFunc); 00106 } 00107 }; 00108 }