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;
}