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