dmail |
07-23-2006 11:22 AM |
passing a class member function to pthread_create.
I was wondering if I could create a simple conveter to pass a class member
function to pthread_create and the following is what I have come up with.
I can't see any problems with it (yes I know there are memory leaks),
but I'm wondering if anybody else can see any.
Sorry for the long post:)
cheers.
Code:
/*
////////////////////////////////////////////////////////////////////////////////
A struct for storing the Object pointer(o) and a function parameter(p)
T is a pointer the class
P is a pointer to the parameter which is passed to the class memeber function
*/
template<typename T,typename P>
struct OP
{
T o;
P p;
};
////////////////////////////////////////////////////////////////////////////////
//normal posix pthread C function pointer
typedef void* (*func_ptr) (void*);
/*
/////////////////////////////////////////////////////////////////////////////////
posix class member function starter
R is the return type of the member function
T is the type of class which the function is a member function of
P is the member functions parameter- NOTE THIS IS A POINTER we are dealing with
passing information between threads
R(T::*f)(P) is the signture of the function pointer
void* op is the templates struct above OP<T,P>
*/
template<class R,class T,class P, R (T::*f)(P)>
void* thread_starter(void* op)
{
//get and store the class pointer
T* p_class = static_cast<T*>(static_cast<OP<T*,P>*>(op)->o);
//get and store the parameter
P parm = static_cast<P>(static_cast<OP<T*,P>*>(op)->p);
//delete the struct which contains the class pointer and parameter
delete static_cast<OP<T*,P>*>(op);
//call the class member function passing the parameter
(p_class->*f)(parm);
return 0;
}
///////////////////////////////////////////////////////////////////////////////
/*=============================================================================
Class : Thread
Remarks :A simple inlined wrapper for pthread
-------------------------------------------------------------------------------
=============================================================================*/
class Thread
{
public:
Thread( void ){;}
~Thread( void ){;}
inline bool start( func_ptr func, void* data)
{
if( pthread_create( &m_thread, NULL, func, data ) != 0){ return false; }
return true;
}
template<class R, class T,class P, R (T::*mem_func)(P)>
inline bool start_member(T *object, P param)
{
OP<T*,P>* op = new OP<T*,P>;
op->o=object;
op->p=param;
if( pthread_create( &m_thread, NULL, thread_starter<R,T,P,mem_func>, static_cast<void*>(op) ) != 0)
{ return false; }
return true;
}
inline bool join( void )
{
if(pthread_join( m_thread, NULL ) != 0)
{ return false; }
return true;
}
inline bool close_thread( void )
{
int result = pthread_cancel(m_thread);
if (result != 0){ return false; }
return true;
}
inline void exit_caller( void )
{
int exit_code = -1;
pthread_exit(&exit_code);
}
private:
pthread_t m_thread;
};
Code:
//tester class
class Some
{
public:
Some(){}
~Some(){}
int func1(int* a){return int;}
void func2(char*c){return;}
void func3(float* d){return;}
};
int main(int argc, char* argv[ ])
{
thread = new Thread;
Some* class_p = new Some;
int * int_p = new int;
*int_p=4;
char* char_p = new char;
*char_p = 'C';
//call: int Some::func1(int*)
thread->start_member<int,Some,int*,&Some::func1>(class_p,int_p);
/*
or calling: void Some::func2(char*)
would be done like:
thread->start_member<void,Some,char*,&Some::func2>(class_p,char_p);
*/
thread->join();
return 0;
}
|