Project Home
Project Home
Documents
Documents
Wiki
Wiki
Discussion Forums
Discussions
Project Information
Project Info
Forum Topic - Resource manager using thread pool in C++: (11 Items)
   
Resource manager using thread pool in C++  
I have a couple of questions concerning development of thread pools in C++.

I am developing a resource manager using thread pool in C++, it is all incapsulated in a Comm class. But when set up the
 thread pool functions, it returns me a casting error, for example:

Function definition:
THREAD_POOL_PARAM_T * Comm::WaitForMessage(THREAD_POOL_PARAM_T *ctp);

Then when initialising the thread_pool_attr_t:
tp_attr.block_func = Comm::WaitForMessage;

Moments give me an error like:
cannot convert 'Comm::WaitForMessage' from type 'resmgr_context_t* (Comm::)(resmgr_context_t*) {aka _resmgr_context* 
(Comm::)(_resmgr_context*)}' to type 'resmgr_context_t* (*)(resmgr_context_t*) {aka _resmgr_context* (*)(_resmgr_context
*)}'

Another thing, as far as the documentation and headers lead me to think, the THREAD_POOL_PARAM_T *, coulee be a void 
pointer (as defined in the dispatch.h header), allowing me to transit any kind of structure as parameters and returns of
 the thread pool functions (allocating resources, blocking, handling, etc).
But when I try this:

THREAD_POOL_PARAM_T * Comm::ContextAlloc(THREAD_POOL_HANDLE_T *handle)
{
    //  Stablish connection to CAN server
    CommServerStruct *comm_server = new CommServerStruct;
    comm_server->can_coid = open(CAN_SERVER_PATH, O_WRONLY);
    return ((void*)comm_server);
}

Moments give me the error:
invalid conversion from 'void*' to 'resmgr_context_t* {aka _resmgr_context*}' [-
 fpermissive]

Could anyone please guide me in what am I doing wrong?
Re: Resource manager using thread pool in C++  
Its seems to me more a C++ problem :-)
Please post some more code...

anyway, I suppose tp_attr is a thread_pool_attr_t ...

this one:
tp_attr.block_func = Comm::WaitForMessage;

If You want to register a class member as a call-back function, like in C, the way 
shown is not correct. A method is NOT like a function.

For Your second question, in C++ You can not do
     return ((void*)comm_server);
but if comm_server is a void*
    return ( (THREAD_POOL_PARAM_T*)comm_server);
