Skip to content

Commit

Permalink
Issue #338: Add mutex implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
LionsAd authored and nikic committed Nov 19, 2018
1 parent 3d5b209 commit 0a891b8
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 3 deletions.
77 changes: 77 additions & 0 deletions apc_mutex.c
@@ -0,0 +1,77 @@
/*
+----------------------------------------------------------------------+
| APCu |
+----------------------------------------------------------------------+
| Copyright (c) 2013 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Fabian Franz <fabian@lionsad.de> |
+----------------------------------------------------------------------+
*/
#include "apc_mutex.h"

#ifdef APC_HAS_PTHREAD_MUTEX

static zend_bool apc_mutex_ready = 0;
static pthread_mutexattr_t apc_mutex_attr;

PHP_APCU_API zend_bool apc_mutex_init() {
if (apc_mutex_ready) {
return 1;
}
apc_mutex_ready = 1;

if (pthread_mutexattr_init(&apc_mutex_attr) != SUCCESS) {
return 0;
}

if (pthread_mutexattr_setpshared(&apc_mutex_attr, PTHREAD_PROCESS_SHARED) != SUCCESS) {
return 0;
}

return 1;
}

PHP_APCU_API void apc_mutex_cleanup() {
if (!apc_mutex_ready) {
return;
}
apc_mutex_ready = 0;

pthread_mutexattr_destroy(&apc_mutex_attr);
}

PHP_APCU_API zend_bool apc_mutex_create(apc_mutex_t *lock) {
pthread_mutex_init(lock, &apc_mutex_attr);
return 1;
}

PHP_APCU_API zend_bool apc_mutex_lock(apc_mutex_t *lock) {
HANDLE_BLOCK_INTERRUPTIONS();
if (pthread_mutex_lock(lock) == 0) {
return 1;
}

HANDLE_UNBLOCK_INTERRUPTIONS();
apc_warning("Failed to acquire lock");
return 0;
}

PHP_APCU_API zend_bool apc_mutex_unlock(apc_mutex_t *lock) {
pthread_mutex_unlock(lock);
HANDLE_UNBLOCK_INTERRUPTIONS();
return 1;
}

PHP_APCU_API void apc_mutex_destroy(apc_mutex_t *lock) {
pthread_mutex_destroy(lock);
}

#endif
63 changes: 63 additions & 0 deletions apc_mutex.h
@@ -0,0 +1,63 @@
/*
+----------------------------------------------------------------------+
| APCu |
+----------------------------------------------------------------------+
| Copyright (c) 2013 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Joe Watkins <joe.watkins@live.co.uk> |
+----------------------------------------------------------------------+
*/

#ifndef APC_MUTEX_H
#define APC_MUTEX_H

#include "apc.h"

#ifdef APC_HAS_PTHREAD_MUTEX

#include "pthread.h"

typedef pthread_mutex_t apc_mutex_t;

PHP_APCU_API zend_bool apc_mutex_init();
PHP_APCU_API void apc_mutex_cleanup();
PHP_APCU_API zend_bool apc_mutex_create(apc_mutex_t *lock);
PHP_APCU_API zend_bool apc_mutex_lock(apc_mutex_t *lock);
PHP_APCU_API zend_bool apc_mutex_unlock(apc_mutex_t *lock);
PHP_APCU_API void apc_mutex_destroy(apc_mutex_t *lock);

#define APC_MUTEX_INIT() apc_mutex_init()
#define APC_MUTEX_CLEANUP() apc_mutex_cleanup()

#define APC_CREATE_MUTEX(lock) apc_mutex_create(lock)
#define APC_DESTROY_MUTEX(lock) apc_mutex_destroy(lock)
#define APC_MUTEX_LOCK(lock) apc_mutex_lock(lock)
#define APC_MUTEX_UNLOCK(lock) apc_mutex_unlock(lock)

#else

#include "apc_lock.h"

typedef apc_lock_t apc_mutex_t;

// Fallback to normal locks

#define APC_MUTEX_INIT()
#define APC_MUTEX_CLEANUP()

#define APC_CREATE_MUTEX(lock) CREATE_LOCK(lock)
#define APC_DESTROY_MUTEX(lock) DESTROY_LOCK(lock)
#define APC_MUTEX_LOCK(lock) WLOCK(lock)
#define APC_MUTEX_UNLOCK(lock) WUNLOCK(lock)

