message passing and thread pools question

Hello anybody

We work with QNX Neutrino 6.1. We’re developing a bunch of processes
which communicate using standard message passing. We attach path names
using resmgr_attach, open them, and use the file descriptor in the
MsgSend call. We use thread pools which we initialize with the
dispatch_* functions, not as proposed in Mr. Krten’s book with the
resmgr_* functions. (If you want to be able to process incoming
messages, you have to do it that way, or am I wrong??)
It all works fine, until we try to exit a process which uses a thread
pool. I’m calling thread_pool_destroy() from my main thread (no, it’s
not a thread pool thread, I called thread_pool_create with flag = 0),
and this function never returns. When I call pidin arg, I can see all my
processes and their arguments, and the one that should have terminated
is still there without any arguments specified (it was started with
arguments, however) - sort of a zombie, I think.
My interpretation is that the thread pool threads don’t exit when you
use the dispatch_* functions instead of the resmgr_* functions. I tried
to terminate the threads with pthread_exit, which I called from an own
unblock function I specified in the thread pool attrs. The unblock
function was called, but pthread_exit as well as ThreadDestroy won’t
return, either.
So what can I do? I could switch to using devctl and the resmgr calls,
but I’d like to use simple message passing instead of that.

Any help or code snipplet is greatly appreciated!

Best regards
Hans

P.S. Here is my code, to clarify things.


#include <errno.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <pthread.h>
#include <process.h>
#include <fcntl.h>

#define THREAD_POOL_PARAM_T dispatch_context_t

#include <sys/neutrino.h>
#include <sys/iofunc.h>
#include <sys/dispatch.h>
#include <sys/resmgr.h>
#include <sys/netmgr.h>



in main()

// initialize dispatch interface
dispatchHdl=dispatch_create();
if(dispatchHdl==NULL) {
printf(“dispach hdl FAILURE\n”);
return EXIT_FAILURE;
}

// initialize resource manager attributes
memset(&resmgrAttr,0,sizeof resmgrAttr);
resmgrAttr.nparts_max = 1;
resmgrAttr.msg_max_size = 4096;

// initialize functions for handling messages

iofunc_func_init(_RESMGR_CONNECT_NFUNCS,&gConnectFuncs,_RESMGR_IO_NFUNCS,
&gIoFuncs);


// initialize attribute structure used by the device
iofunc_attr_init(&(gAttr),S_IFNAM | 0666, 0, 0);

// attach our device name
gPathnameId = resmgr_attach(dispatchHdl, &resmgrAttr, gMountPoint,
_FTYPE_ANY, 0, &gConnectFuncs, &gIoFuncs, &gAttr);
if(gPathnameId == -1) {
return EXIT_FAILURE;
}
// insert the length of the corresponding data structures in the
io_attr struct
gAttr.nbytes = 4096;


// attach a message callback handler
memset(&messageAttr,0,sizeof(messageAttr));
messageAttr.nparts_max = 1;
messageAttr.msg_max_size = 4096;
msgId = message_attach(dispatchHdl, &messageAttr, _IO_MAX+1,
_IO_MAX+256, pmtMessageCallback, NULL);
if(msgId == -1) {
return EXIT_FAILURE;
}
// initialize thread pool attributes
memset(&poolAttr, 0, sizeof poolAttr);
poolAttr.handle = dispatchHdl;
poolAttr.context_alloc = dispatch_context_alloc;
poolAttr.block_func = dispatch_block;
poolAttr.handler_func = dispatch_handler;
poolAttr.context_free = dispatch_context_free;
poolAttr.lo_water = cLoWaterThreads;
poolAttr.hi_water = cHiWaterThreads;
poolAttr.increment = 1;
poolAttr.maximum = 10;

// allocate a thread pool handle; don’t exit the main thread, it
becomes our data polling thread!
threadPoolHdl = thread_pool_create(&poolAttr, 0 );
if(threadPoolHdl == NULL) {
printf(“FAILURE\n”);
return EXIT_FAILURE;
}



// start the request worker thread pool
thread_pool_start(threadPoolHdl);

if(status != EOK) {
return EXIT_FAILURE;
}

// start the pmt loop
pmtLoop();
// to qdn: this call never returns!!!
if(thread_pool_destroy(threadPoolHdl)==-1) {
printf(“THREAD POOL DESTROY FAILURE\n”);
}
return EXIT_SUCCESS;
}

Hello again!

I solved my problem…

It was a combination of some minor bugs and undocumented things.

First of all, you can specify an unblock function for a thread pool; and
in my case you have to specify it. There is a dispatch_unblock() that
you can use directly in the pool_attrs.
Second, I started my thread with the P_NOWAIT flag. It terminated, and I
obviously didn’t do my waitpid() call in the right way… so I changed
the flag to P_NOWAITO, and my zombie disappeared. Now I check for the
pid of the process, which disappears as I expected it.

