blob: 5e5ac5aa781786143697eac0623c379f9f4b1c7c (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
<?php
/**
*
* @package testing
* @copyright (c) 2012 phpBB Group
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
class phpbb_lock_flock_test extends phpbb_test_case
{
public function test_lock()
{
$path = __DIR__ . '/../tmp/precious';
$lock = new \phpbb\lock\flock($path);
$ok = $lock->acquire();
$this->assertTrue($ok);
$lock->release();
}
public function test_consecutive_locking()
{
$path = __DIR__ . '/../tmp/precious';
$lock = new \phpbb\lock\flock($path);
$ok = $lock->acquire();
$this->assertTrue($ok);
$this->assertTrue($lock->owns_lock());
$lock->release();
$this->assertFalse($lock->owns_lock());
$ok = $lock->acquire();
$this->assertTrue($ok);
$this->assertTrue($lock->owns_lock());
$lock->release();
$this->assertFalse($lock->owns_lock());
$ok = $lock->acquire();
$this->assertTrue($ok);
$this->assertTrue($lock->owns_lock());
$lock->release();
$this->assertFalse($lock->owns_lock());
}
/* This hangs the process.
public function test_concurrent_locking_fail()
{
$path = __DIR__ . '/../tmp/precious';
$lock1 = new \phpbb\lock\flock($path);
$ok = $lock1->acquire();
$this->assertTrue($ok);
$lock2 = new \phpbb\lock\flock($path);
$ok = $lock2->acquire();
$this->assertFalse($ok);
$lock->release();
$ok = $lock2->acquire();
$this->assertTrue($ok);
}
*/
public function test_concurrent_locking()
{
if (!function_exists('pcntl_fork'))
{
$this->markTestSkipped('pcntl extension and pcntl_fork are required for this test');
}
$path = __DIR__ . '/../tmp/precious';
$pid = pcntl_fork();
if ($pid)
{
// parent
// wait 0.5 s, acquire the lock, note how long it took
sleep(1);
$lock = new \phpbb\lock\flock($path);
$start = time();
$ok = $lock->acquire();
$delta = time() - $start;
$this->assertTrue($ok);
$this->assertTrue($lock->owns_lock());
$this->assertGreaterThan(0.5, $delta, 'First lock acquired too soon');
$lock->release();
$this->assertFalse($lock->owns_lock());
// acquire again, this should be instantaneous
$start = time();
$ok = $lock->acquire();
$delta = time() - $start;
$this->assertTrue($ok);
$this->assertTrue($lock->owns_lock());
$this->assertLessThan(0.1, $delta, 'Second lock not acquired instantaneously');
// reap the child
$status = null;
pcntl_waitpid($pid, $status);
}
else
{
// child
// immediately acquire the lock and sleep for 2 s
$lock = new \phpbb\lock\flock($path);
$ok = $lock->acquire();
$this->assertTrue($ok);
$this->assertTrue($lock->owns_lock());
sleep(2);
$lock->release();
$this->assertFalse($lock->owns_lock());
// and go away silently
pcntl_exec('/usr/bin/env', array('true'));
}
}
}
|