summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatteo Beccati <mbeccati@php.net>2014-07-25 11:21:47 +0200
committerMatteo Beccati <mbeccati@php.net>2014-09-10 07:31:25 +0200
commit0b648a424fd0ee7039ba4cb50b2bc64c2773b58a (patch)
tree4bb06ff1960f629499ad36cda928f1d68e1c70e4
parent3571a68ab9f41258b4f25daba06fa98abce9281a (diff)
downloadphp-git-0b648a424fd0ee7039ba4cb50b2bc64c2773b58a.tar.gz
FR #67990 - Added nowait argument to sem_acquire
-rw-r--r--NEWS4
-rw-r--r--ext/sysvsem/sysvsem.c18
-rw-r--r--ext/sysvsem/tests/nowait.phpt103
-rw-r--r--ext/sysvsem/tests/sysv.phpt4
4 files changed, 123 insertions, 6 deletions
diff --git a/NEWS b/NEWS
index 3a6b250dec..5f72e2449b 100644
--- a/NEWS
+++ b/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:
diff --git a/ext/sysvsem/sysvsem.c b/ext/sysvsem/sysvsem.c
index c30def8ba5..fce70b9e02 100644
--- a/ext/sysvsem/sysvsem.c
+++ b/ext/sysvsem/sysvsem.c
@@ -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;
}
}
diff --git a/ext/sysvsem/tests/nowait.phpt b/ext/sysvsem/tests/nowait.phpt
new file mode 100644
index 0000000000..0a6fdf4a50
--- /dev/null
+++ b/ext/sysvsem/tests/nowait.phpt
@@ -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.
diff --git a/ext/sysvsem/tests/sysv.phpt b/ext/sysvsem/tests/sysv.phpt
index 6f52f3bd7e..ccfcf03d32 100644
--- a/ext/sysvsem/tests/sysv.phpt
+++ b/ext/sysvsem/tests/sysv.phpt
@@ -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