mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
FR #67990 - Added nowait argument to sem_acquire
This commit is contained in:
parent
3571a68ab9
commit
0b648a424f
4 changed files with 123 additions and 6 deletions
4
NEWS
4
NEWS
|
@ -45,6 +45,10 @@ PHP NEWS
|
|||
- Session:
|
||||
. Fixed bug #67972 (SessionHandler Invalid memory read create_sid()). (Adam)
|
||||
|
||||
- Sysvsem:
|
||||
. Implemented FR #67990 (Add optional nowait argument to sem_acquire).
|
||||
(Matteo)
|
||||
|
||||
28 Aug 2014, PHP 5.6.0
|
||||
|
||||
- Apache2 Handler SAPI:
|
||||
|
|
|
@ -66,6 +66,7 @@ ZEND_END_ARG_INFO()
|
|||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_sem_acquire, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, sem_identifier)
|
||||
ZEND_ARG_INFO(0, nowait)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_sem_release, 0, 0, 1)
|
||||
|
@ -298,11 +299,18 @@ PHP_FUNCTION(sem_get)
|
|||
static void php_sysvsem_semop(INTERNAL_FUNCTION_PARAMETERS, int acquire)
|
||||
{
|
||||
zval *arg_id;
|
||||
zend_bool nowait = 0;
|
||||
sysvsem_sem *sem_ptr;
|
||||
struct sembuf sop;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg_id) == FAILURE) {
|
||||
return;
|
||||
if (acquire) {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|b", &arg_id, &nowait) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg_id) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_FETCH_RESOURCE(sem_ptr, sysvsem_sem *, &arg_id, -1, "SysV semaphore", php_sysvsem_module.le_sem);
|
||||
|
@ -314,11 +322,13 @@ static void php_sysvsem_semop(INTERNAL_FUNCTION_PARAMETERS, int acquire)
|
|||
|
||||
sop.sem_num = SYSVSEM_SEM;
|
||||
sop.sem_op = acquire ? -1 : 1;
|
||||
sop.sem_flg = SEM_UNDO;
|
||||
sop.sem_flg = SEM_UNDO | (nowait ? IPC_NOWAIT : 0);
|
||||
|
||||
while (semop(sem_ptr->semid, &sop, 1) == -1) {
|
||||
if (errno != EINTR) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to %s key 0x%x: %s", acquire ? "acquire" : "release", sem_ptr->key, strerror(errno));
|
||||
if (errno != EAGAIN) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to %s key 0x%x: %s", acquire ? "acquire" : "release", sem_ptr->key, strerror(errno));
|
||||
}
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
|
|
103
ext/sysvsem/tests/nowait.phpt
Normal file
103
ext/sysvsem/tests/nowait.phpt
Normal file
|
@ -0,0 +1,103 @@
|
|||
--TEST--
|
||||
sem_acquire with nowait
|
||||
--SKIPIF--
|
||||
<?php // vim600: ts=4 sw=4 syn=php fdm=marker
|
||||
if(!extension_loaded('sysvsem') || !extension_loaded('pcntl')) {
|
||||
die("skip sysvsem and pcntl required");
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$SEMKEY = ftok(__FILE__, 'P'); // Semaphore key
|
||||
|
||||
$pid = pcntl_fork();
|
||||
|
||||
if ($pid) {
|
||||
echo "Parent.\n";
|
||||
|
||||
pcntl_signal(SIGCHLD, SIG_IGN);
|
||||
|
||||
// Get semaphore
|
||||
$sem_id = sem_get($SEMKEY, 1);
|
||||
if ($sem_id === FALSE) {
|
||||
echo "P: fail to get semaphore";
|
||||
exit;
|
||||
}
|
||||
echo "P: got semaphore $sem_id.\n";
|
||||
|
||||
register_shutdown_function(function () use ($sem_id) {
|
||||
echo "P: cleanup.\n";
|
||||
sem_remove($sem_id);
|
||||
});
|
||||
|
||||
// Acquire semaphore
|
||||
if (! sem_acquire($sem_id)) {
|
||||
echo "P: fail to acquire semaphore $sem_id.\n";
|
||||
sem_remove($sem_id);
|
||||
exit;
|
||||
}
|
||||
echo "P: success acquire semaphore $sem_id.\n";
|
||||
|
||||
usleep(20000);
|
||||
|
||||
echo "P: releases.\n";
|
||||
sem_release($sem_id);
|
||||
|
||||
usleep(5000);
|
||||
|
||||
// Acquire semaphore
|
||||
if (! sem_acquire($sem_id)) {
|
||||
echo "P: fail to acquire semaphore $sem_id.\n";
|
||||
sem_remove($sem_id);
|
||||
exit;
|
||||
}
|
||||
echo "P: success acquire semaphore $sem_id.\n";
|
||||
|
||||
$status = null;
|
||||
pcntl_waitpid($pid, $status);
|
||||
|
||||
} else {
|
||||
usleep(10000);
|
||||
echo "Child.\n";
|
||||
|
||||
// Get semaphore
|
||||
$sem_id = sem_get($SEMKEY, 1);
|
||||
if ($sem_id === FALSE) {
|
||||
echo "C: fail to get semaphore";
|
||||
exit;
|
||||
}
|
||||
echo "C: got semaphore $sem_id.\n";
|
||||
|
||||
// Acquire semaphore
|
||||
if (! sem_acquire($sem_id)) {
|
||||
echo "C: fail to acquire semaphore $sem_id.\n";
|
||||
exit;
|
||||
}
|
||||
echo "C: success acquire semaphore $sem_id.\n";
|
||||
|
||||
echo "C: releases.\n";
|
||||
sem_release($sem_id);
|
||||
|
||||
usleep(10000);
|
||||
|
||||
// Acquire semaphore
|
||||
if (! sem_acquire($sem_id, true)) {
|
||||
echo "C: fail to acquire semaphore $sem_id.\n";
|
||||
exit;
|
||||
}
|
||||
echo "C: success acquire semaphore $sem_id.\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Parent.
|
||||
P: got semaphore Resource id #%i.
|
||||
P: success acquire semaphore Resource id #%i.
|
||||
Child.
|
||||
C: got semaphore Resource id #%i.
|
||||
P: releases.
|
||||
C: success acquire semaphore Resource id #%i.
|
||||
C: releases.
|
||||
P: success acquire semaphore Resource id #%i.
|
||||
C: fail to acquire semaphore Resource id #%i.
|
||||
P: cleanup.
|
|
@ -9,8 +9,8 @@ if(!extension_loaded('sysvsem') || !extension_loaded('sysvshm')) {
|
|||
--FILE--
|
||||
<?php
|
||||
$MEMSIZE = 512; // size of shared memory to allocate
|
||||
$SEMKEY = 1; // Semaphore key
|
||||
$SHMKEY = 2; // Shared memory key
|
||||
$SEMKEY = ftok(__FILE__, 'P'); // Semaphore key
|
||||
$SHMKEY = ftok(__FILE__, 'Q'); // Shared memory key
|
||||
|
||||
echo "Start.\n";
|
||||
// Get semaphore
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue