improve uv_mutex functions and add test case

This commit is contained in:
Shuhei Tanuma 2012-06-30 14:42:06 +09:00
parent 449205e213
commit bcdd3a21e9
3 changed files with 74 additions and 32 deletions

View File

@ -126,8 +126,6 @@ static int uv_sockaddr_handle;
static int uv_lock_handle; static int uv_lock_handle;
static int uv_mutex_handle;
static char uv_fs_read_buf[10]; static char uv_fs_read_buf[10];
/* declarations */ /* declarations */
@ -244,27 +242,29 @@ static zval *php_uv_make_stat(const uv_statbuf_t *s)
/* destructor */ /* destructor */
void static destruct_uv_mutex(zend_rsrc_list_entry *rsrc TSRMLS_DC)
{
uv_mutex_t *mutex = (uv_mutex_t *)rsrc->ptr;
uv_mutex_destroy(mutex);
efree(mutex);
}
void static destruct_uv_lock(zend_rsrc_list_entry *rsrc TSRMLS_DC) void static destruct_uv_lock(zend_rsrc_list_entry *rsrc TSRMLS_DC)
{ {
php_uv_lock_t *lock = (php_uv_lock_t *)rsrc->ptr; php_uv_lock_t *lock = (php_uv_lock_t *)rsrc->ptr;
if (lock->locked == 0x01) { if (lock->type == IS_UV_RWLOCK) {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "uv_rw_lock: unlocked resoruce detected. force rdunlock resource."); if (lock->locked == 0x01) {
uv_rwlock_rdunlock(&lock->lock.rwlock); php_error_docref(NULL TSRMLS_CC, E_NOTICE, "uv_rwlock: unlocked resoruce detected. force rdunlock resource.");
lock->locked = 0x00; uv_rwlock_rdunlock(&lock->lock.rwlock);
} else if (lock->locked == 0x02) { lock->locked = 0x00;
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "uv_rw_lock: unlocked resoruce detected. force wrunlock resource."); } else if (lock->locked == 0x02) {
uv_rwlock_wrunlock(&lock->lock.rwlock); php_error_docref(NULL TSRMLS_CC, E_NOTICE, "uv_rwlock: unlocked resoruce detected. force wrunlock resource.");
lock->locked = 0x00; uv_rwlock_wrunlock(&lock->lock.rwlock);
lock->locked = 0x00;
}
uv_rwlock_destroy(&lock->lock.rwlock);
} else if (lock->type == IS_UV_MUTEX) {
if (lock->locked == 0x01) {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "uv_mutex: unlocked resoruce detected. force unlock resource.");
uv_mutex_unlock(&lock->lock.mutex);
lock->locked = 0x00;
}
uv_mutex_destroy(&lock->lock.mutex);
} }
uv_rwlock_destroy(&lock->lock.rwlock);
efree(lock); efree(lock);
} }
@ -1178,7 +1178,6 @@ PHP_MINIT_FUNCTION(uv) {
uv_loop_handle = zend_register_list_destructors_ex(destruct_uv_loop, NULL, PHP_UV_LOOP_RESOURCE_NAME, module_number); uv_loop_handle = zend_register_list_destructors_ex(destruct_uv_loop, NULL, PHP_UV_LOOP_RESOURCE_NAME, module_number);
uv_sockaddr_handle = zend_register_list_destructors_ex(destruct_uv_sockaddr, NULL, PHP_UV_SOCKADDR_RESOURCE_NAME, module_number); uv_sockaddr_handle = zend_register_list_destructors_ex(destruct_uv_sockaddr, NULL, PHP_UV_SOCKADDR_RESOURCE_NAME, module_number);
uv_lock_handle = zend_register_list_destructors_ex(destruct_uv_lock, NULL, PHP_UV_LOCK_RESOURCE_NAME, module_number); uv_lock_handle = zend_register_list_destructors_ex(destruct_uv_lock, NULL, PHP_UV_LOCK_RESOURCE_NAME, module_number);
uv_mutex_handle = zend_register_list_destructors_ex(destruct_uv_mutex, NULL, PHP_UV_MUTEX_RESOURCE_NAME, module_number);
rc = ares_library_init(ARES_LIB_INIT_ALL); rc = ares_library_init(ARES_LIB_INIT_ALL);
if (rc != 0) { if (rc != 0) {
@ -3513,6 +3512,7 @@ PHP_FUNCTION(uv_rwlock_init)
error = uv_rwlock_init(&lock->lock.rwlock); error = uv_rwlock_init(&lock->lock.rwlock);
if (error == 0) { if (error == 0) {
ZEND_REGISTER_RESOURCE(return_value, lock, uv_lock_handle); ZEND_REGISTER_RESOURCE(return_value, lock, uv_lock_handle);
lock->type = IS_UV_RWLOCK;
} else { } else {
RETURN_FALSE; RETURN_FALSE;
} }
@ -3642,13 +3642,14 @@ PHP_FUNCTION(uv_rwlock_wrunlock)
/* {{{ */ /* {{{ */
PHP_FUNCTION(uv_mutex_init) PHP_FUNCTION(uv_mutex_init)
{ {
uv_mutex_t *mutex; php_uv_lock_t *mutex;
int error; int error;
mutex = emalloc(sizeof(uv_mutex_t)); mutex = emalloc(sizeof(php_uv_t));
error = uv_mutex_init(mutex); error = uv_mutex_init(&mutex->lock.mutex);
if (error == 0) { if (error == 0) {
ZEND_REGISTER_RESOURCE(return_value, mutex, uv_mutex_handle); ZEND_REGISTER_RESOURCE(return_value, mutex, uv_lock_handle);
mutex->type = IS_UV_MUTEX;
} else { } else {
RETURN_FALSE; RETURN_FALSE;
} }
@ -3658,7 +3659,7 @@ PHP_FUNCTION(uv_mutex_init)
/* {{{ */ /* {{{ */
PHP_FUNCTION(uv_mutex_lock) PHP_FUNCTION(uv_mutex_lock)
{ {
uv_mutex_t *mutex; php_uv_lock_t *mutex;
zval *handle; zval *handle;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
@ -3666,31 +3667,40 @@ PHP_FUNCTION(uv_mutex_lock)
return; return;
} }
ZEND_FETCH_RESOURCE(mutex, uv_mutex_t *, &handle, -1, PHP_UV_MUTEX_RESOURCE_NAME, uv_mutex_handle); ZEND_FETCH_RESOURCE(mutex, php_uv_lock_t*, &handle, -1, PHP_UV_LOCK_RESOURCE_NAME, uv_lock_handle);
uv_mutex_lock(mutex); uv_mutex_lock(&mutex->lock.mutex);
mutex->locked = 0x01;
} }
/* }}} */ /* }}} */
/* {{{ */ /* {{{ */
PHP_FUNCTION(uv_mutex_trylock) PHP_FUNCTION(uv_mutex_trylock)
{ {
uv_mutex_t *mutex; php_uv_lock_t *mutex;
zval *handle; zval *handle;
int error = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
"z", &handle) == FAILURE) { "z", &handle) == FAILURE) {
return; return;
} }
ZEND_FETCH_RESOURCE(mutex, uv_mutex_t *, &handle, -1, PHP_UV_MUTEX_RESOURCE_NAME, uv_mutex_handle); ZEND_FETCH_RESOURCE(mutex, php_uv_lock_t *, &handle, -1, PHP_UV_LOCK_RESOURCE_NAME, uv_lock_handle);
RETURN_LONG(uv_mutex_trylock(mutex)); error = uv_mutex_trylock(&mutex->lock.mutex);
if (error == 0) {
mutex->locked = 0x01;
RETURN_TRUE;
} else {
RETURN_FALSE;
}
} }
/* }}} */ /* }}} */
/* {{{ */ /* {{{ */
PHP_FUNCTION(uv_mutex_unlock) PHP_FUNCTION(uv_mutex_unlock)
{ {
uv_mutex_t *mutex; php_uv_lock_t *mutex;
zval *handle; zval *handle;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
@ -3698,8 +3708,11 @@ PHP_FUNCTION(uv_mutex_unlock)
return; return;
} }
ZEND_FETCH_RESOURCE(mutex, uv_mutex_t *, &handle, -1, PHP_UV_MUTEX_RESOURCE_NAME, uv_mutex_handle); ZEND_FETCH_RESOURCE(mutex, php_uv_lock_t *, &handle, -1, PHP_UV_LOCK_RESOURCE_NAME, uv_lock_handle);
uv_mutex_unlock(mutex); if (mutex->locked == 0x01) {
uv_mutex_unlock(&mutex->lock.mutex);
mutex->locked = 0x00;
}
} }
/* }}} */ /* }}} */