thanks for thinking about it, if you did already :slight_smile:

hans


Hello anybody

We work with QNX Neutrino 6.1. We’re developing a bunch of processes
which communicate using standard message passing. We attach path names
using resmgr_attach, open them, and use the file descriptor in the
MsgSend call. We use thread pools which we initialize with the
dispatch_* functions, not as proposed in Mr. Krten’s book with the
resmgr_* functions. (If you want to be able to process incoming
messages, you have to do it that way, or am I wrong??)
It all works fine, until we try to exit a process which uses a thread
pool. I’m calling thread_pool_destroy() from my main thread (no, it’s
not a thread pool thread, I called thread_pool_create with flag = 0),
and this function never returns. When I call pidin arg, I can see all my
processes and their arguments, and the one that should have terminated
is still there without any arguments specified (it was started with
arguments, however) - sort of a zombie, I think.
My interpretation is that the thread pool threads don’t exit when you
use the dispatch_* functions instead of the resmgr_* functions. I tried
to terminate the threads with pthread_exit, which I called from an own
unblock function I specified in the thread pool attrs. The unblock
function was called, but pthread_exit as well as ThreadDestroy won’t
return, either.
So what can I do? I could switch to using devctl and the resmgr calls,
but I’d like to use simple message passing instead of that.

Any help or code snipplet is greatly appreciated!

Best regards
Hans

P.S. Here is my code, to clarify things.


#include <errno.h
#include <stdio.h
#include <stddef.h
#include <stdlib.h
#include <time.h
#include <string.h
#include <pthread.h
#include <process.h
#include <fcntl.h

#define THREAD_POOL_PARAM_T dispatch_context_t

#include <sys/neutrino.h
#include <sys/iofunc.h
#include <sys/dispatch.h
#include <sys/resmgr.h
#include <sys/netmgr.h



in main()

// initialize dispatch interface
dispatchHdl=dispatch_create();
if(dispatchHdl==NULL) {
printf(“dispach hdl FAILURE\n”);
return EXIT_FAILURE;
}

// initialize resource manager attributes
memset(&resmgrAttr,0,sizeof resmgrAttr);
resmgrAttr.nparts_max = 1;
resmgrAttr.msg_max_size = 4096;

// initialize functions for handling messages

iofunc_func_init(_RESMGR_CONNECT_NFUNCS,&gConnectFuncs,_RESMGR_IO_NFUNCS,
&gIoFuncs);


// initialize attribute structure used by the device
iofunc_attr_init(&(gAttr),S_IFNAM | 0666, 0, 0);

// attach our device name
gPathnameId = resmgr_attach(dispatchHdl, &resmgrAttr, gMountPoint,
_FTYPE_ANY, 0, &gConnectFuncs, &gIoFuncs, &gAttr);
if(gPathnameId == -1) {
return EXIT_FAILURE;
}
// insert the length of the corresponding data structures in the
io_attr struct
gAttr.nbytes = 4096;


// attach a message callback handler
memset(&messageAttr,0,sizeof(messageAttr));
messageAttr.nparts_max = 1;
messageAttr.msg_max_size = 4096;
msgId = message_attach(dispatchHdl, &messageAttr, _IO_MAX+1,
_IO_MAX+256, pmtMessageCallback, NULL);
if(msgId == -1) {
return EXIT_FAILURE;
}
// initialize thread pool attributes
memset(&poolAttr, 0, sizeof poolAttr);
poolAttr.handle = dispatchHdl;
poolAttr.context_alloc = dispatch_context_alloc;
poolAttr.block_func = dispatch_block;
poolAttr.handler_func = dispatch_handler;
poolAttr.context_free = dispatch_context_free;
poolAttr.lo_water = cLoWaterThreads;
poolAttr.hi_water = cHiWaterThreads;
poolAttr.increment = 1;
poolAttr.maximum = 10;

// allocate a thread pool handle; don’t exit the main thread, it
becomes our data polling thread!
threadPoolHdl = thread_pool_create(&poolAttr, 0 );
if(threadPoolHdl == NULL) {
printf(“FAILURE\n”);
return EXIT_FAILURE;
}



// start the request worker thread pool
thread_pool_start(threadPoolHdl);

if(status != EOK) {
return EXIT_FAILURE;
}

// start the pmt loop
pmtLoop();
// to qdn: this call never returns!!!
if(thread_pool_destroy(threadPoolHdl)==-1) {
printf(“THREAD POOL DESTROY FAILURE\n”);
}
return EXIT_SUCCESS;
}