diff --git a/test/napi/napi-app/main.js b/test/napi/napi-app/main.js index 9c11801727f4..8d0b3c2e79bb 100644 --- a/test/napi/napi-app/main.js +++ b/test/napi/napi-app/main.js @@ -1,3 +1,8 @@ +// Node writes to a piped stdout asynchronously on POSIX: after one EAGAIN every +// console.log is queued until the event loop runs while the addons' printf keeps +// writing to the fd directly. Make it blocking so output stays in program order. +if (!process.isBun) process.stdout._handle?.setBlocking?.(true); + const tests = require("./module"); if (process.argv[2] === "self") { console.log( diff --git a/test/napi/napi-app/utils.h b/test/napi/napi-app/utils.h index 0711999a329e..3a0f69854b20 100644 --- a/test/napi/napi-app/utils.h +++ b/test/napi/napi-app/utils.h @@ -13,18 +13,21 @@ class BlockingStdoutScope { BlockingStdoutScope() { original = fcntl(1, F_GETFL); fcntl(1, F_SETFL, original & ~O_NONBLOCK); - setvbuf(stdout, nullptr, _IOFBF, 8192); fflush(stdout); + // Both runtimes start with stdout unbuffered. glibc keeps the existing + // 1-byte buffer when setvbuf is given a null buffer, so pass a real one. + setvbuf(stdout, buffer, _IOFBF, sizeof(buffer)); } ~BlockingStdoutScope() { fflush(stdout); fcntl(1, F_SETFL, original); - setvbuf(stdout, nullptr, _IOLBF, 0); + setvbuf(stdout, nullptr, _IONBF, 0); } private: int original; + inline static char buffer[8192]; }; #endif