]> granicus.if.org Git - php/commitdiff
FR #67990 - Added nowait argument to sem_acquire
authorMatteo Beccati <mbeccati@php.net>
Fri, 25 Jul 2014 09:21:47 +0000 (11:21 +0200)
committerMatteo Beccati <mbeccati@php.net>
Wed, 10 Sep 2014 05:31:25 +0000 (07:31 +0200)
NEWS
ext/sysvsem/sysvsem.c
ext/sysvsem/tests/nowait.phpt [new file with mode: 0644]
ext/sysvsem/tests/sysv.phpt

diff --git a/NEWS b/NEWS
index 3a6b250dec25cb200a4e3a1c9c940f89ab961b51..5f72e2449be4c9e595c231b5c9165074f903e01c 100644 (file)
--- 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:
index c30def8ba5d211c2f285645c5f8ce8c02d798c0b..fce70b9e02eaf586e4da37d5d52ef402118051bc 100644 (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;
                }
        }
diff --git a/ext/sysvsem/tests/nowait.phpt b/ext/sysvsem/tests/nowait.phpt
new file mode 100644 (file)
index 0000000..0a6fdf4
--- /dev/null
@@ -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.
index 6f52f3bd7ee661c737d47dbe540a7d9eee31a8f1..ccfcf03d322f3c249d1cbd4575870a5ff75f7b96 100644 (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