1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- ***********
- Portability
- ***********
- .. _portability-thread-safety:
- Thread safety
- -------------
- Jansson is thread safe and has no mutable global state. The only
- exceptions are the hash function seed and memory allocation functions,
- see below.
- There's no locking performed inside Jansson's code, so a multithreaded
- program must perform its own locking if JSON values are shared by
- multiple threads. Jansson's reference counting semantics may make this
- a bit harder than it seems, as it's possible to have a reference to a
- value that's also stored inside a list or object. Modifying the
- container (adding or removing values) may trigger concurrent access to
- such values, as containers manage the reference count of their
- contained values. Bugs involving concurrent incrementing or
- decrementing of deference counts may be hard to track.
- The encoding functions (:func:`json_dumps()` and friends) track
- reference loops by modifying the internal state of objects and arrays.
- For this reason, encoding functions must not be run on the same JSON
- values in two separate threads at the same time. As already noted
- above, be especially careful if two arrays or objects share their
- contained values with another array or object.
- If you want to make sure that two JSON value hierarchies do not
- contain shared values, use :func:`json_deep_copy()` to make copies.
- Hash function seed
- ==================
- To prevent an attacker from intentionally causing large JSON objects
- with specially crafted keys to perform very slow, the hash function
- used by Jansson is randomized using a seed value. The seed is
- automatically generated on the first explicit or implicit call to
- :func:`json_object()`, if :func:`json_object_seed()` has not been
- called beforehand.
- The seed is generated by using operating system's entropy sources if
- they are available (``/dev/urandom``, ``CryptGenRandom()``). The
- initialization is done in as thread safe manner as possible, by using
- architecture specific lockless operations if provided by the platform
- or the compiler.
- If you're using threads, it's recommended to autoseed the hashtable
- explicitly before spawning any threads by calling
- ``json_object_seed(0)`` , especially if you're unsure whether the
- initialization is thread safe on your platform.
- Memory allocation functions
- ===========================
- Memory allocation functions should be set at most once, and only on
- program startup. See :ref:`apiref-custom-memory-allocation`.
- Locale
- ------
- Jansson works fine under any locale.
- However, if the host program is multithreaded and uses ``setlocale()``
- to switch the locale in one thread while Jansson is currently encoding
- or decoding JSON data in another thread, the result may be wrong or
- the program may even crash.
- Jansson uses locale specific functions for certain string conversions
- in the encoder and decoder, and then converts the locale specific
- values to/from the JSON representation. This fails if the locale
- changes between the string conversion and the locale-to-JSON
- conversion. This can only happen in multithreaded programs that use
- ``setlocale()``, because ``setlocale()`` switches the locale for all
- running threads, not only the thread that calls ``setlocale()``.
- If your program uses ``setlocale()`` as described above, consider
- using the thread-safe ``uselocale()`` instead.
|