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

Reply via email to