1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include "apr_strings.h"
19 #include "apr_arch_proc_mutex.h"
20 #include "apr_arch_file_io.h" /* for apr_mkstemp() */
22 APR_DECLARE(apr_status_t) apr_proc_mutex_destroy(apr_proc_mutex_t *mutex)
24 return apr_pool_cleanup_run(mutex->pool, mutex, apr_proc_mutex_cleanup);
27 static apr_status_t proc_mutex_no_tryacquire(apr_proc_mutex_t *new_mutex)
32 #if APR_HAS_POSIXSEM_SERIALIZE
35 #define SEM_FAILED (-1)
38 static void proc_mutex_posix_setup(void)
42 static apr_status_t proc_mutex_posix_cleanup(void *mutex_)
44 apr_proc_mutex_t *mutex=mutex_;
45 apr_status_t stat = APR_SUCCESS;
47 if (mutex->interproc->filedes != -1) {
48 if (sem_close((sem_t *)mutex->interproc->filedes) < 0) {
55 static apr_status_t proc_mutex_posix_create(apr_proc_mutex_t *new_mutex,
65 new_mutex->interproc = apr_palloc(new_mutex->pool,
66 sizeof(*new_mutex->interproc));
67 new_mutex->interproc->filedes = -1;
69 * This bogusness is to follow what appears to be the
70 * lowest common denominator in Posix semaphore naming:
72 * - be at most 14 chars
73 * - be unique and not match anything on the filesystem
75 * Because of this, we ignore fname, and try our
76 * own naming system. We tuck the name away, since it might
77 * be useful for debugging. to make this as robust as possible,
78 * we initially try something larger (and hopefully more unique)
79 * and gracefully fail down to the LCD above.
81 * NOTE: Darwin (Mac OS X) seems to be the most restrictive
82 * implementation. Versions previous to Darwin 6.2 had the 14
83 * char limit, but later rev's allow up to 31 characters.
85 * FIXME: There is a small window of opportunity where
86 * instead of getting a new semaphore descriptor, we get
87 * a previously obtained one. This can happen if the requests
88 * are made at the "same time" and in the small span of time between
89 * the sem_open and the sem_unlink. Use of O_EXCL does not
90 * help here however...
94 sec = apr_time_sec(now);
95 usec = apr_time_usec(now);
96 apr_snprintf(semname, sizeof(semname), "/ApR.%lxZ%lx", sec, usec);
97 psem = sem_open((const char *) semname, O_CREAT, 0644, 1);
98 if ((psem == (sem_t *)SEM_FAILED) && (errno == ENAMETOOLONG)) {
99 /* Oh well, good try */
101 psem = sem_open((const char *) semname, O_CREAT, 0644, 1);
104 if (psem == (sem_t *)SEM_FAILED) {
106 proc_mutex_posix_cleanup(new_mutex);
109 /* Ahhh. The joys of Posix sems. Predelete it... */
110 sem_unlink((const char *) semname);
111 new_mutex->interproc->filedes = (int)psem; /* Ugg */
112 new_mutex->fname = apr_pstrdup(new_mutex->pool, semname);
113 apr_pool_cleanup_register(new_mutex->pool, (void *)new_mutex,
114 apr_proc_mutex_cleanup,
115 apr_pool_cleanup_null);
119 static apr_status_t proc_mutex_posix_acquire(apr_proc_mutex_t *mutex)
123 if ((rc = sem_wait((sem_t *)mutex->interproc->filedes)) < 0) {
126 mutex->curr_locked = 1;
130 static apr_status_t proc_mutex_posix_release(apr_proc_mutex_t *mutex)
134 mutex->curr_locked = 0;
135 if ((rc = sem_post((sem_t *)mutex->interproc->filedes)) < 0) {
141 static apr_status_t proc_mutex_posix_child_init(apr_proc_mutex_t **mutex,
148 const apr_proc_mutex_unix_lock_methods_t apr_proc_mutex_unix_posix_methods =
150 #if APR_PROCESS_LOCK_IS_GLOBAL || !APR_HAS_THREADS || defined(POSIXSEM_IS_GLOBAL)
151 APR_PROCESS_LOCK_MECH_IS_GLOBAL,
155 proc_mutex_posix_create,
156 proc_mutex_posix_acquire,
157 proc_mutex_no_tryacquire,
158 proc_mutex_posix_release,
159 proc_mutex_posix_cleanup,
160 proc_mutex_posix_child_init,
164 #endif /* Posix sem implementation */
166 #if APR_HAS_SYSVSEM_SERIALIZE
168 static struct sembuf proc_mutex_op_on;
169 static struct sembuf proc_mutex_op_off;
171 static void proc_mutex_sysv_setup(void)
173 proc_mutex_op_on.sem_num = 0;
174 proc_mutex_op_on.sem_op = -1;
175 proc_mutex_op_on.sem_flg = SEM_UNDO;
176 proc_mutex_op_off.sem_num = 0;
177 proc_mutex_op_off.sem_op = 1;
178 proc_mutex_op_off.sem_flg = SEM_UNDO;
181 static apr_status_t proc_mutex_sysv_cleanup(void *mutex_)
183 apr_proc_mutex_t *mutex=mutex_;
186 if (mutex->interproc->filedes != -1) {
188 semctl(mutex->interproc->filedes, 0, IPC_RMID, ick);
193 static apr_status_t proc_mutex_sysv_create(apr_proc_mutex_t *new_mutex,
199 new_mutex->interproc = apr_palloc(new_mutex->pool, sizeof(*new_mutex->interproc));
200 new_mutex->interproc->filedes = semget(IPC_PRIVATE, 1, IPC_CREAT | 0600);
202 if (new_mutex->interproc->filedes < 0) {
204 proc_mutex_sysv_cleanup(new_mutex);
208 if (semctl(new_mutex->interproc->filedes, 0, SETVAL, ick) < 0) {
210 proc_mutex_sysv_cleanup(new_mutex);
213 new_mutex->curr_locked = 0;
214 apr_pool_cleanup_register(new_mutex->pool,
215 (void *)new_mutex, apr_proc_mutex_cleanup,
216 apr_pool_cleanup_null);
220 static apr_status_t proc_mutex_sysv_acquire(apr_proc_mutex_t *mutex)
225 rc = semop(mutex->interproc->filedes, &proc_mutex_op_on, 1);
226 } while (rc < 0 && errno == EINTR);
230 mutex->curr_locked = 1;
234 static apr_status_t proc_mutex_sysv_release(apr_proc_mutex_t *mutex)
238 mutex->curr_locked = 0;
240 rc = semop(mutex->interproc->filedes, &proc_mutex_op_off, 1);
241 } while (rc < 0 && errno == EINTR);
248 static apr_status_t proc_mutex_sysv_child_init(apr_proc_mutex_t **mutex, apr_pool_t *cont, const char *fname)
253 const apr_proc_mutex_unix_lock_methods_t apr_proc_mutex_unix_sysv_methods =
255 #if APR_PROCESS_LOCK_IS_GLOBAL || !APR_HAS_THREADS || defined(SYSVSEM_IS_GLOBAL)
256 APR_PROCESS_LOCK_MECH_IS_GLOBAL,
260 proc_mutex_sysv_create,
261 proc_mutex_sysv_acquire,
262 proc_mutex_no_tryacquire,
263 proc_mutex_sysv_release,
264 proc_mutex_sysv_cleanup,
265 proc_mutex_sysv_child_init,
269 #endif /* SysV sem implementation */
271 #if APR_HAS_PROC_PTHREAD_SERIALIZE
273 static void proc_mutex_proc_pthread_setup(void)
277 static apr_status_t proc_mutex_proc_pthread_cleanup(void *mutex_)
279 apr_proc_mutex_t *mutex=mutex_;
282 if (mutex->curr_locked == 1) {
283 if ((rv = pthread_mutex_unlock(mutex->pthread_interproc))) {
284 #ifdef PTHREAD_SETS_ERRNO
289 if (munmap((caddr_t)mutex->pthread_interproc, sizeof(pthread_mutex_t))){
296 static apr_status_t proc_mutex_proc_pthread_create(apr_proc_mutex_t *new_mutex,
301 pthread_mutexattr_t mattr;
303 fd = open("/dev/zero", O_RDWR);
308 new_mutex->pthread_interproc = (pthread_mutex_t *)mmap(
310 sizeof(pthread_mutex_t),
311 PROT_READ | PROT_WRITE, MAP_SHARED,
313 if (new_mutex->pthread_interproc == (pthread_mutex_t *) (caddr_t) -1) {
317 if ((rv = pthread_mutexattr_init(&mattr))) {
318 #ifdef PTHREAD_SETS_ERRNO
321 proc_mutex_proc_pthread_cleanup(new_mutex);
324 if ((rv = pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED))) {
325 #ifdef PTHREAD_SETS_ERRNO
328 proc_mutex_proc_pthread_cleanup(new_mutex);
332 #ifdef HAVE_PTHREAD_MUTEX_ROBUST
333 if ((rv = pthread_mutexattr_setrobust_np(&mattr,
334 PTHREAD_MUTEX_ROBUST_NP))) {
335 #ifdef PTHREAD_SETS_ERRNO
338 proc_mutex_proc_pthread_cleanup(new_mutex);
341 if ((rv = pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT))) {
342 #ifdef PTHREAD_SETS_ERRNO
345 proc_mutex_proc_pthread_cleanup(new_mutex);
348 #endif /* HAVE_PTHREAD_MUTEX_ROBUST */
350 if ((rv = pthread_mutex_init(new_mutex->pthread_interproc, &mattr))) {
351 #ifdef PTHREAD_SETS_ERRNO
354 proc_mutex_proc_pthread_cleanup(new_mutex);
358 if ((rv = pthread_mutexattr_destroy(&mattr))) {
359 #ifdef PTHREAD_SETS_ERRNO
362 proc_mutex_proc_pthread_cleanup(new_mutex);
366 new_mutex->curr_locked = 0;
367 apr_pool_cleanup_register(new_mutex->pool,
369 apr_proc_mutex_cleanup,
370 apr_pool_cleanup_null);
374 static apr_status_t proc_mutex_proc_pthread_acquire(apr_proc_mutex_t *mutex)
378 if ((rv = pthread_mutex_lock(mutex->pthread_interproc))) {
379 #ifdef PTHREAD_SETS_ERRNO
382 #ifdef HAVE_PTHREAD_MUTEX_ROBUST
383 /* Okay, our owner died. Let's try to make it consistent again. */
384 if (rv == EOWNERDEAD) {
385 pthread_mutex_consistent_np(mutex->pthread_interproc);
393 mutex->curr_locked = 1;
397 /* TODO: Add proc_mutex_proc_pthread_tryacquire(apr_proc_mutex_t *mutex) */
399 static apr_status_t proc_mutex_proc_pthread_release(apr_proc_mutex_t *mutex)
403 mutex->curr_locked = 0;
404 if ((rv = pthread_mutex_unlock(mutex->pthread_interproc))) {
405 #ifdef PTHREAD_SETS_ERRNO
413 static apr_status_t proc_mutex_proc_pthread_child_init(apr_proc_mutex_t **mutex,
420 const apr_proc_mutex_unix_lock_methods_t apr_proc_mutex_unix_proc_pthread_methods =
422 APR_PROCESS_LOCK_MECH_IS_GLOBAL,
423 proc_mutex_proc_pthread_create,
424 proc_mutex_proc_pthread_acquire,
425 proc_mutex_no_tryacquire,
426 proc_mutex_proc_pthread_release,
427 proc_mutex_proc_pthread_cleanup,
428 proc_mutex_proc_pthread_child_init,
434 #if APR_HAS_FCNTL_SERIALIZE
436 static struct flock proc_mutex_lock_it;
437 static struct flock proc_mutex_unlock_it;
439 static apr_status_t proc_mutex_fcntl_release(apr_proc_mutex_t *);
441 static void proc_mutex_fcntl_setup(void)
443 proc_mutex_lock_it.l_whence = SEEK_SET; /* from current point */
444 proc_mutex_lock_it.l_start = 0; /* -"- */
445 proc_mutex_lock_it.l_len = 0; /* until end of file */
446 proc_mutex_lock_it.l_type = F_WRLCK; /* set exclusive/write lock */
447 proc_mutex_lock_it.l_pid = 0; /* pid not actually interesting */
448 proc_mutex_unlock_it.l_whence = SEEK_SET; /* from current point */
449 proc_mutex_unlock_it.l_start = 0; /* -"- */
450 proc_mutex_unlock_it.l_len = 0; /* until end of file */
451 proc_mutex_unlock_it.l_type = F_UNLCK; /* set exclusive/write lock */
452 proc_mutex_unlock_it.l_pid = 0; /* pid not actually interesting */
455 static apr_status_t proc_mutex_fcntl_cleanup(void *mutex_)
458 apr_proc_mutex_t *mutex=mutex_;
460 if (mutex->curr_locked == 1) {
461 status = proc_mutex_fcntl_release(mutex);
462 if (status != APR_SUCCESS)
465 if (mutex->interproc) { /* if it was opened successfully */
466 apr_file_close(mutex->interproc);
471 static apr_status_t proc_mutex_fcntl_create(apr_proc_mutex_t *new_mutex,
477 new_mutex->fname = apr_pstrdup(new_mutex->pool, fname);
478 rv = apr_file_open(&new_mutex->interproc, new_mutex->fname,
479 APR_CREATE | APR_WRITE | APR_EXCL,
480 APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD,
484 new_mutex->fname = apr_pstrdup(new_mutex->pool, "/tmp/aprXXXXXX");
485 rv = apr_file_mktemp(&new_mutex->interproc, new_mutex->fname,
486 APR_CREATE | APR_WRITE | APR_EXCL,
490 if (rv != APR_SUCCESS) {
491 proc_mutex_fcntl_cleanup(new_mutex);
495 new_mutex->curr_locked = 0;
496 unlink(new_mutex->fname);
497 apr_pool_cleanup_register(new_mutex->pool,
499 apr_proc_mutex_cleanup,
500 apr_pool_cleanup_null);
504 static apr_status_t proc_mutex_fcntl_acquire(apr_proc_mutex_t *mutex)
509 rc = fcntl(mutex->interproc->filedes, F_SETLKW, &proc_mutex_lock_it);
510 } while (rc < 0 && errno == EINTR);
514 mutex->curr_locked=1;
518 static apr_status_t proc_mutex_fcntl_release(apr_proc_mutex_t *mutex)
522 mutex->curr_locked=0;
524 rc = fcntl(mutex->interproc->filedes, F_SETLKW, &proc_mutex_unlock_it);
525 } while (rc < 0 && errno == EINTR);
532 static apr_status_t proc_mutex_fcntl_child_init(apr_proc_mutex_t **mutex,
539 const apr_proc_mutex_unix_lock_methods_t apr_proc_mutex_unix_fcntl_methods =
541 #if APR_PROCESS_LOCK_IS_GLOBAL || !APR_HAS_THREADS || defined(FCNTL_IS_GLOBAL)
542 APR_PROCESS_LOCK_MECH_IS_GLOBAL,
546 proc_mutex_fcntl_create,
547 proc_mutex_fcntl_acquire,
548 proc_mutex_no_tryacquire,
549 proc_mutex_fcntl_release,
550 proc_mutex_fcntl_cleanup,
551 proc_mutex_fcntl_child_init,
555 #endif /* fcntl implementation */
557 #if APR_HAS_FLOCK_SERIALIZE
559 static apr_status_t proc_mutex_flock_release(apr_proc_mutex_t *);
561 static void proc_mutex_flock_setup(void)
565 static apr_status_t proc_mutex_flock_cleanup(void *mutex_)
568 apr_proc_mutex_t *mutex=mutex_;
570 if (mutex->curr_locked == 1) {
571 status = proc_mutex_flock_release(mutex);
572 if (status != APR_SUCCESS)
575 if (mutex->interproc) { /* if it was opened properly */
576 apr_file_close(mutex->interproc);
578 unlink(mutex->fname);
582 static apr_status_t proc_mutex_flock_create(apr_proc_mutex_t *new_mutex,
588 new_mutex->fname = apr_pstrdup(new_mutex->pool, fname);
589 rv = apr_file_open(&new_mutex->interproc, new_mutex->fname,
590 APR_CREATE | APR_WRITE | APR_EXCL,
591 APR_UREAD | APR_UWRITE,
595 new_mutex->fname = apr_pstrdup(new_mutex->pool, "/tmp/aprXXXXXX");
596 rv = apr_file_mktemp(&new_mutex->interproc, new_mutex->fname,
597 APR_CREATE | APR_WRITE | APR_EXCL,
601 if (rv != APR_SUCCESS) {
602 proc_mutex_flock_cleanup(new_mutex);
605 new_mutex->curr_locked = 0;
606 apr_pool_cleanup_register(new_mutex->pool, (void *)new_mutex,
607 apr_proc_mutex_cleanup,
608 apr_pool_cleanup_null);
612 static apr_status_t proc_mutex_flock_acquire(apr_proc_mutex_t *mutex)
617 rc = flock(mutex->interproc->filedes, LOCK_EX);
618 } while (rc < 0 && errno == EINTR);
622 mutex->curr_locked = 1;
626 static apr_status_t proc_mutex_flock_release(apr_proc_mutex_t *mutex)
630 mutex->curr_locked = 0;
632 rc = flock(mutex->interproc->filedes, LOCK_UN);
633 } while (rc < 0 && errno == EINTR);
640 static apr_status_t proc_mutex_flock_child_init(apr_proc_mutex_t **mutex,
644 apr_proc_mutex_t *new_mutex;
647 new_mutex = (apr_proc_mutex_t *)apr_palloc(pool, sizeof(apr_proc_mutex_t));
649 memcpy(new_mutex, *mutex, sizeof *new_mutex);
650 new_mutex->pool = pool;
652 fname = (*mutex)->fname;
654 new_mutex->fname = apr_pstrdup(pool, fname);
655 rv = apr_file_open(&new_mutex->interproc, new_mutex->fname,
656 APR_WRITE, 0, new_mutex->pool);
657 if (rv != APR_SUCCESS) {
658 proc_mutex_flock_cleanup(new_mutex);
665 const apr_proc_mutex_unix_lock_methods_t apr_proc_mutex_unix_flock_methods =
667 #if APR_PROCESS_LOCK_IS_GLOBAL || !APR_HAS_THREADS || defined(FLOCK_IS_GLOBAL)
668 APR_PROCESS_LOCK_MECH_IS_GLOBAL,
672 proc_mutex_flock_create,
673 proc_mutex_flock_acquire,
674 proc_mutex_no_tryacquire,
675 proc_mutex_flock_release,
676 proc_mutex_flock_cleanup,
677 proc_mutex_flock_child_init,
681 #endif /* flock implementation */
683 void apr_proc_mutex_unix_setup_lock(void)
685 #if APR_HAS_POSIXSEM_SERIALIZE
686 proc_mutex_posix_setup();
688 #if APR_HAS_SYSVSEM_SERIALIZE
689 proc_mutex_sysv_setup();
691 #if APR_HAS_PROC_PTHREAD_SERIALIZE
692 proc_mutex_proc_pthread_setup();
694 #if APR_HAS_FCNTL_SERIALIZE
695 proc_mutex_fcntl_setup();
697 #if APR_HAS_FLOCK_SERIALIZE
698 proc_mutex_flock_setup();
702 static apr_status_t proc_mutex_choose_method(apr_proc_mutex_t *new_mutex, apr_lockmech_e mech)
706 #if APR_HAS_FCNTL_SERIALIZE
707 new_mutex->inter_meth = &apr_proc_mutex_unix_fcntl_methods;
713 #if APR_HAS_FLOCK_SERIALIZE
714 new_mutex->inter_meth = &apr_proc_mutex_unix_flock_methods;
719 case APR_LOCK_SYSVSEM:
720 #if APR_HAS_SYSVSEM_SERIALIZE
721 new_mutex->inter_meth = &apr_proc_mutex_unix_sysv_methods;
726 case APR_LOCK_POSIXSEM:
727 #if APR_HAS_POSIXSEM_SERIALIZE
728 new_mutex->inter_meth = &apr_proc_mutex_unix_posix_methods;
733 case APR_LOCK_PROC_PTHREAD:
734 #if APR_HAS_PROC_PTHREAD_SERIALIZE
735 new_mutex->inter_meth = &apr_proc_mutex_unix_proc_pthread_methods;
740 case APR_LOCK_DEFAULT:
741 #if APR_USE_FLOCK_SERIALIZE
742 new_mutex->inter_meth = &apr_proc_mutex_unix_flock_methods;
743 #elif APR_USE_SYSVSEM_SERIALIZE
744 new_mutex->inter_meth = &apr_proc_mutex_unix_sysv_methods;
745 #elif APR_USE_FCNTL_SERIALIZE
746 new_mutex->inter_meth = &apr_proc_mutex_unix_fcntl_methods;
747 #elif APR_USE_PROC_PTHREAD_SERIALIZE
748 new_mutex->inter_meth = &apr_proc_mutex_unix_proc_pthread_methods;
749 #elif APR_USE_POSIXSEM_SERIALIZE
750 new_mutex->inter_meth = &apr_proc_mutex_unix_posix_methods;
761 APR_DECLARE(const char *) apr_proc_mutex_defname(void)
764 apr_proc_mutex_t mutex;
766 if ((rv = proc_mutex_choose_method(&mutex, APR_LOCK_DEFAULT)) != APR_SUCCESS) {
769 mutex.meth = mutex.inter_meth;
771 return apr_proc_mutex_name(&mutex);
774 static apr_status_t proc_mutex_create(apr_proc_mutex_t *new_mutex, apr_lockmech_e mech, const char *fname)
778 if ((rv = proc_mutex_choose_method(new_mutex, mech)) != APR_SUCCESS) {
782 new_mutex->meth = new_mutex->inter_meth;
784 if ((rv = new_mutex->meth->create(new_mutex, fname)) != APR_SUCCESS) {
791 APR_DECLARE(apr_status_t) apr_proc_mutex_create(apr_proc_mutex_t **mutex,
796 apr_proc_mutex_t *new_mutex;
799 new_mutex = (apr_proc_mutex_t *)apr_pcalloc(pool,
800 sizeof(apr_proc_mutex_t));
802 new_mutex->pool = pool;
803 #if APR_HAS_SYSVSEM_SERIALIZE || APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE || APR_HAS_POSIXSEM_SERIALIZE
804 new_mutex->interproc = NULL;
807 if ((rv = proc_mutex_create(new_mutex, mech, fname)) != APR_SUCCESS)
814 APR_DECLARE(apr_status_t) apr_proc_mutex_child_init(apr_proc_mutex_t **mutex,
818 return (*mutex)->meth->child_init(mutex, pool, fname);
821 APR_DECLARE(apr_status_t) apr_proc_mutex_lock(apr_proc_mutex_t *mutex)
823 return mutex->meth->acquire(mutex);
826 APR_DECLARE(apr_status_t) apr_proc_mutex_trylock(apr_proc_mutex_t *mutex)
828 return mutex->meth->tryacquire(mutex);
831 APR_DECLARE(apr_status_t) apr_proc_mutex_unlock(apr_proc_mutex_t *mutex)
833 return mutex->meth->release(mutex);
836 APR_DECLARE(apr_status_t) apr_proc_mutex_cleanup(void *mutex)
838 return ((apr_proc_mutex_t *)mutex)->meth->cleanup(mutex);
841 APR_DECLARE(const char *) apr_proc_mutex_name(apr_proc_mutex_t *mutex)
843 return mutex->meth->name;
846 APR_DECLARE(const char *) apr_proc_mutex_lockfile(apr_proc_mutex_t *mutex)
848 /* posix sems use the fname field but don't use a file,
851 if (!strcmp(mutex->meth->name, "flock") ||
852 !strcmp(mutex->meth->name, "fcntl")) {
858 APR_POOL_IMPLEMENT_ACCESSOR(proc_mutex)
860 /* Implement OS-specific accessors defined in apr_portable.h */
862 APR_DECLARE(apr_status_t) apr_os_proc_mutex_get(apr_os_proc_mutex_t *ospmutex,
863 apr_proc_mutex_t *pmutex)
865 #if APR_HAS_SYSVSEM_SERIALIZE || APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE || APR_HAS_POSIXSEM_SERIALIZE
866 ospmutex->crossproc = pmutex->interproc->filedes;
868 #if APR_HAS_PROC_PTHREAD_SERIALIZE
869 ospmutex->pthread_interproc = pmutex->pthread_interproc;
874 APR_DECLARE(apr_status_t) apr_os_proc_mutex_put(apr_proc_mutex_t **pmutex,
875 apr_os_proc_mutex_t *ospmutex,
881 if ((*pmutex) == NULL) {
882 (*pmutex) = (apr_proc_mutex_t *)apr_pcalloc(pool,
883 sizeof(apr_proc_mutex_t));
884 (*pmutex)->pool = pool;
886 #if APR_HAS_SYSVSEM_SERIALIZE || APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE || APR_HAS_POSIXSEM_SERIALIZE
887 apr_os_file_put(&(*pmutex)->interproc, &ospmutex->crossproc, 0, pool);
889 #if APR_HAS_PROC_PTHREAD_SERIALIZE
890 (*pmutex)->pthread_interproc = ospmutex->pthread_interproc;