Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Robust lock #262

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -254,3 +254,11 @@ win32/phpts.def
win32/wsyslog.h
win32/win32.dsp
win32/php.dsw

Makefile.global
acinclude.m4
apc_lock.loT
build/
configure.in
ltmain.sh
run-tests.php
3 changes: 1 addition & 2 deletions apc.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,8 @@ PHP_APCU_API int APC_UNSERIALIZER_NAME(eval) (APC_UNSERIALIZER_ARGS); /* }}} */
JMP_BUF *zb = EG(bailout); \
JMP_BUF ab; \
\
EG(bailout) = &ab; \
\
begin; \
EG(bailout) = &ab; \
if (SETJMP(ab) == SUCCESS) { \
block \
} else { \
Expand Down
52 changes: 36 additions & 16 deletions apc_lock.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,18 +120,24 @@ PHP_APCU_API zend_bool apc_lock_init() {
#ifndef APC_SPIN_LOCK
# ifndef APC_FCNTL_LOCK
# ifdef APC_LOCK_RECURSIVE
if (pthread_mutexattr_init(&apc_lock_attr) == SUCCESS) {
if (pthread_mutexattr_setpshared(&apc_lock_attr, PTHREAD_PROCESS_SHARED) == SUCCESS) {
pthread_mutexattr_settype(&apc_lock_attr, PTHREAD_MUTEX_RECURSIVE);
return 1;
}
}
if (pthread_mutexattr_init(&apc_lock_attr) == SUCCESS) {
if (pthread_mutexattr_setpshared(&apc_lock_attr, PTHREAD_PROCESS_SHARED) == SUCCESS) {
pthread_mutexattr_settype(&apc_lock_attr, PTHREAD_MUTEX_RECURSIVE);
#ifdef APC_LOCK_ROBUST
pthread_mutexattr_setrobust(&apc_lock_attr, PTHREAD_MUTEX_ROBUST);
#endif
return 1;
}
}
# else
if (pthread_rwlockattr_init(&apc_lock_attr) == SUCCESS) {
if (pthread_rwlockattr_setpshared(&apc_lock_attr, PTHREAD_PROCESS_SHARED) == SUCCESS) {
return 1;
}
}
if (pthread_rwlockattr_init(&apc_lock_attr) == SUCCESS) {
if (pthread_rwlockattr_setpshared(&apc_lock_attr, PTHREAD_PROCESS_SHARED) == SUCCESS) {
#ifdef APC_LOCK_ROBUST
pthread_mutexattr_setrobust(&apc_lock_attr, PTHREAD_MUTEX_ROBUST);
#endif
return 1;
}
}
# endif
# endif
#endif
Expand Down Expand Up @@ -212,11 +218,18 @@ PHP_APCU_API zend_bool apc_lock_rlock(apc_lock_t *lock) {
#ifndef PHP_WIN32
#ifndef APC_SPIN_LOCK
# ifndef APC_FCNTL_LOCK
int result;
# ifdef APC_LOCK_RECURSIVE
pthread_mutex_lock(lock);
result = pthread_mutex_lock(lock);
# else
pthread_rwlock_rdlock(lock);
# endif
result = pthread_rwlock_rdlock(lock);
# endif
# ifdef APC_LOCK_ROBUST
if (result != SUCCESS)
{
return 0;
}
# endif
# else
{
/* FCNTL */
Expand All @@ -239,10 +252,17 @@ PHP_APCU_API zend_bool apc_lock_wlock(apc_lock_t *lock) {
#ifndef PHP_WIN32
#ifndef APC_SPIN_LOCK
# ifndef APC_FCNTL_LOCK
int result;
# ifdef APC_LOCK_RECURSIVE
pthread_mutex_lock(lock);
result = pthread_mutex_lock(lock);
# else
pthread_rwlock_wrlock(lock);
result = pthread_rwlock_wrlock(lock);
# endif
# ifdef APC_LOCK_ROBUST
if (result != SUCCESS)
{
return 0;
}
# endif
# else
{
Expand Down
10 changes: 8 additions & 2 deletions apc_lock_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
# include "pthread.h"
# ifndef APC_SPIN_LOCK
# ifndef APC_FCNTL_LOCK
# if defined(APC_NATIVE_RWLOCK) && defined(HAVE_ATOMIC_OPERATIONS)
# if defined(APC_NATIVE_RWLOCK) && defined(HAVE_ATOMIC_OPERATIONS) && !defined(APC_LOCK_ROBUST)
typedef pthread_rwlock_t apc_lock_t;
# define APC_LOCK_SHARED
# else
Expand Down Expand Up @@ -86,9 +86,15 @@ PHP_APCU_API void apc_lock_destroy(apc_lock_t *lock); /* }}} */
/* {{{ generic locking macros */
#define CREATE_LOCK(lock) apc_lock_create(lock)
#define DESTROY_LOCK(lock) apc_lock_destroy(lock)

#ifdef APC_LOCK_ROBUST
#define WLOCK(lock) { HANDLE_BLOCK_INTERRUPTIONS(); if(!apc_lock_wlock(lock)){apc_error("inconsistent memory");} }
#define RLOCK(lock) { HANDLE_BLOCK_INTERRUPTIONS(); if(!apc_lock_rlock(lock)){apc_error("inconsistent memory");} }
#else
#define WLOCK(lock) { HANDLE_BLOCK_INTERRUPTIONS(); apc_lock_wlock(lock); }
#define WUNLOCK(lock) { apc_lock_wunlock(lock); HANDLE_UNBLOCK_INTERRUPTIONS(); }
#define RLOCK(lock) { HANDLE_BLOCK_INTERRUPTIONS(); apc_lock_rlock(lock); }
#endif
#define WUNLOCK(lock) { apc_lock_wunlock(lock); HANDLE_UNBLOCK_INTERRUPTIONS(); }
#define RUNLOCK(lock) { apc_lock_runlock(lock); HANDLE_UNBLOCK_INTERRUPTIONS(); }
#define LOCK WLOCK
#define UNLOCK WUNLOCK
Expand Down
16 changes: 16 additions & 0 deletions config.m4
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@ AC_ARG_ENABLE(apcu-rwlocks,
AC_MSG_RESULT(yes)
])

AC_MSG_CHECKING(if APCu should use robust locking)
AC_ARG_ENABLE(apcu-robust,
[ --enable-apcu-robust Enable APCu robust locking],
[
PHP_APCU_ROBUST=$enableval
],
[
PHP_APCU_ROBUST=no
])
AC_MSG_RESULT($PHP_APCU_ROBUST)

AC_MSG_CHECKING(if APCu should be built in debug mode)
AC_ARG_ENABLE(apcu-debug,
[ --enable-apcu-debug Enable APCu debugging],
Expand Down Expand Up @@ -204,6 +215,11 @@ if test "$PHP_APCU" != "no"; then
LIBS="$orig_LIBS"
fi

if test "$PHP_APCU_ROBUST" != "no"; then
AC_DEFINE(APC_LOCK_ROBUST, 1, [ ])
AC_MSG_WARN([APCu robust locking enabled])
fi

if test "$PHP_APCU_RWLOCKS" == "no"; then
if test "$PHP_APCU_MUTEX" == "no"; then
if test "$PHP_APCU_SPINLOCK" != "no"; then
Expand Down