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