Skip to content

Commit 0b648a4

Browse files
committed
FR #67990 - Added nowait argument to sem_acquire
1 parent 3571a68 commit 0b648a4

File tree

4 files changed

+123
-6
lines changed

4 files changed

+123
-6
lines changed

NEWS

+4
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ PHP NEWS
4545
- Session:
4646
. Fixed bug #67972 (SessionHandler Invalid memory read create_sid()). (Adam)
4747

48+
- Sysvsem:
49+
. Implemented FR #67990 (Add optional nowait argument to sem_acquire).
50+
(Matteo)
51+
4852
28 Aug 2014, PHP 5.6.0
4953

5054
- Apache2 Handler SAPI:

ext/sysvsem/sysvsem.c

+14-4
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ ZEND_END_ARG_INFO()
6666

6767
ZEND_BEGIN_ARG_INFO_EX(arginfo_sem_acquire, 0, 0, 1)
6868
ZEND_ARG_INFO(0, sem_identifier)
69+
ZEND_ARG_INFO(0, nowait)
6970
ZEND_END_ARG_INFO()
7071

7172
ZEND_BEGIN_ARG_INFO_EX(arginfo_sem_release, 0, 0, 1)
@@ -298,11 +299,18 @@ PHP_FUNCTION(sem_get)
298299
static void php_sysvsem_semop(INTERNAL_FUNCTION_PARAMETERS, int acquire)
299300
{
300301
zval *arg_id;
302+
zend_bool nowait = 0;
301303
sysvsem_sem *sem_ptr;
302304
struct sembuf sop;
303305

304-
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg_id) == FAILURE) {
305-
return;
306+
if (acquire) {
307+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|b", &arg_id, &nowait) == FAILURE) {
308+
return;
309+
}
310+
} else {
311+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &arg_id) == FAILURE) {
312+
return;
313+
}
306314
}
307315

308316
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)
314322

315323
sop.sem_num = SYSVSEM_SEM;
316324
sop.sem_op = acquire ? -1 : 1;
317-
sop.sem_flg = SEM_UNDO;
325+
sop.sem_flg = SEM_UNDO | (nowait ? IPC_NOWAIT : 0);
318326

319327
while (semop(sem_ptr->semid, &sop, 1) == -1) {
320328
if (errno != EINTR) {
321-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to %s key 0x%x: %s", acquire ? "acquire" : "release", sem_ptr->key, strerror(errno));
329+
if (errno != EAGAIN) {
330+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to %s key 0x%x: %s", acquire ? "acquire" : "release", sem_ptr->key, strerror(errno));
331+
}
322332
RETURN_FALSE;
323333
}
324334
}

ext/sysvsem/tests/nowait.phpt

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
--TEST--
2+
sem_acquire with nowait
3+
--SKIPIF--
4+
<?php // vim600: ts=4 sw=4 syn=php fdm=marker
5+
if(!extension_loaded('sysvsem') || !extension_loaded('pcntl')) {
6+
die("skip sysvsem and pcntl required");
7+
}
8+
?>
9+
--FILE--
10+
<?php
11+
$SEMKEY = ftok(__FILE__, 'P'); // Semaphore key
12+
13+
$pid = pcntl_fork();
14+
15+
if ($pid) {
16+
echo "Parent.\n";
17+
18+
pcntl_signal(SIGCHLD, SIG_IGN);
19+
20+
// Get semaphore
21+
$sem_id = sem_get($SEMKEY, 1);
22+
if ($sem_id === FALSE) {
23+
echo "P: fail to get semaphore";
24+
exit;
25+
}
26+
echo "P: got semaphore $sem_id.\n";
27+
28+
register_shutdown_function(function () use ($sem_id) {
29+
echo "P: cleanup.\n";
30+
sem_remove($sem_id);
31+
});
32+
33+
// Acquire semaphore
34+
if (! sem_acquire($sem_id)) {
35+
echo "P: fail to acquire semaphore $sem_id.\n";
36+
sem_remove($sem_id);
37+
exit;
38+
}
39+
echo "P: success acquire semaphore $sem_id.\n";
40+
41+
usleep(20000);
42+
43+
echo "P: releases.\n";
44+
sem_release($sem_id);
45+
46+
usleep(5000);
47+
48+
// Acquire semaphore
49+
if (! sem_acquire($sem_id)) {
50+
echo "P: fail to acquire semaphore $sem_id.\n";
51+
sem_remove($sem_id);
52+
exit;
53+
}
54+
echo "P: success acquire semaphore $sem_id.\n";
55+
56+
$status = null;
57+
pcntl_waitpid($pid, $status);
58+
59+
} else {
60+
usleep(10000);
61+
echo "Child.\n";
62+
63+
// Get semaphore
64+
$sem_id = sem_get($SEMKEY, 1);
65+
if ($sem_id === FALSE) {
66+
echo "C: fail to get semaphore";
67+
exit;
68+
}
69+
echo "C: got semaphore $sem_id.\n";
70+
71+
// Acquire semaphore
72+
if (! sem_acquire($sem_id)) {
73+
echo "C: fail to acquire semaphore $sem_id.\n";
74+
exit;
75+
}
76+
echo "C: success acquire semaphore $sem_id.\n";
77+
78+
echo "C: releases.\n";
79+
sem_release($sem_id);
80+
81+
usleep(10000);
82+
83+
// Acquire semaphore
84+
if (! sem_acquire($sem_id, true)) {
85+
echo "C: fail to acquire semaphore $sem_id.\n";
86+
exit;
87+
}
88+
echo "C: success acquire semaphore $sem_id.\n";
89+
}
90+
91+
?>
92+
--EXPECTF--
93+
Parent.
94+
P: got semaphore Resource id #%i.
95+
P: success acquire semaphore Resource id #%i.
96+
Child.
97+
C: got semaphore Resource id #%i.
98+
P: releases.
99+
C: success acquire semaphore Resource id #%i.
100+
C: releases.
101+
P: success acquire semaphore Resource id #%i.
102+
C: fail to acquire semaphore Resource id #%i.
103+
P: cleanup.

ext/sysvsem/tests/sysv.phpt

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ if(!extension_loaded('sysvsem') || !extension_loaded('sysvshm')) {
99
--FILE--
1010
<?php
1111
$MEMSIZE = 512; // size of shared memory to allocate
12-
$SEMKEY = 1; // Semaphore key
13-
$SHMKEY = 2; // Shared memory key
12+
$SEMKEY = ftok(__FILE__, 'P'); // Semaphore key
13+
$SHMKEY = ftok(__FILE__, 'Q'); // Shared memory key
1414

1515
echo "Start.\n";
1616
// Get semaphore

0 commit comments

Comments
 (0)