Skip to content

Commit 418d1d6

Browse files
committed
Add timeout parameter to file watch method
1 parent 2a556d3 commit 418d1d6

File tree

4 files changed

+42
-13
lines changed

4 files changed

+42
-13
lines changed

src/Symfony/Component/Filesystem/Filesystem.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -732,18 +732,19 @@ public function appendToFile($filename, $content)
732732
*
733733
* @param mixed $path The path to watch for changes. Can be a path to a file or directory, iterator or array with paths
734734
* @param callable $callback The callback to execute when a change is detected
735+
* @param float $timeout The time in milliseconds to wait between checking for changes (defaults to 1000 when inotify is not available)
735736
*
736-
* @throws \InvalidArgumentException
737+
* @throws \InvalidArgumentException|IOException
737738
*/
738-
public function watch($path, callable $callback)
739+
public function watch($path, callable $callback, float $timeout = null)
739740
{
740741
if (\extension_loaded('inotify')) {
741742
$watcher = new INotifyWatcher();
742743
} else {
743744
$watcher = new FileChangeWatcher();
744745
}
745746

746-
$watcher->watch($path, $callback);
747+
$watcher->watch($path, $callback, $timeout);
747748
}
748749

749750
private function toIterable($files): iterable

src/Symfony/Component/Filesystem/Watcher/FileChangeWatcher.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,12 @@ public function __construct()
2525
$this->locator = new FileResourceLocator();
2626
}
2727

28-
public function watch($path, callable $callback)
28+
public function watch($path, callable $callback, float $timeout = null)
2929
{
30+
if (null === $timeout) {
31+
$timeout = 1000;
32+
}
33+
3034
$resource = $this->locator->locate($path);
3135

3236
if (!$resource) {
@@ -42,7 +46,7 @@ public function watch($path, callable $callback)
4246
}
4347
}
4448

45-
sleep(1);
49+
usleep($timeout * 1000);
4650
}
4751
}
4852
}

src/Symfony/Component/Filesystem/Watcher/INotifyWatcher.php

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,50 @@
1111

1212
namespace Symfony\Component\Filesystem\Watcher;
1313

14+
use Symfony\Component\Filesystem\Exception\IOException;
15+
1416
/**
1517
* @internal
1618
*/
1719
class INotifyWatcher implements WatcherInterface
1820
{
19-
public function watch($path, callable $callback)
21+
public function watch($path, callable $callback, float $timeout = null)
2022
{
2123
$inotifyInit = inotify_init();
22-
$dir = false;
2324

24-
if (is_dir($path)) {
25+
if (false === $inotifyInit) {
26+
throw new IOException('Unable initialize inotify', 0, null, $path);
27+
}
28+
29+
stream_set_blocking($inotifyInit, false);
30+
31+
$isDir = is_dir($path);
32+
33+
if ($isDir) {
2534
$watchId = inotify_add_watch($inotifyInit, $path, IN_CREATE | IN_DELETE | IN_MODIFY);
26-
$dir = true;
2735
} else {
2836
$watchId = inotify_add_watch($inotifyInit, $path, IN_MODIFY);
2937
}
3038

3139
try {
32-
$run = true;
33-
while ($run) {
40+
$read = [$inotifyInit];
41+
$write = null;
42+
$except = null;
43+
$tvSec = $timeout === null ? null : 0;
44+
$tvUsec = $timeout === null ? null : $timeout * 1000;
45+
46+
while (true) {
47+
if (0 === stream_select($read, $write, $except, $tvSec, $tvUsec)) {
48+
$read = [$inotifyInit];
49+
continue;
50+
}
51+
3452
$events = inotify_read($inotifyInit);
3553

54+
if (false === $events) {
55+
continue;
56+
}
57+
3658
foreach ($events as $event) {
3759
$code = null;
3860
switch ($event['mask']) {
@@ -47,7 +69,9 @@ public function watch($path, callable $callback)
4769
break;
4870
}
4971

50-
$run = false !== $callback(($dir ? $path : '').$event['name'], $code);
72+
if (false === $callback(($isDir ? $path : '').$event['name'], $code)) {
73+
break;
74+
}
5175
}
5276
}
5377
} finally {

src/Symfony/Component/Filesystem/Watcher/WatcherInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@
1313

1414
interface WatcherInterface
1515
{
16-
public function watch($path, callable $callback);
16+
public function watch($path, callable $callback, float $timeout = null);
1717
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy