docs: name the macros that turn off FILE* locking and bulk scans

parse() and sax_parse() now say that the FILE* is locked unless
JSON_DISABLE_UNLOCKED_FILE_IO is defined to 1, and the input-source
table and the performance page name JSON_DISABLE_STREAM_BULK_SCAN and
JSON_DISABLE_UNLOCKED_FILE_IO with what each turns off.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann committed 2026-11-11 22:21:47 +01:00
1 parent 81f81a2262
commit 73db3b5fdb
4 files changed
+17 -8

No files matched your search

+4 -4
View File
@@ -133,10 +133,10 @@ outside of a string, invalid) byte; see the [FAQ entry](../../home/faq.md#nul-by
ahead, so the stream is left exactly where it would be after reading one character at a time. With glibc
and the Apple C library, the characters the `#!cpp FILE` holds in its buffer are scanned in bulk like a stream's;
elsewhere a `#!cpp FILE*` is read one character at a time. Where the C library has unlocked stdio functions, the
file is locked only once, so other threads that use the same `FILE` object wait until parsing is done. See
[input sources and performance](../../features/parsing/index.md#input-sources-and-performance),
[`JSON_DISABLE_STREAM_BULK_SCAN`](../macros/json_disable_stream_bulk_scan.md), and
[`JSON_DISABLE_UNLOCKED_FILE_IO`](../macros/json_disable_unlocked_file_io.md).
file is locked only once, so other threads that use the same `FILE` object wait until parsing is done, unless
[`JSON_DISABLE_UNLOCKED_FILE_IO`](../macros/json_disable_unlocked_file_io.md) is defined to `1`. See
[input sources and performance](../../features/parsing/index.md#input-sources-and-performance) and
[`JSON_DISABLE_STREAM_BULK_SCAN`](../macros/json_disable_stream_bulk_scan.md).
## Examples
+2 -2
View File
@@ -124,8 +124,8 @@ consumer `sax` has a super-linear complexity.
A UTF-8 byte order mark is silently ignored.
When reading from a `#!c FILE*`, where the C library has unlocked stdio functions (see
[`JSON_DISABLE_UNLOCKED_FILE_IO`](../macros/json_disable_unlocked_file_io.md)), the file is locked while it is parsed.
When reading from a `#!c FILE*` where the C library has unlocked stdio functions, the file is locked while it is parsed,
unless [`JSON_DISABLE_UNLOCKED_FILE_IO`](../macros/json_disable_unlocked_file_io.md) is defined to `1`.
The lock is recursive, so the SAX handler may use the same file with stdio functions, but it must not wait for another
thread that uses the same `FILE` object.
@@ -80,6 +80,12 @@ them faster than others:
| `#!cpp FILE*` | with glibc and the Apple C library, the characters the `FILE` holds in its buffer are scanned in bulk like a stream's; elsewhere one character at a time; where the C library has unlocked stdio functions, the file is locked once for the whole parse |
| other iterator ranges (e.g., `#!cpp std::list<char>`, `#!cpp std::istreambuf_iterator<char>`), wide strings | one character at a time |
Defining [`JSON_DISABLE_STREAM_BULK_SCAN`](../../api/macros/json_disable_stream_bulk_scan.md) to `1` turns off the bulk
scan of a stream buffer, so a `#!cpp std::istream` is read one character at a time. Defining
[`JSON_DISABLE_UNLOCKED_FILE_IO`](../../api/macros/json_disable_unlocked_file_io.md) to `1` makes a `#!cpp FILE*` read
every character with `std::fgetc`, without locking the file for the whole parse and without the bulk scan of its buffer
(which `JSON_DISABLE_STREAM_BULK_SCAN` does not affect). Neither changes any result.
Input in one block of memory is read even faster with the default options (no
[parser callback](../../api/basic_json/parser_callback_t.md), no comments, no trailing commas, and for `sax_parse()`
`strict = true`): `parse()`, `accept()`, and `sax_parse()` then read the grammar and the tokens in one loop over the
+5 -2
View File
@@ -29,8 +29,11 @@ up. Nothing is read ahead, so the stream is left exactly where it would be after
[`operator>>`](../api/operator_gtgt.md) can still read several values from one stream. A stream buffer without a get
area is read one character at a time. Where the C library has unlocked stdio functions, a `#!cpp FILE*` is locked once
per parse instead of once per character, and with glibc and the Apple C library, the characters in its buffer are
scanned in bulk as a stream's get area is. See
[input sources and performance](parsing/index.md#input-sources-and-performance) for the full table. Parsing from a
scanned in bulk as a stream's get area is.
[`JSON_DISABLE_STREAM_BULK_SCAN`](../api/macros/json_disable_stream_bulk_scan.md) turns off the bulk scan of streams, and
[`JSON_DISABLE_UNLOCKED_FILE_IO`](../api/macros/json_disable_unlocked_file_io.md) both the single lock and the bulk scan
of a `#!cpp FILE*`. See [input sources and performance](parsing/index.md#input-sources-and-performance) for the full
table. Parsing from a
stream takes about 1.15 to 1.45 times as long as parsing an equivalent `#!cpp std::string`, which `parse()` reads with
a parser of its own (see there).