View File

@ -29,6 +29,11 @@ extern zend_module_entry uv_module_entry;
extern zend_class_entry *uv_class_entry; extern zend_class_entry *uv_class_entry;
enum php_uv_lock_type{
IS_UV_RWLOCK = 1,
IS_UV_MUTEX = 2
};
enum php_uv_resource_type{ enum php_uv_resource_type{
IS_UV_TCP = 0, IS_UV_TCP = 0,
IS_UV_UDP = 1, IS_UV_UDP = 1,
@ -118,6 +123,7 @@ typedef struct {
typedef struct { typedef struct {
int locked; int locked;
enum php_uv_lock_type type;
int resource_id; int resource_id;
union { union {
uv_rwlock_t rwlock; uv_rwlock_t rwlock;

23
tests/701-uv_mutex.phpt Normal file
View File

@ -0,0 +1,23 @@
--TEST--
Check for uv_rwlock
--FILE--
<?php
$lock = uv_mutex_init();
if (uv_mutex_trylock($lock)) {
echo "OK" . PHP_EOL;
} else {
echo "FAILED" . PHP_EOL;
}
uv_mutex_unlock($lock);
if (uv_mutex_trylock($lock)) {
echo "OK" . PHP_EOL;
} else {
echo "FAILED" . PHP_EOL;
}
uv_mutex_unlock($lock);
--EXPECT--
OK
OK