Skip to content

Commit 5e7c651

Browse files
gireeshpunathiltargos
authored andcommitted
doc: warn against streaming from character devices
charcter device streaming works just like any other streams, but hangs on the close callsite due to the worker thread being blocked on the read and main thread waiting for any async event that may not occur. Document this behavior and suggest a potential workaround. Fixes: #15439 PR-URL: #21212 Reviewed-By: Vse Mozhet Byt <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Trivikram Kamat <[email protected]>
1 parent 609ae33 commit 5e7c651

File tree

1 file changed

+20
-0
lines changed

1 file changed

+20
-0
lines changed

doc/api/fs.md

+20
Original file line numberDiff line numberDiff line change
@@ -1459,6 +1459,26 @@ the specified file descriptor. This means that no `'open'` event will be
14591459
emitted. `fd` should be blocking; non-blocking `fd`s should be passed to
14601460
[`net.Socket`][].
14611461

1462+
The blocking `fd`, if pointing to a character device (such as keyboard or
1463+
sound card) can potentially block the main thread on stream close. This is
1464+
because these devices do not produce EOF character as part of their data
1465+
flow cycle, and thereby exemplify endless streams. As a result, they do not
1466+
respond to `stream.close()`. A workaround is to close the stream first
1467+
using `stream.close()` and then push a random character into the stream, and
1468+
issue a single read. This unblocks the reader thread, leads to the completion
1469+
of the data flow cycle, and the actual closing of the stream.
1470+
1471+
```js
1472+
const fs = require('fs');
1473+
// Create a stream from some character device.
1474+
const stream = fs.createReadStream('/dev/input/event0');
1475+
setTimeout(() => {
1476+
stream.close(); // This does not close the stream.
1477+
stream.push(null);
1478+
stream.read(0); // Pushing a null and reading leads to close.
1479+
}, 100);
1480+
```
1481+
14621482
If `autoClose` is false, then the file descriptor won't be closed, even if
14631483
there's an error. It is the application's responsibility to close it and make
14641484
sure there's no file descriptor leak. If `autoClose` is set to true (default

0 commit comments

Comments
 (0)