diff --git a/.gitignore b/.gitignore index cf615c6e..52907c51 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/apc.h b/apc.h index abd72824..9e4a81aa 100644 --- a/apc.h +++ b/apc.h @@ -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 { \ diff --git a/apc_lock.c b/apc_lock.c index 80697a41..c09ad540 100644 --- a/apc_lock.c +++ b/apc_lock.c @@ -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 @@ -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 */ @@ -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 { diff --git a/apc_lock_api.h b/apc_lock_api.h index 2a6e7793..18cabbf5 100644 --- a/apc_lock_api.h +++ b/apc_lock_api.h @@ -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 @@ -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 diff --git a/config.m4 b/config.m4 index b2b836a8..6ade7ef6 100644 --- a/config.m4 +++ b/config.m4 @@ -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], @@ -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