aswang  1.0
ThreadFunc.h
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines