Hi,
the subject might suggest the message is an off-topic
for the list.
Actually this problem arose in the early stages of the analysis
and design of a software component that eventually could be
merged with the libraries that come with mod_rivet.
To put it simple my question is: can every module in APR be used
also to build standalone applications? More specifically: can
apr_global_mutex_* calls be used this way?
I'm still in the phase of familiarizing with some of modules
of APR, hence I've written a simple 'hello world' program
in which I can experiment with most of the stuff that will
go in the project.
The very first version of this program creates a global mutex
and wants to use it to synchronize access to a resource shared
between parent and child processes (a shared memory area)
I've found out that, when used this way,
apr_global_mutex_[lock|unlock|trylock] block forever. Why?
I also tried to unlock the mutex after it was created,
surmising the mutex could be created by _mutex_create
as locked, but also in this case
apr_global_mutex_unlock blocks and never returns.
The relevant calls are
apr_s = apr_global_mutex_create
(&mutex_c,MUTEX_NAME,APR_LOCK_DEFAULT,aPool);
if (apr_s != APR_SUCCESS)
{
fprintf(stderr,"damn....could not create the mutex\n");
exit(1);
}
fprintf (stderr,"mutex created\n");
...
/* copying mutex_c into mutex_p is just to have pointers with
different names in the child and parent code */
mutex_p = mutex_c;
cpid=fork();
if (cpid == 0)
{
/* child process */
apr_s = apr_global_mutex_child_init(&mutex_c,MUTEX_NAME,aPool);
if (apr_s != APR_SUCCESS)
{
fprintf (stderr,"...could not map the mutex...\n");
exit(1);
}
fprintf (stderr,"mutex '%s'
mapped\n",apr_global_mutex_name(mutex_p));
fprintf (stderr,"child attempts to lock on mutex...\n");
apr_s = apr_global_mutex_lock(mutex_c);
if (apr_s != APR_SUCCESS)
{
fprintf (stderr,"failed\n");
exit(1);
}
fprintf (stderr," child lock ok!\n");
.....
apr_s = apr_global_mutex_unlock(mutex_c);
if (apr_s != APR_SUCCESS)
{
fprintf (stderr,"mhhh....unlock fails...why?\n");
exit(1);
}
fprintf (stderr,"unlocked\n");
}
else
{
/* parent process */
int i;
sleep(2);
fprintf(stderr,"parent process attempts to lock...\n");
apr_s = apr_global_mutex_lock(mutex_p);
if (apr_s != APR_SUCCESS)
{
fprintf (stderr,"failed\n");
exit(1);
}
fprintf (stderr," parent lock ok!\n");
....
apr_s = apr_global_mutex_unlock(mutex_p);
if (apr_s != APR_SUCCESS)
{
fprintf (stderr,"mhhh....unlock fails...why?\n");
exit(1);
}
fprintf (stderr,"mutex unlocked\n");
}
basically the 2 process print the messages before attempting to
lock the mutex and then they stay indefinitely.
Am I missing something in the big picture of using APR
global mutexes? Thanks for any suggestion.
-- Massimo Manghi