Permalink
Browse files

finished implementation of lock, independant of the mutex available

  • Loading branch information...
1 parent 43970ae commit 92d32c590403d4a3c6dc238ca31cbd3e22387b22 @krakjoe committed Nov 15, 2012
View
@@ -50,9 +50,6 @@ extern zend_function_entry pthreads_mutex_methods[];
#else
# ifndef HAVE_PTHREADS_CLASS_MUTEX
# define HAVE_PTHREADS_CLASS_MUTEX
-# ifndef HAVE_PTHREADS_LOCK_H
-# include <src/lock.h>
-# endif
zend_function_entry pthreads_mutex_methods[] = {
PHP_ME(Mutex, create, Mutex_create, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
PHP_ME(Mutex, lock, Mutex_lock, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
@@ -68,14 +65,8 @@ PHP_METHOD(Mutex, create)
{
zend_bool lock;
pthread_mutex_t *mutex;
- int result = FAILURE;
if ((mutex=(pthread_mutex_t*) calloc(1, sizeof(pthread_mutex_t)))!=NULL) {
- pthread_mutexattr_t mutype;
- pthread_mutexattr_init(&mutype);
- pthread_mutexattr_settype(&mutype, PTHREADS_LOCK_TYPE);
- result = pthread_mutex_init(mutex, &mutype);
- pthread_mutexattr_destroy(&mutype);
- switch(result){
+ switch(pthread_mutex_init(mutex, NULL)){
case SUCCESS:
if (ZEND_NUM_ARGS()) {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &lock)==SUCCESS) {
View
@@ -8,16 +8,7 @@ if test "$PHP_PTHREADS" != "no"; then
else
AC_MSG_ERROR([pthreads requires ZTS, please re-compile PHP with ZTS enabled])
fi
- PHP_NEW_EXTENSION(pthreads, php_pthreads.c \
- src/lock.c \
- src/globals.c \
- src/prepare.c \
- src/synchro.c \
- src/state.c \
- src/store.c \
- src/modifiers.c\
- src/handlers.c \
- src/object.c, $ext_shared)
+ PHP_NEW_EXTENSION(pthreads, php_pthreads.c src/lock.c src/globals.c src/prepare.c src/synchro.c src/state.c src/store.c src/modifiers.c src/handlers.c src/object.c, $ext_shared)
PHP_ADD_BUILD_DIR($ext_builddir/src, 1)
PHP_ADD_INCLUDE($ext_builddir)
PHP_SUBST(PTHREADS_SHARED_LIBADD)
@@ -4,7 +4,6 @@
<refentry xml:id="cond.broadcast" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<refnamediv>
<refname>Cond::broadcast</refname>
- <refpurpose>Broadcast a condition to all Threads</refpurpose>
</refnamediv>
<refsect1 role="description">
View
@@ -4,7 +4,6 @@
<refentry xml:id="cond.create" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<refnamediv>
<refname>Cond::create</refname>
- <refpurpose>Create a new Condition Variable</refpurpose>
</refnamediv>
<refsect1 role="description">
View
@@ -4,7 +4,6 @@
<refentry xml:id="cond.destroy" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<refnamediv>
<refname>Cond::destroy</refname>
- <refpurpose>Destroy a handle to a Condition Variable and free the associated resources</refpurpose>
</refnamediv>
<refsect1 role="description">
View
@@ -4,7 +4,6 @@
<refentry xml:id="cond.signal" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<refnamediv>
<refname>Cond::signal</refname>
- <refpurpose>Signal a condition to a single Thread</refpurpose>
</refnamediv>
<refsect1 role="description">
View
@@ -4,7 +4,6 @@
<refentry xml:id="cond.wait" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<refnamediv>
<refname>Cond::wait</refname>
- <refpurpose>Wait for a signal on a Condition Variable</refpurpose>
</refnamediv>
<refsect1 role="description">
View
@@ -4,7 +4,6 @@
<refentry xml:id="mutex.create" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<refnamediv>
<refname>Mutex::create</refname>
- <refpurpose>Create a new Mutex</refpurpose>
</refnamediv>
<refsect1 role="description">
View
@@ -4,7 +4,6 @@
<refentry xml:id="mutex.destroy" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<refnamediv>
<refname>Mutex::destroy</refname>
- <refpurpose>To destroy a handle to a Mutex and free the associated resources</refpurpose>
</refnamediv>
<refsect1 role="description">
View
@@ -4,7 +4,6 @@
<refentry xml:id="mutex.lock" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<refnamediv>
<refname>Mutex::lock</refname>
- <refpurpose>The lock purpose</refpurpose>
</refnamediv>
<refsect1 role="description">
View
@@ -4,7 +4,6 @@
<refentry xml:id="mutex.trylock" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<refnamediv>
<refname>Mutex::trylock</refname>
- <refpurpose>To attempt to lock a Mutex without blocking.</refpurpose>
</refnamediv>
<refsect1 role="description">
View
@@ -4,7 +4,6 @@
<refentry xml:id="mutex.unlock" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<refnamediv>
<refname>Mutex::unlock</refname>
- <refpurpose>Attempts to unlock a Mutex</refpurpose>
</refnamediv>
<refsect1 role="description">
View
@@ -22,27 +22,36 @@
# include <src/globals.h>
#endif
-#ifndef HAVE_PTHREADS_OBJECT_H
-# include <src/object.h>
+struct _pthreads_globals pthreads_globals;
+
+#ifndef HAVE_PTHREADS_LOCK_H
+# include <src/lock.h>
#endif
-struct _pthreads_globals pthreads_globals;
+#ifndef PTHREADS_GTSRMLS_C
+# define PTHREADS_GTSRMLS_C (TSRMLS_C) ? TSRMLS_C : (void***) &pthreads_globals
+#endif
+
+#ifndef PTHREADS_GLOBAL_LOCK_ARGS
+# define PTHREADS_GLOBAL_LOCK_ARGS \
+ locked, PTHREADS_GTSRMLS_C
+#endif
/* {{{ pthreads_globals_init */
void pthreads_globals_init(TSRMLS_D){
if (!PTHREADS_G(init)) {
PTHREADS_G(init)=1;
- PTHREADS_G(lock)=pthreads_lock_alloc(TSRMLS_C);
+ PTHREADS_G(lock)=pthreads_lock_alloc(PTHREADS_GTSRMLS_C);
}
} /* }}} */
/* {{{ pthreads_globals_lock */
zend_bool pthreads_globals_lock(zend_bool *locked TSRMLS_DC){
- return pthreads_lock_acquire(PTHREADS_G(lock), locked TSRMLS_CC);
+ return pthreads_lock_acquire(PTHREADS_G(lock), PTHREADS_GLOBAL_LOCK_ARGS);
} /* }}} */
/* {{{ pthreads_globals_unlock */
void pthreads_globals_unlock(zend_bool locked TSRMLS_DC) {
- pthreads_lock_release(PTHREADS_G(lock), locked TSRMLS_CC);
+ pthreads_lock_release(PTHREADS_G(lock), PTHREADS_GLOBAL_LOCK_ARGS);
} /* }}} */
#endif
View
@@ -17,7 +17,7 @@
*/
/*
-* These handlers are mutex aware for safer operation in multi-threaded applications
+* These handlers provide thread-safe read/write/call for pthreads objects
*/
#ifndef HAVE_PTHREADS_HANDLERS_H
#define HAVE_PTHREADS_HANDLERS_H
View
@@ -22,32 +22,41 @@
# include <src/lock.h>
#endif
+#ifndef HAVE_PTHREADS_THREAD_H
+# include <src/thread.h>
+#endif
+
+/* {{{ proto pthreads_lock pthreads_lock_alloc(TSRMLS_D)
+ shall allocate and initialize a pthreads lock */
pthreads_lock pthreads_lock_alloc(TSRMLS_D) {
pthreads_lock lock = calloc(1, sizeof(*lock));
- if (lock) {
- pthread_mutexattr_t mutype;
- if (pthread_mutexattr_init(&mutype)==SUCCESS) {
- if (pthread_mutexattr_settype(&mutype, PTHREADS_LOCK_TYPE)==SUCCESS) {
- if (pthread_mutex_init(&lock->mutex, &mutype)==SUCCESS) {
- pthread_mutexattr_destroy(&mutype);
- lock->owner = NULL;
- return lock;
- }
- }
- pthread_mutexattr_destroy(&mutype);
+ if (lock) {
+ /* whatever the default type will do */
+ if (pthread_mutex_init(&lock->mutex, NULL)==SUCCESS) {
+ lock->owner = NULL;
+ lock->locks = 0;
+ return lock;
}
free(lock);
}
return NULL;
-}
+} /* }}} */
+/* {{{ proto zend_bool pthreads_lock_acquire(pthreads_lock lock, zend_bool *acquired TSRMLS_DC)
+ shall attempt to acquire the referenced lock, setting acquired and returning true on success
+ if the lock is already held by the caller, the lock count is increased, acquired is not set,
+ and true is still returned ( since the caller still owns the lock, and has the privilege to
+ carry out whatever action they were acqiuring the lock for ) */
zend_bool pthreads_lock_acquire(pthreads_lock lock, zend_bool *acquired TSRMLS_DC) {
+ zend_bool locked = 0;
if (lock) {
if (!TSRMLS_C || lock->owner != TSRMLS_C){
- int locked, result = pthread_mutex_lock(&lock->mutex);
- switch (result) {
- case SUCCESS: locked = (((*acquired)=1)==1); break;
- case EDEADLK: locked = (((*acquired)=0)==0); break;
+ switch (pthread_mutex_lock(&lock->mutex)) {
+ case SUCCESS:
+ locked = (((*acquired)=1)==1);
+ lock->owner = TSRMLS_C;
+ lock->locks = 1;
+ break;
default: {
zend_error_noreturn(
@@ -56,39 +65,51 @@ zend_bool pthreads_lock_acquire(pthreads_lock lock, zend_bool *acquired TSRMLS_D
locked = (((*acquired)=0)==1);
}
}
-
- if (locked)
- lock->owner = tsrm_ls;
- return locked;
- } else return (((*acquired)=0)==0);
- } else return (((*acquired)=0)==1);
-}
+ } else {
+ locked = (((*acquired)=0)==0);
+ lock->locks++;
+ }
+ } else locked = (((*acquired)=0)==1);
+
+ return locked;
+} /* }}} */
+/* {{{ proto zend_bool pthreads_lock_release(pthreads_lock lock, zend_bool acquired TSRMLS_DC)
+ acquired should have been set by the accompanying call to pthreads_lock_acquire
+ if acquired is set true then the lock shall be released, resetting the owner and decremeneting the count
+ if acquired is set false then the counter shall be decremented without unlocking taking place */
zend_bool pthreads_lock_release(pthreads_lock lock, zend_bool acquired TSRMLS_DC) {
+ zend_bool released = 1;
if (lock) {
if (acquired) {
- int result = pthread_mutex_unlock(&lock->mutex);
- switch (result) {
- case SUCCESS:
- lock->owner = NULL;
- return 1;
+ lock->locks--;
+ lock->owner = NULL;
+ switch (pthread_mutex_unlock(&lock->mutex)) {
+ case SUCCESS:
+ released = 1;
+ break;
default: {
zend_error_noreturn(
E_ERROR,
"pthreads has experienced an internal error while releasing lock @ %p and cannot continue",
lock
);
- return 0;
+ released = 0;
}
}
- } else return 1;
- } else return 0;
-}
+ } else --lock->locks;
+ } else released = 0;
+
+ return released;
+} /* }}} */
+/* {{{ proto void pthreads_lock_free(pthreads_lock lock TSRMLS_DC)
+ shall deinitialize and free the memory associated with the referenced lock */
void pthreads_lock_free(pthreads_lock lock TSRMLS_DC) {
if (lock) {
+ pthread_mutex_destroy(&lock->mutex);
free(lock);
}
-}
+} /* }}} */
#endif
View
@@ -17,19 +17,33 @@
*/
#ifndef HAVE_PTHREADS_LOCK_H
#define HAVE_PTHREADS_LOCK_H
-
+/*
+* This API is NOT ready to be exposed to userland.
+*
+* This header provides pthreads with a recursive locking mechanism that
+* will eventually be independant of threading implementation that pthreads
+* is using, it will use the default mutex type on the system, but will manage
+* the lock count using TSRMLS_C as a reference to the owner
+*/
#ifndef HAVE_PTHREADS_H
# include <src/pthreads.h>
#endif
typedef struct {
pthread_mutex_t mutex;
void*** owner;
-
+ ulong locks;
} *pthreads_lock;
-pthreads_lock pthreads_lock_alloc(TSRMLS_D);
-zend_bool pthreads_lock_acquire(pthreads_lock lock, zend_bool *acquired TSRMLS_DC);
-zend_bool pthreads_lock_release(pthreads_lock lock, zend_bool acquired TSRMLS_DC);
-void pthreads_lock_free(pthreads_lock lock TSRMLS_DC);
+/* {{{ allocate a lock */
+pthreads_lock pthreads_lock_alloc(TSRMLS_D); /* }}} */
+
+/* {{{ acquire a lock */
+zend_bool pthreads_lock_acquire(pthreads_lock lock, zend_bool *acquired TSRMLS_DC); /* }}} */
+
+/* {{{ release a lock */
+zend_bool pthreads_lock_release(pthreads_lock lock, zend_bool acquired TSRMLS_DC); /* }}} */
+
+/* {{{ free a lock */
+void pthreads_lock_free(pthreads_lock lock TSRMLS_DC); /* }}} */
#endif
View
@@ -535,14 +535,14 @@ int pthreads_internal_serialize(zval *object, unsigned char **buffer, zend_uint
threaded->address->serial = calloc(1, threaded->address->length);
if (threaded->address->serial) {
sprintf(
- threaded->address->serial, "%lu", (long) threaded
+ (char*) threaded->address->serial, "%lu", (long) threaded
);
} else return FAILURE;
}
} else return FAILURE;
}
- (*buffer) = estrndup((char*)threaded->address->serial, threaded->address->length);
+ (*buffer) = (unsigned char*) estrndup((char*)threaded->address->serial, threaded->address->length);
(*blength) = threaded->address->length;
return SUCCESS;
@@ -553,7 +553,7 @@ int pthreads_internal_serialize(zval *object, unsigned char **buffer, zend_uint
/* {{{ connects to an instance of a threaded object */
int pthreads_internal_unserialize(zval **object, zend_class_entry *ce, const unsigned char *buffer, zend_uint blength, zend_unserialize_data *data TSRMLS_DC) {
PTHREAD address = NULL;
- if (sscanf((char*)buffer, "%lu", &address)) {
+ if (sscanf((const char*)buffer, "%lu", &address)) {
if (address) {
if (object_init_ex(
*object, pthreads_prepared_entry(address, ce TSRMLS_CC)
View
@@ -267,22 +267,17 @@ void pthreads_prepare(PTHREAD thread TSRMLS_DC){
char *setting;
uint slength;
ulong idx;
+
if ((zend_hash_get_current_key_ex(table[0], &setting, &slength, &idx, 0, &position)==HASH_KEY_IS_STRING) &&
(zend_hash_find(table[1], setting, slength, (void**) &entry[1])==SUCCESS)) {
if (((entry[0]->value && entry[1]->value) && (strcmp(entry[0]->value, entry[1]->value) != 0)) || entry[0]->value) {
- entry[1]->orig_value = entry[1]->value;
- entry[1]->orig_value_length = entry[1]->orig_value_length;
- entry[1]->orig_modifiable = entry[1]->modifiable;
- entry[1]->value = estrndup(entry[0]->value, entry[0]->value_length);
- entry[1]->value_length = entry[0]->value_length;
- entry[1]->modified = 1;
-
- if (!EG(modified_ini_directives)) {
- ALLOC_HASHTABLE(EG(modified_ini_directives));
- zend_hash_init(EG(modified_ini_directives), 8, NULL, NULL, 0);
- }
-
- zend_hash_add(EG(modified_ini_directives), setting, slength, (void**) &entry[1], sizeof(zend_ini_entry*), NULL);
+ zend_bool modifiable = entry[1]->modifiable;
+ zend_alter_ini_entry_ex(
+ setting, slength,
+ entry[0]->value, entry[0]->value_length,
+ ZEND_INI_STAGE_ACTIVATE, ZEND_INI_SYSTEM, 1 TSRMLS_CC
+ );
+ entry[1]->modifiable = modifiable;
}
}
}
Oops, something went wrong.

0 comments on commit 92d32c5

Please sign in to comment.