apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Chris Darroch <chr...@pearsoncmg.com>
Subject Re: [PATCH] trial implementation of proc_pthread trylock
Date Mon, 16 Sep 2002 21:57:10 GMT
Aaron Bannert wrote:

> On Thu, Aug 22, 2002 at 03:59:24PM -0400, Chris Darroch wrote:


>>   The proc_mutex_proc_pthread_acquire() function seems to
>>suck up the EOWNERDEAD return value, setting the curr_locked flag
>>to 1 and returning APR_SUCCESS, so that's what I made the tryacquire
>>case do also.
>>   However, it seems to me that this behaviour, for both functions,
>>might not be too helpful for callers, since any data they
>>are protecting with our lock might be in an inconsistent state,
>>but they'd have no way of determining that from our return value.
>>Maybe we should invent an APR_EOWNERDEAD value and return that?
> You are correct, but we can't invent an APR_EOWNERDEAD unless that
> semantic is portable, which I don't believe it is. What happens to
> a mutex right now when the owner dies, on platforms that don't have
> pthread_mutex_consistent_np()?
> I'm all for implementing trylock where possible, but I'm not comfortable
> introducing non-posix/non-portable pthread calls.

    Sorry to take so long testing this out ... had a deadline
in the meantime.  On my Solaris 8 box -- only type I have access to --
the behaviour seems to be as follows.  I'm using the Sun WorkShop 6,
update 2, C 5.3 cc compiler.

    The code I used for testing is appeneded below.  It tries the
four (of five) process lock types that have apr.h defines as valid
on my platform -- APR_USE_FLOCK_SERIALIZE is 0, so I can't test that
one (easily, anyway).

    The little process below creates a process lock using standard
apr_proc_mutex_create(), forks a child, and then both parent and
child try to acquire a lock with apr_proc_mutex_lock().  The parent
waits a bit so the child always goes first.  (Note that I'm just
testing the standard lock behaviour, not any kind of experimental
trylock implementation.)

    I can then let the process run, or kill the child with good ole
"kill -9", and see what happens.  The results are as follows:

1) APR_LOCK_PROC_PTHREAD (default on Solaris 8):
    OK in both cases.  Killing the child results in immediate lock
    by the parent, with no status report.  As expected.

    OK in both cases, as above for APR_LOCK_PROC_PTHREAD.

    Letting the process run normally results in error reports from
    the parent:

unable to lock lock: 36, Identifier removed
unable to unlock lock: 22, Invalid argument

    Interestingly, killing the child causes the parent to run normally
    without reporting any errors.


    OK in the normal case.  Parent hangs when the child process is

    So (3) and (4) have sort-of reversed behaviour, and neither seems
consistent with (1) or (2).

    My sense, then, is that things might not be quite as portable
as could be desired -- leaving aside entirely the question of
whether or not to implement apr_proc_mutex_trylock().  If others could
try this on different platforms, especially using the
default APR lock type, that would be enlightening.

    I'm not sure what a good solution is, because I'm not sure if
all these lock types -- on different platforms -- can be made to
detect, or not detect, the death of the process that holds the lock.


#include <stdio.h>
#include <stdlib.h>
#include "apr_general.h"
#include "apr_pools.h"
#include "apr_proc_mutex.h"

int main(int argc, const char * const *argv)
     apr_status_t s;
     apr_pool_t *p;
     apr_proc_mutex_t *l;
     char buf[100];
     int pid;
     int i;

     apr_app_initialize(&argc, &argv, NULL);

     apr_pool_create(&p, NULL);

     /**** DEBUG: try one of APR_LOCK_FLOCK, APR_LOCK_FCNTL,

     s = apr_proc_mutex_create(&l, "/path/to/non/NFS/volume",
         APR_LOCK_SYSVSEM, p);
         fprintf(stderr, "unable to create lock: %d, %s", (int) s,
             apr_strerror(s, buf, 100));

     printf("lock name: %s\n", apr_proc_mutex_name(l));

     if((pid = fork()) == -1)
         fprintf(stderr, "unable to fork");


     s = apr_proc_mutex_lock(l);
         fprintf(stderr, "unable to lock lock: %d, %s", (int) s,
             apr_strerror(s, buf, 100));

         printf("parent (child: %d)\n", pid);

     for(i = 0; i < 20; ++i)
         printf("%d\n", i);

     s = apr_proc_mutex_unlock(l);
         fprintf(stderr, "unable to unlock lock: %d, %s", (int) s,
             apr_strerror(s, buf, 100));


     s = apr_proc_mutex_destroy(l);
         fprintf(stderr, "unable to destroy lock: %d, %s", (int) s,
             apr_strerror(s, buf, 100));


View raw message