mirror of
https://github.com/danog/ext-uv.git
synced 2024-11-30 04:29:01 +01:00
pthread_rwlock requires the lock being unlocked as often as it has been acquired
tests/700-uv_rwlock.phpt throws a notice inside resource dtor, which causes a memory leak in PHP; setting track_errors=0 temporarily there for having the test pass here.
This commit is contained in:
parent
567ca4f30b
commit
30c34d72a3
58
php_uv.c
58
php_uv.c
@ -611,14 +611,26 @@ static void php_uv_lock_lock(enum php_uv_lock_type lock_type, INTERNAL_FUNCTION_
|
|||||||
case IS_UV_RWLOCK:
|
case IS_UV_RWLOCK:
|
||||||
case IS_UV_RWLOCK_RD:
|
case IS_UV_RWLOCK_RD:
|
||||||
{
|
{
|
||||||
|
if (lock->locked == 0x01) {
|
||||||
|
zend_error(E_WARNING, "Cannot acquire a read lock while holding a write lock");
|
||||||
|
RETURN_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
uv_rwlock_rdlock(PHP_UV_LOCK_RWLOCK_P(lock));
|
uv_rwlock_rdlock(PHP_UV_LOCK_RWLOCK_P(lock));
|
||||||
lock->locked = 0x01;
|
if (!lock->locked++) {
|
||||||
|
lock->locked = 0x02;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IS_UV_RWLOCK_WR:
|
case IS_UV_RWLOCK_WR:
|
||||||
{
|
{
|
||||||
|
if (lock->locked) {
|
||||||
|
zend_error(E_WARNING, "Cannot acquire a write lock when already holding a lock");
|
||||||
|
RETURN_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
uv_rwlock_wrlock(PHP_UV_LOCK_RWLOCK_P(lock));
|
uv_rwlock_wrlock(PHP_UV_LOCK_RWLOCK_P(lock));
|
||||||
lock->locked = 0x02;
|
lock->locked = 0x01;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IS_UV_MUTEX:
|
case IS_UV_MUTEX:
|
||||||
@ -654,15 +666,17 @@ static void php_uv_lock_unlock(enum php_uv_lock_type lock_type, INTERNAL_FUNCTI
|
|||||||
case IS_UV_RWLOCK:
|
case IS_UV_RWLOCK:
|
||||||
case IS_UV_RWLOCK_RD:
|
case IS_UV_RWLOCK_RD:
|
||||||
{
|
{
|
||||||
if (lock->locked == 0x01) {
|
if (lock->locked > 0x01) {
|
||||||
uv_rwlock_rdunlock(PHP_UV_LOCK_RWLOCK_P(lock));
|
uv_rwlock_rdunlock(PHP_UV_LOCK_RWLOCK_P(lock));
|
||||||
lock->locked = 0x00;
|
if (--lock->locked == 0x01) {
|
||||||
|
lock->locked = 0x00;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IS_UV_RWLOCK_WR:
|
case IS_UV_RWLOCK_WR:
|
||||||
{
|
{
|
||||||
if (lock->locked == 0x02) {
|
if (lock->locked == 0x01) {
|
||||||
uv_rwlock_wrunlock(PHP_UV_LOCK_RWLOCK_P(lock));
|
uv_rwlock_wrunlock(PHP_UV_LOCK_RWLOCK_P(lock));
|
||||||
lock->locked = 0x00;
|
lock->locked = 0x00;
|
||||||
}
|
}
|
||||||
@ -704,9 +718,16 @@ static void php_uv_lock_trylock(enum php_uv_lock_type lock_type, INTERNAL_FUNCTI
|
|||||||
case IS_UV_RWLOCK:
|
case IS_UV_RWLOCK:
|
||||||
case IS_UV_RWLOCK_RD:
|
case IS_UV_RWLOCK_RD:
|
||||||
{
|
{
|
||||||
|
if (lock->locked == 0x01) {
|
||||||
|
zend_error(E_WARNING, "Cannot acquire a read lock while holding a write lock");
|
||||||
|
RETURN_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
error = uv_rwlock_tryrdlock(PHP_UV_LOCK_RWLOCK_P(lock));
|
error = uv_rwlock_tryrdlock(PHP_UV_LOCK_RWLOCK_P(lock));
|
||||||
if (error == 0) {
|
if (error == 0) {
|
||||||
lock->locked = 0x01;
|
if (!lock->locked++) {
|
||||||
|
lock->locked = 0x02;
|
||||||
|
}
|
||||||
RETURN_TRUE;
|
RETURN_TRUE;
|
||||||
} else {
|
} else {
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
@ -715,9 +736,14 @@ static void php_uv_lock_trylock(enum php_uv_lock_type lock_type, INTERNAL_FUNCTI
|
|||||||
break;
|
break;
|
||||||
case IS_UV_RWLOCK_WR:
|
case IS_UV_RWLOCK_WR:
|
||||||
{
|
{
|
||||||
|
if (lock->locked) {
|
||||||
|
zend_error(E_WARNING, "Cannot acquire a write lock when already holding a lock");
|
||||||
|
RETURN_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
error = uv_rwlock_trywrlock(PHP_UV_LOCK_RWLOCK_P(lock));
|
error = uv_rwlock_trywrlock(PHP_UV_LOCK_RWLOCK_P(lock));
|
||||||
if (error == 0) {
|
if (error == 0) {
|
||||||
lock->locked = 0x02;
|
lock->locked = 0x01;
|
||||||
RETURN_TRUE;
|
RETURN_TRUE;
|
||||||
} else {
|
} else {
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
@ -1152,27 +1178,25 @@ void static destruct_uv_lock(zend_resource *rsrc)
|
|||||||
|
|
||||||
if (lock->type == IS_UV_RWLOCK) {
|
if (lock->type == IS_UV_RWLOCK) {
|
||||||
if (lock->locked == 0x01) {
|
if (lock->locked == 0x01) {
|
||||||
php_error_docref(NULL, E_NOTICE, "uv_rwlock: unlocked resoruce detected. force rdunlock resource.");
|
php_error_docref(NULL, E_NOTICE, "uv_rwlock: still locked resource detected; forcing wrunlock");
|
||||||
uv_rwlock_rdunlock(PHP_UV_LOCK_RWLOCK_P(lock));
|
|
||||||
lock->locked = 0x00;
|
|
||||||
} else if (lock->locked == 0x02) {
|
|
||||||
php_error_docref(NULL, E_NOTICE, "uv_rwlock: unlocked resoruce detected. force wrunlock resource.");
|
|
||||||
uv_rwlock_wrunlock(PHP_UV_LOCK_RWLOCK_P(lock));
|
uv_rwlock_wrunlock(PHP_UV_LOCK_RWLOCK_P(lock));
|
||||||
lock->locked = 0x00;
|
} else if (lock->locked) {
|
||||||
|
php_error_docref(NULL, E_NOTICE, "uv_rwlock: still locked resource detected; forcing rdunlock");
|
||||||
|
while (--lock->locked > 0) {
|
||||||
|
uv_rwlock_rdunlock(PHP_UV_LOCK_RWLOCK_P(lock));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
uv_rwlock_destroy(PHP_UV_LOCK_RWLOCK_P(lock));
|
uv_rwlock_destroy(PHP_UV_LOCK_RWLOCK_P(lock));
|
||||||
} else if (lock->type == IS_UV_MUTEX) {
|
} else if (lock->type == IS_UV_MUTEX) {
|
||||||
if (lock->locked == 0x01) {
|
if (lock->locked == 0x01) {
|
||||||
php_error_docref(NULL, E_NOTICE, "uv_mutex: unlocked resoruce detected. force unlock resource.");
|
php_error_docref(NULL, E_NOTICE, "uv_mutex: still locked resource detected; forcing unlock");
|
||||||
uv_mutex_unlock(PHP_UV_LOCK_MUTEX_P(lock));
|
uv_mutex_unlock(PHP_UV_LOCK_MUTEX_P(lock));
|
||||||
lock->locked = 0x00;
|
|
||||||
}
|
}
|
||||||
uv_mutex_destroy(PHP_UV_LOCK_MUTEX_P(lock));
|
uv_mutex_destroy(PHP_UV_LOCK_MUTEX_P(lock));
|
||||||
} else if (lock->type == IS_UV_SEMAPHORE) {
|
} else if (lock->type == IS_UV_SEMAPHORE) {
|
||||||
if (lock->locked == 0x01) {
|
if (lock->locked == 0x01) {
|
||||||
php_error_docref(NULL, E_NOTICE, "uv_sem: unlocked resoruce detected. force unlock resource.");
|
php_error_docref(NULL, E_NOTICE, "uv_sem: still locked resource detected; forcing unlock");
|
||||||
uv_sem_post(PHP_UV_LOCK_SEM_P(lock));
|
uv_sem_post(PHP_UV_LOCK_SEM_P(lock));
|
||||||
lock->locked = 0x00;
|
|
||||||
}
|
}
|
||||||
uv_sem_destroy(PHP_UV_LOCK_SEM_P(lock));
|
uv_sem_destroy(PHP_UV_LOCK_SEM_P(lock));
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
--TEST--
|
--TEST--
|
||||||
Check for uv_rwlock
|
Check for uv_rwlock
|
||||||
|
--INI--
|
||||||
|
track_errors=0
|
||||||
--FILE--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
$lock = uv_rwlock_init();
|
$lock = uv_rwlock_init();
|
||||||
@ -20,4 +22,6 @@ if (uv_rwlock_tryrdlock($lock)) {
|
|||||||
uv_rwlock_rdunlock($lock);
|
uv_rwlock_rdunlock($lock);
|
||||||
--EXPECT--
|
--EXPECT--
|
||||||
OK
|
OK
|
||||||
OK
|
OK
|
||||||
|
|
||||||
|
Notice: Unknown: uv_rwlock: still locked resource detected; forcing rdunlock in Unknown on line 0
|
||||||
|
Loading…
Reference in New Issue
Block a user