or, if You want a void* , You have to change member declaration.

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Try this one (I'm not sure it works)
class Comm{
public:
	thread_pool_attr_t	tp_attr;

	public:
	Comm(){
		tp_attr.block_func = WaitForMessage;
	};
	~Comm(){};

	static THREAD_POOL_PARAM_T* WaitForMessage(THREAD_POOL_PARAM_T *ctp);
	static THREAD_POOL_PARAM_T* ContextAlloc(THREAD_POOL_HANDLE_T *handle);
};

THREAD_POOL_PARAM_T * Comm::WaitForMessage(THREAD_POOL_PARAM_T *ctp)
{
	THREAD_POOL_PARAM_T *pTh=0;
	return(pTh);
}


THREAD_POOL_PARAM_T* Comm::ContextAlloc(THREAD_POOL_HANDLE_T *handle)
{
	void* pTh=0;

	int fd;
    fd= open("/dev/mydev", O_WRONLY);
    return ( (THREAD_POOL_PARAM_T*)pTh);
}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


Bye,
Mario



RE: Resource manager using thread pool in C++  
Re: RE: Resource manager using thread pool in C++  
Thank you both very much for such a quick reply.
Follow the "complete" code of what I have until the moment (there's still much to do).
About returning a void pointer, I've just did the same as the thread pool example in the Get Programming with QNX 
Neutrino guide does.

#define CAN_SERVER_PATH "/net/..."
//****************************************************************************
//  Global variables
//****************************************************************************



//****************************************************************************
//  Thread pool lifecycle functions
//****************************************************************************
//  Context manipulation functions when thread is created and killed
THREAD_POOL_PARAM_T * Comm::ContextAlloc(THREAD_POOL_HANDLE_T *handle)
{
    //  Stablish connection to CAN server
    CommServerStruct *comm_server = new CommServerStruct;
    comm_server->can_coid = open(CAN_SERVER_PATH, O_WRONLY);

    if(comm_server->can_coid == -1)
    {
        //  Failed to connect to CAN server
        //  Return error
    }
    //  Initialize values;
    comm_server->comm_rcvid = -1;

    return ((void*)comm_server);
}

void Comm::ContextFree(THREAD_POOL_PARAM_T *param)
{
    CommServerStruct *comm_server = (CommServerStruct *)param;
    delete comm_server;
}

//  Function to block waiting for a message from client
THREAD_POOL_PARAM_T * Comm::WaitForMessage(THREAD_POOL_PARAM_T *ctp)
{
    //  Cast pointer
    CommServerStruct *comm_server = (CommServerStruct *)ctp;
    //  Blocks waiting for message
    MsgReceive(comm_chid_, comm_server->msg, sizeof(comm_server->msg), NULL);

    return ((void*)comm_server); 
}

//  Message parsing function when unblocks with received message
int Comm::ParseMessage(THREAD_POOL_PARAM_T *ctp)
{
    //  Cast pointer
    CommServerStruct *comm_server = (CommServerStruct *)ctp;
    char return_message[16];
    //  Pass the message over to CAN server
    MsgSend(comm_server->can_coid, comm_server->msg, sizeof(comm_server->msg), return_message, sizeof(return_message));
    return 1;
}

//****************************************************************************
//  Communications set up and start
//****************************************************************************
int Comm::InitComm()
{
    if((comm_chid_ = ChannelCreate(0)) == -1)
    {
        //  Could not create Channel, insert error code
        return -1;

    }

    //  Set up the thread parameters for the threads that will populate the pool
    pthread_attr_t *t_attr;
    pthread_attr_init (t_attr);


    //  Set up the thread pool parameters
    thread_pool_attr_t tp_attr;
    thread_pool_t    *tpp;
    memset(&tp_attr, 0, sizeof (tp_attr));
    //tp_attr.handle = (void *) 0x12345678;  // passed to contextalloc
    tp_attr.block_func = WaitForMessage;
    tp_attr.unblock_func = UnblockFunc;
    tp_attr.context_alloc = ContextAlloc;
    tp_attr.handler_func = ParseMessage;
    tp_attr.context_free = ContextFree;
    tp_attr.lo_water = 2;
    tp_attr.hi_water = 6;
    tp_attr.increment = 1;
    tp_attr.maximum = 10;
    tp_attr.attr = t_attr;



    //  Create a thread pool that returns
    tpp = thread_pool_create (&tp_attr, 0);
    if (tpp == NULL)
    {
        //  Could not create thread pool
        return -1;
    }

    if (thread_pool_start(tpp) == -1)
    {
        //  Could not start thread pool
        ChannelDestroy(comm_chid_);
        //sleep (3000);
        return -1;
    }

    //  If it gets here, thread pool is up and running
    return 1;
}
Re: RE: Resource manager using thread pool in C++  
And yes, I did assume it was more of a language problem.
QNX base it's guides and manuals all in C language.

Could you please give me some directions on how to deal with this C++ Method vs C function callback assignment?
Re: RE: Resource manager using thread pool in C++  
About returning a void pointer, it's different from C than C++: in C++ type checking
is much stronger that in C: You must return the type You've declared explicitly.
About Your code, You miss the most important thing: class declaration :-)
Mario

Re: Resource manager using thread pool in C++  
I was giving a further read in the resmgr_context_t structure, and I've realised that I can use it's own attribute IOV 
to return the values that I need.
About class declaration, it comes in the header, that I did not posted (see below).

#ifndef CMS_COMM_H_
#define CMS_COMM_H_


#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/neutrino.h>
#include <sys/dispatch.h>

class Comm
{
//****************************************************************************
//  Data structure
//****************************************************************************
public:
    typedef struct CommServer
    {
        //  How long without CAN reply for killing itself
        int timeout;
        //  Receive ID for it's COMM server role
        int comm_rcvid;
        //  Channel ID for it's CAN client role
        int can_coid;
        //  Message information
        char msg[6];
        //int msglen;

    } CommServerStruct;
//****************************************************************************
//  Thread pool lifecycle functions
//****************************************************************************
private:
    //  Context manipulation functions when thread is created and killed
    THREAD_POOL_PARAM_T * ContextAlloc(THREAD_POOL_HANDLE_T *handle);
    void ContextFree(THREAD_POOL_PARAM_T *param);
    //  Function to block waiting for a message from client
    THREAD_POOL_PARAM_T * WaitForMessage(THREAD_POOL_PARAM_T *ctp);
    //  For future versions
    void UnblockFunc(THREAD_POOL_PARAM_T *ctp);
    //  Message parsing function when unblocks with received message
    int ParseMessage(THREAD_POOL_PARAM_T *ctp);


    int comm_chid_;         //  Channel ID
    int can_chid;
//****************************************************************************
//  Thread pool lifecycle functions
//****************************************************************************

//****************************************************************************
//  Thread pool lifecycle functions
//****************************************************************************

public:
    int InitComm();
};


#endif
Re: Resource manager using thread pool in C++  
Sorry, a bit of repeated comments, as I'm still filling up the whole thing, but got stuck in those initial issues.

Thank you very much for the help anyway!
Re: Resource manager using thread pool in C++  
But still remains the question about setting the thread pool functions, since in C++ reference to callbacks are not as 
straight-forward as in C.

Re: Resource manager using thread pool in C++  
Hi, some trouble with Your sources: to use call backs, You must use static methods,
but in such case, You cannot access class members...
Maybe You should think to switch back to good old plain C :-)
Anyway, I've attached a example source: maybe it can help  (I've not test it)  :-)
Bye,
Mario

Attachment: Text fuffacpp.cc 6.79 KB
Re: Resource manager using thread pool in C++  
Thank you very much, Mario.

Will give a thorough study into it.

Cheers!