Skip to content

Commit 1e0100e

Browse files
authored
Add timed lock support to RWLock (#5866)
* Swoole\Lock: add timed rwlock support * fixed known issues
1 parent 907a06c commit 1e0100e

File tree

5 files changed

+48
-6
lines changed

5 files changed

+48
-6
lines changed

ext-src/stubs/php_swoole_lock.stub.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ class Lock {
44
public function __construct(int $type = SWOOLE_MUTEX) {}
55
public function __destruct() {}
66
public function lock(): bool {}
7-
public function locakwait(float $timeout = 1.0): bool {}
7+
public function lockwait(float $timeout = 1.0, int $kind = 0): bool {}
88
public function trylock(): bool {}
99
public function lock_read(): bool {}
1010
public function trylock_read(): bool {}

ext-src/stubs/php_swoole_lock_arginfo.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 078bbefb0c45cb686da54e4c700bad31710589ef */
2+
* Stub hash: aa2ff16543143c6d0e8858e9900fa511cffed40c */
33

44
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Swoole_Lock___construct, 0, 0, 0)
55
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, type, IS_LONG, 0, "SWOOLE_MUTEX")
@@ -11,8 +11,9 @@ ZEND_END_ARG_INFO()
1111
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Lock_lock, 0, 0, _IS_BOOL, 0)
1212
ZEND_END_ARG_INFO()
1313

14-
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Lock_locakwait, 0, 0, _IS_BOOL, 0)
14+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Swoole_Lock_lockwait, 0, 0, _IS_BOOL, 0)
1515
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timeout, IS_DOUBLE, 0, "1.0")
16+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, kind, IS_LONG, 0, "0")
1617
ZEND_END_ARG_INFO()
1718

1819
#define arginfo_class_Swoole_Lock_trylock arginfo_class_Swoole_Lock_lock

ext-src/swoole_lock.cc

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ static const zend_function_entry swoole_lock_methods[] =
8888
PHP_ME(swoole_lock, __construct, arginfo_class_Swoole_Lock___construct, ZEND_ACC_PUBLIC)
8989
PHP_ME(swoole_lock, __destruct, arginfo_class_Swoole_Lock___destruct, ZEND_ACC_PUBLIC)
9090
PHP_ME(swoole_lock, lock, arginfo_class_Swoole_Lock_lock, ZEND_ACC_PUBLIC)
91-
PHP_ME(swoole_lock, lockwait, arginfo_class_Swoole_Lock_locakwait, ZEND_ACC_PUBLIC)
91+
PHP_ME(swoole_lock, lockwait, arginfo_class_Swoole_Lock_lockwait, ZEND_ACC_PUBLIC)
9292
PHP_ME(swoole_lock, trylock, arginfo_class_Swoole_Lock_trylock, ZEND_ACC_PUBLIC)
9393
PHP_ME(swoole_lock, lock_read, arginfo_class_Swoole_Lock_lock_read, ZEND_ACC_PUBLIC)
9494
PHP_ME(swoole_lock, trylock_read, arginfo_class_Swoole_Lock_trylock_read, ZEND_ACC_PUBLIC)
@@ -170,17 +170,42 @@ static PHP_METHOD(swoole_lock, lock) {
170170

171171
static PHP_METHOD(swoole_lock, lockwait) {
172172
double timeout = 1.0;
173+
// 0: write lock, 1: read lock(only for rwlock)
174+
zend_long kind = 0;
173175

174-
ZEND_PARSE_PARAMETERS_START(0, 1)
176+
ZEND_PARSE_PARAMETERS_START(0, 2)
175177
Z_PARAM_OPTIONAL
176178
Z_PARAM_DOUBLE(timeout)
179+
Z_PARAM_LONG(kind)
177180
ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
178181

179182
Lock *lock = php_swoole_lock_get_and_check_ptr(ZEND_THIS);
180-
if (lock->get_type() != Lock::MUTEX) {
183+
if (!(lock->get_type() == Lock::MUTEX
184+
#ifdef HAVE_RWLOCK
185+
|| lock->get_type() == Lock::RW_LOCK
186+
#endif
187+
)) {
188+
#ifdef HAVE_RWLOCK
189+
zend_throw_exception(swoole_exception_ce, "only mutex and rwlock supports lockwait", -2);
190+
#else
181191
zend_throw_exception(swoole_exception_ce, "only mutex supports lockwait", -2);
192+
#endif
193+
182194
RETURN_FALSE;
183195
}
196+
#ifdef HAVE_RWLOCK
197+
if (lock->get_type() == Lock::RW_LOCK) {
198+
RWLock *rwlock = dynamic_cast<RWLock *>(lock);
199+
if (rwlock == nullptr) {
200+
zend_throw_exception(swoole_exception_ce, "wrong lock type", -3);
201+
RETURN_FALSE;
202+
}
203+
if (kind == 1) {
204+
SW_LOCK_CHECK_RETURN(rwlock->lock_rd_wait((int) (timeout * 1000)));
205+
}
206+
SW_LOCK_CHECK_RETURN(rwlock->lock_wait((int) (timeout * 1000)));
207+
}
208+
#endif
184209
Mutex *mutex = dynamic_cast<Mutex *>(lock);
185210
if (mutex == nullptr) {
186211
zend_throw_exception(swoole_exception_ce, "wrong lock type", -3);

include/swoole_lock.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ class RWLock final : public Lock {
8888
int unlock() override;
8989
int trylock_rd() override;
9090
int trylock() override;
91+
int lock_wait(int timeout_msec);
92+
int lock_rd_wait(int timeout_msec);
9193
};
9294
#endif
9395

src/lock/rw_lock.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,20 @@ int RWLock::lock_rd() {
5252
return pthread_rwlock_rdlock(&impl->_lock);
5353
}
5454

55+
int RWLock::lock_rd_wait(int timeout_msec) {
56+
timespec timeo;
57+
realtime_get(&timeo);
58+
realtime_add(&timeo, timeout_msec);
59+
return pthread_rwlock_timedrdlock(&impl->_lock, &timeo);
60+
}
61+
62+
int RWLock::lock_wait(int timeout_msec) {
63+
timespec timeo;
64+
realtime_get(&timeo);
65+
realtime_add(&timeo, timeout_msec);
66+
return pthread_rwlock_timedwrlock(&impl->_lock, &timeo);
67+
}
68+
5569
int RWLock::lock() {
5670
return pthread_rwlock_wrlock(&impl->_lock);
5771
}

0 commit comments

Comments
 (0)