portability.rst 3.3 KB

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