0

Possible Duplicate:
pthread Function from a Class

I am getting an error ("Can not convert .....") and I think the third argument in the pthread_create call is wrong. I know the type of the third argument should be (void*)*(void *) but I am still getting an error.

void ServerManager::Init(){  
     pthread_t thread;
     pthread_create(&thread, NULL, AcceptLoop, (void *)this);
}

I have declared like this and I am trying to call the function below

void* ServerManager::AcceptLoop(void * delegate){

}

Please let me know how to fix this..

Thanks in advance.

3

2 Answers 2

5

To be portable the callback function must use the C ABI;

extern "C" void* AcceptLoop(void*);

class ServerManager 
{
    public:
       void  Init();

    private:
       friend void* AcceptLoop(void*);

       void* AcceptLoop();   // Implement this yourself
       pthread_t thread;
};

void ServerManager::Init()
{  
     pthread_create(&thread, NULL, &AcceptLoop, reinterpret_cast<void*>(this));
}

void* AcceptLoop(void* delegate)
{
    return reinterpret_cast<ServerManager*>(delegate)->AcceptLoop();
}

void* ServerManager::AcceptLoop()
{
    // Do stuff
    // Be carefull this may (or may not) start before ServerManager::Init() returns.
    return NULL;
}

Edit: Based on comment

pthread_join()

This will wait for a particular thread to exit. The thread that called pthread_create() can call pthread_join() to wait for the child to finish. A good place for this would(might) be to put the join in the destructor of the ServerManager.

pthread_cancel()

pthread_cancel() is an asynchronous request for the thread to stop. The call will return immediately (thus does not mean the thread is dead yet). It is unspecified how quickily it will stop executing your code but it should execute some tidy handlers and then exit. It is a good idea to wait for a cancelled thread using pthread_jon().

class ServerManager 
{
    public:
       void  ~ServerManager()
       {
           join();
       }
       void* join()
       {
           void*   result;
           pthread_join(thread, &result);
           return result;
       }
       void cancel()
       {
           pthread_cancel(thread);
           join();
       }
       ... like before
};
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your answer. I have one more question. What is the best way to close this thread? I have read pthread_join or pthread_cancel but I am not sure which one is better. Thanks in advance.
@LCYSoft: Updated. PS. You may want to look at boost::thread. It is much more advanced and easy to use. The pthread interface is not really for the beginner.
2

You need to make your AcceptLoop(void*) a static function.

Example:

class ServerManager {
    // ...
    static void* AcceptLoop(void*);
    void* AcceptLoop();   // Implement this yourself
};

void* ServerManager::AcceptLoop(void* delegate)
{
    return static_cast<ServerManager*>(delegate)->AcceptLoop();
}

5 Comments

Thanks for your answer. But is there any alternative way to do this such as using a function pointer?
@LCYSoft: You can get a function pointer for a static function.
The static function specified in the pthread_create() call can do whatever it likes - if you give it a function pointer, either through the final void* parameter to pthread_create() which is passed as the only parameter to the static function, or beforehand however you like, then it can call it. Note: pointers to member function can't be called without knowing the object's address anyway. Unless you want to vary which member function's called at run-time, Chris's solution is simpler and better than stuffing around with function pointers - btw "delegate" = addr of ServerManager object.
Since pthreads is a C library the callback must use the C ABI. The only way to gurantee this is to make "AcceptLoop()" an extern "C" you are just lucky that your compiler uses the same ABI for static methods.
@Martin: +1 That is true. I thought about fixing it, but then it seems your answer already took care of that. :-)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.