// Common, group Miscelaneous
// Copyright Alexander Liss
#ifndef __TASKTHREAD_H__
#define __TASKTHREAD_H__
#include <process.h>
#include "win0.h"
// pass data in heap, thread procedure deletes it
// callback is of a form void callback(const t&);
// TaskThread
// no control over TaskThread - fire and forget
// do not have anything in callback that can stuck
// (a call to external lib, infinite loop, etc.)
// an object has no data and
// can be destructed before the end of the thread
// if a reference to a counter is passed
// then the counter is updated
template<class T>
class TaskThread
{
public:
static int launch(void (*callback)(const T&),T *z=0,long *counter=0);
private:
struct H{void (*callback)(const T&);T* data; long *counter;};
static void _cdecl thread_procedure(void *);
};
// TaskThread
template<class T>
void _cdecl TaskThread<T>::thread_procedure(void * ptr)
{
TaskThread<T>::H * h=static_cast< TaskThread<T>::H *>(ptr);
h->callback(*h->data);
delete h->data;
h->data=0;
if(h->counter)
InterlockedDecrement(h->counter);
delete h;
h=0;
}
template<class T>
int TaskThread<T>::launch(void (*f)(const T&),T *d,long *counter)
{
H *h=new H;
h->callback=f;
h->data=d;
h->counter=counter;
if(counter)
InterlockedIncrement(counter);
unsigned long g=_beginthread(thread_procedure,0,h);
if(g==-1)
{
InterlockedDecrement(counter);
return 1;
}
return 0;
}
/*
// Usage
//#include "stdio.h"
struct A{int i;};
void callback(const A& z)
{ fprintf(stdout,"a = %d\n",z.i);}
long counter=0;
void f()
{
A *a = new A;
a->i=1;
TaskThread<A>::launch(callback,a,&counter);
TaskThread<A>::launch(callback,a);
}
*/
#endif