Skip to content

Commit be01892

Browse files
committed
fix: exception when watcher services are closed
When watcher are closed and there is still a running thread waiting for some event, an java.nio.file.ClosedWatchServiceException is thrown. According to the javadoc (https://docs.oracle.com/javase/7/docs/api/java/nio/file/WatchService.html#take%28%29) this is the expected behavior, so we don't need to propagate this exception outside the thread.
1 parent d05094a commit be01892

1 file changed

Lines changed: 59 additions & 54 deletions

File tree

restx-common/src/main/java/restx/common/watch/StdWatcherService.java

Lines changed: 59 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -111,60 +111,65 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
111111
* Process all events for keys queued to the watcher
112112
*/
113113
void processEvents() {
114-
for (;;) {
115-
116-
// wait for key to be signalled
117-
WatchKey key;
118-
try {
119-
key = watcher.take();
120-
} catch (InterruptedException x) {
121-
return;
122-
}
123-
124-
Path dir = keys.get(key);
125-
if (dir == null) {
126-
System.err.println("WatchKey not recognized!!");
127-
continue;
128-
}
129-
130-
for (WatchEvent<?> event: key.pollEvents()) {
131-
WatchEvent.Kind kind = event.kind();
132-
133-
// Context for directory entry event is the file name of entry
134-
WatchEvent<Path> ev = cast(event);
135-
136-
coalescor.post(FileWatchEvent.newInstance(root, dir, ev.context(), ev.kind(), ev.count()));
137-
138-
if (kind == OVERFLOW) {
139-
continue;
140-
}
141-
142-
Path name = ev.context();
143-
Path child = dir.resolve(name);
144-
145-
// if directory is created, and watching recursively, then
146-
// register it and its sub-directories
147-
if (recursive && (kind == ENTRY_CREATE)) {
148-
try {
149-
if (Files.isDirectory(child, NOFOLLOW_LINKS)) {
150-
registerAll(child);
151-
}
152-
} catch (IOException x) {
153-
// ignore to keep sample readbale
154-
}
155-
}
156-
}
157-
158-
// reset key and remove from set if directory no longer accessible
159-
boolean valid = key.reset();
160-
if (!valid) {
161-
keys.remove(key);
162-
163-
// all directories are inaccessible
164-
if (keys.isEmpty()) {
165-
break;
166-
}
167-
}
114+
try {
115+
for (;;) {
116+
117+
// wait for key to be signalled
118+
WatchKey key;
119+
try {
120+
key = watcher.take();
121+
} catch (InterruptedException x) {
122+
return;
123+
}
124+
125+
Path dir = keys.get(key);
126+
if (dir == null) {
127+
System.err.println("WatchKey not recognized!!");
128+
continue;
129+
}
130+
131+
for (WatchEvent<?> event: key.pollEvents()) {
132+
WatchEvent.Kind kind = event.kind();
133+
134+
// Context for directory entry event is the file name of entry
135+
WatchEvent<Path> ev = cast(event);
136+
137+
coalescor.post(FileWatchEvent.newInstance(root, dir, ev.context(), ev.kind(), ev.count()));
138+
139+
if (kind == OVERFLOW) {
140+
continue;
141+
}
142+
143+
Path name = ev.context();
144+
Path child = dir.resolve(name);
145+
146+
// if directory is created, and watching recursively, then
147+
// register it and its sub-directories
148+
if (recursive && (kind == ENTRY_CREATE)) {
149+
try {
150+
if (Files.isDirectory(child, NOFOLLOW_LINKS)) {
151+
registerAll(child);
152+
}
153+
} catch (IOException x) {
154+
// ignore to keep sample readbale
155+
}
156+
}
157+
}
158+
159+
// reset key and remove from set if directory no longer accessible
160+
boolean valid = key.reset();
161+
if (!valid) {
162+
keys.remove(key);
163+
164+
// all directories are inaccessible
165+
if (keys.isEmpty()) {
166+
break;
167+
}
168+
}
169+
}
170+
} catch (ClosedWatchServiceException e) {
171+
// just ignore this exception, it just meant that the service has been closed,
172+
// while the current thread was waiting some event with the "take" method.
168173
}
169174
}
170175

0 commit comments

Comments
 (0)