FR #67990 - Added nowait argument to sem_acquire

This commit is contained in:
Matteo Beccati 2014-07-25 11:21:47 +02:00
parent 3571a68ab9
commit 0b648a424f
4 changed files with 123 additions and 6 deletions

4
NEWS
View file

@ -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:

View file

@ -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;
}
}

View 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.

View file

@ -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