#endif

#endif
7 changes: 4 additions & 3 deletions config.m4
Expand Up @@ -135,7 +135,7 @@ if test "$PHP_APCU" != "no"; then
LIBS="$orig_LIBS"
fi

if test "$PHP_APCU_RWLOCKS" = "no"; then
if test "$PHP_APCU" != "no"; then
orig_LIBS="$LIBS"
LIBS="$LIBS -lpthread"
AC_RUN_IFELSE([AC_LANG_SOURCE([[
Expand Down Expand Up @@ -172,6 +172,7 @@ if test "$PHP_APCU" != "no"; then
PHP_ADD_LIBRARY(pthread)
PHP_LDFLAGS="$PHP_LDFLAGS -lpthread"
AC_MSG_WARN([APCu has access to mutexes])
AC_DEFINE(APC_HAS_PTHREAD_MUTEX, 1, [ ])
],[ dnl -Failure-
AC_MSG_WARN([It doesn't appear that pthread mutexes are supported on your system])
PHP_APCU_MUTEX=no
Expand Down Expand Up @@ -225,7 +226,7 @@ if test "$PHP_APCU" != "no"; then
[AC_DEFINE([HAVE_VALGRIND_MEMCHECK_H],1, [enable valgrind memchecks])])
])

apc_sources="apc.c apc_lock.c php_apc.c \
apc_sources="apc.c apc_lock.c apc_mutex.c php_apc.c \
apc_cache.c \
apc_mmap.c \
apc_shm.c \
Expand All @@ -240,7 +241,7 @@ if test "$PHP_APCU" != "no"; then
PHP_SUBST(APCU_SHARED_LIBADD)
PHP_SUBST(APCU_CFLAGS)
PHP_SUBST(PHP_LDFLAGS)
PHP_INSTALL_HEADERS(ext/apcu, [php_apc.h apc.h apc_api.h apc_arginfo.h apc_cache.h apc_cache_api.h apc_globals.h apc_iterator.h apc_lock.h apc_lock_api.h apc_sma.h apc_sma_api.h apc_serializer.h apc_stack.h])
PHP_INSTALL_HEADERS(ext/apcu, [php_apc.h apc.h apc_api.h apc_arginfo.h apc_cache.h apc_cache_api.h apc_globals.h apc_iterator.h apc_lock.h apc_mutex.h apc_lock_api.h apc_sma.h apc_sma_api.h apc_serializer.h apc_stack.h])
AC_DEFINE(HAVE_APCU, 1, [ ])
fi

Expand Down
2 changes: 2 additions & 0 deletions package.xml
Expand Up @@ -123,6 +123,8 @@
<file name="apc_lock.h" role="src" />
<file name="apc_mmap.c" role="src" />
<file name="apc_mmap.h" role="src" />
<file name="apc_mutex.c" role="src" />
<file name="apc_mutex.h" role="src" />
<file name="apc_persist.c" role="src" />
<file name="apc.php" role="src" />
<file name="apc_php.h" role="src" />
Expand Down
3 changes: 3 additions & 0 deletions php_apc.c
Expand Up @@ -34,6 +34,7 @@
#include "apc_iterator.h"
#include "apc_sma.h"
#include "apc_lock.h"
#include "apc_mutex.h"
#include "apc_strings.h"
#include "php_globals.h"
#include "php_ini.h"
Expand Down Expand Up @@ -227,6 +228,7 @@ static PHP_MINIT_FUNCTION(apcu)

/* locks initialized regardless of settings */
apc_lock_init();
APC_MUTEX_INIT();

/* Disable APC in cli mode unless overridden by apc.enable_cli */
if (!APCG(enable_cli) && !strcmp(sapi_module.name, "cli")) {
Expand Down Expand Up @@ -290,6 +292,7 @@ static PHP_MSHUTDOWN_FUNCTION(apcu)

/* locks shutdown regardless of settings */
apc_lock_cleanup();
APC_MUTEX_CLEANUP();

/* only shut down if APC is enabled */
if (APCG(enabled)) {
Expand Down

0 comments on commit 0a891b8

Please sign in to comment.