static apr_status_t proc_mutex_pthread_create()

in locks/unix/proc_mutex.c [580:686]


static apr_status_t proc_mutex_pthread_create(apr_proc_mutex_t *new_mutex,
                                              const char *fname)
{
    apr_status_t rv;
    int fd;
    pthread_mutexattr_t mattr;

    fd = open("/dev/zero", O_RDWR);
    if (fd < 0) {
        return errno;
    }

    new_mutex->os.pthread_interproc = mmap(NULL, sizeof(proc_pthread_mutex_t),
                                           PROT_READ | PROT_WRITE, MAP_SHARED,
                                           fd, 0);
    if (new_mutex->os.pthread_interproc == MAP_FAILED) {
        new_mutex->os.pthread_interproc = NULL;
        rv = errno;
        close(fd);
        return rv;
    }
    close(fd);

    new_mutex->pthread_refcounting = 1;
    new_mutex->curr_locked = -1; /* until the mutex has been created */
#if APR_USE_PROC_PTHREAD_MUTEX_COND
    proc_pthread_mutex_cond_locked(new_mutex) = -1;
#endif

    if ((rv = pthread_mutexattr_init(&mattr))) {
#ifdef HAVE_ZOS_PTHREADS
        rv = errno;
#endif
        proc_mutex_pthread_cleanup(new_mutex);
        return rv;
    }
    if ((rv = pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED))) {
#ifdef HAVE_ZOS_PTHREADS
        rv = errno;
#endif
        proc_mutex_pthread_cleanup(new_mutex);
        pthread_mutexattr_destroy(&mattr);
        return rv;
    }

#if defined(HAVE_PTHREAD_MUTEX_ROBUST) || defined(HAVE_PTHREAD_MUTEX_ROBUST_NP)
#ifdef HAVE_PTHREAD_MUTEX_ROBUST
    rv = pthread_mutexattr_setrobust(&mattr, PTHREAD_MUTEX_ROBUST);
#else
    rv = pthread_mutexattr_setrobust_np(&mattr, PTHREAD_MUTEX_ROBUST_NP);
#endif
    if (rv) {
#ifdef HAVE_ZOS_PTHREADS
        rv = errno;
#endif
        proc_mutex_pthread_cleanup(new_mutex);
        pthread_mutexattr_destroy(&mattr);
        return rv;
    }
    if ((rv = pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT))) {
#ifdef HAVE_ZOS_PTHREADS
        rv = errno;
#endif
        proc_mutex_pthread_cleanup(new_mutex);
        pthread_mutexattr_destroy(&mattr);
        return rv;
    }
#endif /* HAVE_PTHREAD_MUTEX_ROBUST[_NP] */

#if defined(APR_THREAD_DEBUG)
    /* ignore errors. */
    if ((rv = pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_ERRORCHECK))) {
#ifdef HAVE_ZOS_PTHREADS
        rv = errno;
#endif
        proc_mutex_pthread_cleanup(new_mutex);
        pthread_mutexattr_destroy(&mattr);
        return rv;
    }
#endif

    if ((rv = pthread_mutex_init(&proc_pthread_mutex(new_mutex), &mattr))) {
#ifdef HAVE_ZOS_PTHREADS
        rv = errno;
#endif
        proc_mutex_pthread_cleanup(new_mutex);
        pthread_mutexattr_destroy(&mattr);
        return rv;
    }

    proc_pthread_mutex_refcount(new_mutex) = 1; /* first/parent reference */
    new_mutex->curr_locked = 0; /* mutex created now */

    if ((rv = pthread_mutexattr_destroy(&mattr))) {
#ifdef HAVE_ZOS_PTHREADS
        rv = errno;
#endif
        proc_mutex_pthread_cleanup(new_mutex);
        return rv;
    }

    apr_pool_cleanup_register(new_mutex->pool,
                              (void *)new_mutex,
                              apr_proc_mutex_cleanup,
                              apr_pool_cleanup_null);
    return APR_SUCCESS;
}