LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   passing a class member function to pthread_create. (https://www.linuxquestions.org/questions/programming-9/passing-a-class-member-function-to-pthread_create-466807/)

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;
}


dmail 07-29-2006 11:15 AM

If anybody is interested the sources for this are located @
Thread starters
Posix thread
and
Win32 thread


All times are GMT -5. The time now is 06:38 PM.