From 56578ba215bcdd2e3faa71e3b47d617cf6d32dc0 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Tue, 28 Aug 2018 15:56:30 +0200 Subject: [PATCH] doc: fix up warning text about character devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The text contained a number of inaccuracies: - The main thread is never blocked by a stream close. - There is no such thing as an EOF character on the OS level, the libuv level, or the Node.js stream level. - These streams *do* respond to `.close()`, but pending reads can delay this indefinitely. - Pushing a random character into the stream works only when the source data can be controlled; Using the JS `.push()` method is something different, and does not “unblock” any threads. Refs: https://github.com/nodejs/node/pull/21212 --- doc/api/fs.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/doc/api/fs.md b/doc/api/fs.md index bb22690003fdca..636fcacc228c05 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -1464,23 +1464,24 @@ the specified file descriptor. This means that no `'open'` event will be emitted. `fd` should be blocking; non-blocking `fd`s should be passed to [`net.Socket`][]. -The blocking `fd`, if pointing to a character device (such as keyboard or -sound card) can potentially block the main thread on stream close. This is -because these devices do not produce EOF character as part of their data -flow cycle, and thereby exemplify endless streams. As a result, they do not -respond to `stream.close()`. A workaround is to close the stream first -using `stream.close()` and then push a random character into the stream, and -issue a single read. This unblocks the reader thread, leads to the completion -of the data flow cycle, and the actual closing of the stream. +If `fd` points to a character device that only supports blocking reads +(such as keyboard or sound card), read operations do not finish until data is +available. This can prevent the process from exiting and the stream from +closing naturally. ```js const fs = require('fs'); // Create a stream from some character device. const stream = fs.createReadStream('/dev/input/event0'); setTimeout(() => { - stream.close(); // This does not close the stream. + stream.close(); // This may not close the stream. + // Artificially marking end-of-stream, as if the underlying resource had + // indicated end-of-file by itself, allows the stream to close. + // This does not cancel pending read operations, and if there is such an + // operation, the process may still not be able to exit successfully + // until it finishes. stream.push(null); - stream.read(0); // Pushing a null and reading leads to close. + stream.read(0); }, 100); ```