|
|
|
@ -11,25 +11,43 @@
|
|
|
|
|
# include <errno.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* {{{ detect what lock to use */
|
|
|
|
|
#undef XC_INTERPROCESS_LOCK_IMPLEMENTED
|
|
|
|
|
#undef XC_LOCK_UNSUED
|
|
|
|
|
/* {{{ detect what type of lock is needed */
|
|
|
|
|
#ifdef ZTS
|
|
|
|
|
# define XC_LOCK_NEED_TS
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef ZEND_WIN32
|
|
|
|
|
# define XC_INTERPROCESS_LOCK_IMPLEMENTED
|
|
|
|
|
# ifndef ZTS
|
|
|
|
|
# define XC_LOCK_UNSUED
|
|
|
|
|
# endif
|
|
|
|
|
#ifndef ZEND_WIN32
|
|
|
|
|
# define XC_LOCK_NEED_INTERPROCESS
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef _POSIX_THREAD_PROCESS_SHARED
|
|
|
|
|
# include "../mod_cacher/xc_cache.h"
|
|
|
|
|
# define XC_INTERPROCESS_LOCK_IMPLEMENTED
|
|
|
|
|
#if defined(XC_LOCK_NEED_TS) && defined(XC_LOCK_NEED_INTERPROCESS)
|
|
|
|
|
/* allow switching off interprocess support */
|
|
|
|
|
# define XC_LOCK_HAVE_INTERPROCESS_SWITCH
|
|
|
|
|
#endif
|
|
|
|
|
/* }}} */
|
|
|
|
|
|
|
|
|
|
#ifndef XC_INTERPROCESS_LOCK_IMPLEMENTED
|
|
|
|
|
/* {{{ detect which lock is needed */
|
|
|
|
|
#if defined(XC_LOCK_NEED_TS) && defined(XC_LOCK_NEED_INTERPROCESS)
|
|
|
|
|
# ifdef PTHREAD
|
|
|
|
|
# define XC_LOCK_USE_PTHREAD
|
|
|
|
|
# ifndef _POSIX_THREAD_PROCESS_SHARED
|
|
|
|
|
# define XC_LOCK_USE_FCNTL
|
|
|
|
|
# endif
|
|
|
|
|
# else
|
|
|
|
|
# define XC_LOCK_USE_TSRM
|
|
|
|
|
# define XC_LOCK_USE_FCNTL
|
|
|
|
|
# endif
|
|
|
|
|
#elif defined(XC_LOCK_NEED_TS)
|
|
|
|
|
# define XC_LOCK_USE_TSRM
|
|
|
|
|
#elif defined(XC_LOCK_NEED_INTERPROCESS)
|
|
|
|
|
# define XC_LOCK_USE_FCNTL
|
|
|
|
|
#else
|
|
|
|
|
# define XC_LOCK_USE_NOOP
|
|
|
|
|
#endif
|
|
|
|
|
/* }}} */
|
|
|
|
|
|
|
|
|
|
/* {{{ fcntl lock impl */
|
|
|
|
|
#ifdef XC_LOCK_USE_FCNTL
|
|
|
|
|
#ifndef ZEND_WIN32
|
|
|
|
|
typedef int HANDLE;
|
|
|
|
|
# ifndef INVALID_HANDLE_VALUE
|
|
|
|
@ -51,7 +69,6 @@ typedef struct {
|
|
|
|
|
char *pathname;
|
|
|
|
|
} xc_fcntl_lock_t;
|
|
|
|
|
|
|
|
|
|
/* {{{ fcntl lock impl */
|
|
|
|
|
#ifndef ZEND_WIN32
|
|
|
|
|
# define LCK_WR F_WRLCK
|
|
|
|
|
# define LCK_RD F_RDLCK
|
|
|
|
@ -182,25 +199,27 @@ static void xc_fcntl_unlock(xc_fcntl_lock_t *lck) /* {{{ */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* }}} */
|
|
|
|
|
#endif /* XC_INTERPROCESS_LOCK_IMPLEMENTED */
|
|
|
|
|
#endif /* XC_LOCK_USE_FCNTL */
|
|
|
|
|
|
|
|
|
|
struct _xc_lock_t {
|
|
|
|
|
#ifdef XC_LOCK_UNSUED
|
|
|
|
|
#ifdef XC_LOCK_USE_NOOP
|
|
|
|
|
int dummy;
|
|
|
|
|
#else
|
|
|
|
|
# ifdef ZTS
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef XC_LOCK_USE_TSRM
|
|
|
|
|
MUTEX_T tsrm_mutex;
|
|
|
|
|
# endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef XC_LOCK_HAVE_INTERPROCESS_SWITCH
|
|
|
|
|
zend_bool interprocess;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
# ifdef _POSIX_THREAD_PROCESS_SHARED
|
|
|
|
|
#ifdef XC_LOCK_USE_PTHREAD
|
|
|
|
|
pthread_mutex_t pthread_mutex;
|
|
|
|
|
# endif
|
|
|
|
|
# ifndef XC_INTERPROCESS_LOCK_IMPLEMENTED
|
|
|
|
|
# ifdef ZTS
|
|
|
|
|
zend_bool use_fcntl;
|
|
|
|
|
# endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef XC_LOCK_USE_FCNTL
|
|
|
|
|
xc_fcntl_lock_t fcntl_lock;
|
|
|
|
|
# endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
@ -208,6 +227,12 @@ struct _xc_lock_t {
|
|
|
|
|
#endif
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#ifdef XC_LOCK_HAVE_INTERPROCESS_SWITCH
|
|
|
|
|
# define XC_LOCK_INTERPROCESS (lck->interprocess)
|
|
|
|
|
#else
|
|
|
|
|
# define XC_LOCK_INTERPROCESS 1
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
size_t xc_lock_size(void) /* {{{ */
|
|
|
|
|
{
|
|
|
|
|
return sizeof(xc_lock_t);
|
|
|
|
@ -215,24 +240,27 @@ size_t xc_lock_size(void) /* {{{ */
|
|
|
|
|
/* }}} */
|
|
|
|
|
xc_lock_t *xc_lock_init(xc_lock_t *lck, const char *pathname, unsigned char interprocess) /* {{{ */
|
|
|
|
|
{
|
|
|
|
|
#ifdef ZTS
|
|
|
|
|
# ifdef _POSIX_THREAD_PROCESS_SHARED
|
|
|
|
|
pthread_mutexattr_t psharedm;
|
|
|
|
|
pthread_mutexattr_init(&psharedm);
|
|
|
|
|
pthread_mutexattr_setpshared(&psharedm, PTHREAD_PROCESS_SHARED);
|
|
|
|
|
pthread_mutex_init(&lck->pthread_mutex, &psharedm);
|
|
|
|
|
lck->tsrm_mutex = &lck->pthread_mutex;
|
|
|
|
|
# else
|
|
|
|
|
#ifdef XC_LOCK_HAVE_INTERPROCESS_SWITCH
|
|
|
|
|
lck->interprocess = interprocess;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef XC_LOCK_USE_PTHREAD
|
|
|
|
|
{
|
|
|
|
|
pthread_mutexattr_t psharedm;
|
|
|
|
|
pthread_mutexattr_init(&psharedm);
|
|
|
|
|
pthread_mutexattr_setpshared(&psharedm, XC_LOCK_INTERPROCESS ? PTHREAD_PROCESS_PRIVATE : PTHREAD_PROCESS_SHARED);
|
|
|
|
|
pthread_mutex_init(&lck->pthread_mutex, &psharedm);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef XC_LOCK_USE_TSRM
|
|
|
|
|
lck->tsrm_mutex = tsrm_mutex_alloc();
|
|
|
|
|
# endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef XC_INTERPROCESS_LOCK_IMPLEMENTED
|
|
|
|
|
# ifdef ZTS
|
|
|
|
|
lck->use_fcntl = interprocess;
|
|
|
|
|
if (lck->use_fcntl)
|
|
|
|
|
# endif
|
|
|
|
|
#ifdef XC_LOCK_USE_FCNTL
|
|
|
|
|
if (XC_LOCK_INTERPROCESS) {
|
|
|
|
|
xc_fcntl_init(&lck->fcntl_lock, pathname);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
@ -244,38 +272,40 @@ xc_lock_t *xc_lock_init(xc_lock_t *lck, const char *pathname, unsigned char inte
|
|
|
|
|
/* }}} */
|
|
|
|
|
void xc_lock_destroy(xc_lock_t *lck) /* {{{ */
|
|
|
|
|
{
|
|
|
|
|
#ifdef ZTS
|
|
|
|
|
# ifdef _POSIX_THREAD_PROCESS_SHARED
|
|
|
|
|
#ifdef XC_LOCK_USE_PTHREAD
|
|
|
|
|
pthread_mutex_destroy(&lck->pthread_mutex);
|
|
|
|
|
# else
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef XC_LOCK_USE_TSRM
|
|
|
|
|
tsrm_mutex_free(lck->tsrm_mutex);
|
|
|
|
|
# endif
|
|
|
|
|
lck->tsrm_mutex = NULL;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef XC_INTERPROCESS_LOCK_IMPLEMENTED
|
|
|
|
|
# ifdef ZTS
|
|
|
|
|
if (lck->use_fcntl)
|
|
|
|
|
# endif
|
|
|
|
|
#ifdef XC_LOCK_USE_FCNTL
|
|
|
|
|
if (XC_LOCK_INTERPROCESS) {
|
|
|
|
|
xc_fcntl_destroy(&lck->fcntl_lock);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
/* }}} */
|
|
|
|
|
void xc_lock(xc_lock_t *lck) /* {{{ */
|
|
|
|
|
{
|
|
|
|
|
#ifdef XC_LOCK_UNSUED
|
|
|
|
|
#else
|
|
|
|
|
# ifdef ZTS
|
|
|
|
|
#ifdef XC_LOCK_USE_PTHREAD
|
|
|
|
|
if (pthread_mutex_lock(&lck->pthread_mutex) < 0) {
|
|
|
|
|
zend_error(E_ERROR, "xc_lock failed errno:%d", errno);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef XC_LOCK_USE_TSRM
|
|
|
|
|
if (tsrm_mutex_lock(lck->tsrm_mutex) < 0) {
|
|
|
|
|
zend_error(E_ERROR, "xc_lock failed errno:%d", errno);
|
|
|
|
|
}
|
|
|
|
|
# endif
|
|
|
|
|
# ifndef XC_INTERPROCESS_LOCK_IMPLEMENTED
|
|
|
|
|
# ifdef ZTS
|
|
|
|
|
if (lck->use_fcntl)
|
|
|
|
|
# endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef XC_LOCK_USE_FCNTL
|
|
|
|
|
if (XC_LOCK_INTERPROCESS) {
|
|
|
|
|
xc_fcntl_lock(&lck->fcntl_lock);
|
|
|
|
|
# endif
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
@ -287,19 +317,22 @@ void xc_lock(xc_lock_t *lck) /* {{{ */
|
|
|
|
|
/* }}} */
|
|
|
|
|
void xc_rdlock(xc_lock_t *lck) /* {{{ */
|
|
|
|
|
{
|
|
|
|
|
#ifdef XC_LOCK_UNSUED
|
|
|
|
|
#else
|
|
|
|
|
# ifdef ZTS
|
|
|
|
|
#ifdef XC_LOCK_USE_PTHREAD
|
|
|
|
|
if (pthread_mutex_lock(&lck->pthread_mutex) < 0) {
|
|
|
|
|
zend_error(E_ERROR, "xc_rdlock failed errno:%d", errno);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef XC_LOCK_USE_TSRM
|
|
|
|
|
if (tsrm_mutex_lock(lck->tsrm_mutex) < 0) {
|
|
|
|
|
zend_error(E_ERROR, "xc_rdlock failed errno:%d", errno);
|
|
|
|
|
}
|
|
|
|
|
# endif
|
|
|
|
|
# ifndef XC_INTERPROCESS_LOCK_IMPLEMENTED
|
|
|
|
|
# ifdef ZTS
|
|
|
|
|
if (lck->use_fcntl)
|
|
|
|
|
# endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef XC_LOCK_USE_FCNTL
|
|
|
|
|
if (XC_LOCK_INTERPROCESS) {
|
|
|
|
|
xc_fcntl_lock(&lck->fcntl_lock);
|
|
|
|
|
# endif
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
@ -317,19 +350,22 @@ void xc_unlock(xc_lock_t *lck) /* {{{ */
|
|
|
|
|
assert(!lck->locked);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef XC_LOCK_UNSUED
|
|
|
|
|
#else
|
|
|
|
|
# ifndef XC_INTERPROCESS_LOCK_IMPLEMENTED
|
|
|
|
|
# ifdef ZTS
|
|
|
|
|
if (lck->use_fcntl)
|
|
|
|
|
# endif
|
|
|
|
|
#ifdef XC_LOCK_USE_FCNTL
|
|
|
|
|
if (XC_LOCK_INTERPROCESS) {
|
|
|
|
|
xc_fcntl_unlock(&lck->fcntl_lock);
|
|
|
|
|
# endif
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
# ifdef ZTS
|
|
|
|
|
|
|
|
|
|
#ifdef XC_LOCK_USE_TSRM
|
|
|
|
|
if (tsrm_mutex_unlock(lck->tsrm_mutex) < 0) {
|
|
|
|
|
zend_error(E_ERROR, "xc_unlock failed errno:%d", errno);
|
|
|
|
|
}
|
|
|
|
|
# endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef XC_LOCK_USE_PTHREAD
|
|
|
|
|
if (pthread_mutex_unlock(&lck->pthread_mutex) < 0) {
|
|
|
|
|
zend_error(E_ERROR, "xc_unlock failed errno:%d", errno);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
/* }}} */
|
|
|
|
|