Browse Source

Merge branch 'improve-threading-docs'

Add a Threading section to the guide, and refer to internal threading
documentation for details.
v1.0-maintenance
Sami Vaarala 10 years ago
parent
commit
00fa06e854
  1. 78
      doc/threading.rst
  2. 2
      website/buildsite.py
  3. 1
      website/guide/intro.html
  4. 3
      website/guide/programming.html
  5. 27
      website/guide/threading.html

78
doc/threading.rst

@ -0,0 +1,78 @@
Duktape threading
=================
Overview
========
This document describes native threading options that can be used
with Duktape.
The basic threading rules are as follows.
Only one active native thread at a time per Duktape heap
--------------------------------------------------------
When user code calls e.g. ``duk_call()``, control flow is transferred to
Duktape. Duktape executes with that native thread until the original call
returns or errors out. While Duktape has control, it may execute multiple
Duktape threads (coroutines, not to be confused with native threads).
The caller must not interact with the Duktape heap with any other native
thread until the original call returns.
After the original call returns, further calls into Duktape may use a
different native thread, but never at the same time.
Multiple native threads can execute code on separate Duktape heaps
------------------------------------------------------------------
Multiple threads can use different Duktape heaps: each heap is entirely
independent.
Although Duktape itself is fully re-entrant, there are some situations
(discussed separately below) which can limit re-entrancy and prevent
running multiple threads at the same time, even when they run code in
separate Duktape heaps.
Platform limitations on re-entrancy
===================================
Lack of variadic preprocessor macros
------------------------------------
When variadic preprocessor macros are not available, Duktape currently
passes some fields through globals in that case. This creates a race
condition where error information (``__FILE__`` and ``__LINE__``, for
instance) can be corrupted for errors thrown in different Duktape heaps.
This should not cause unsafe behavior but may corrupt error messages
or tracebacks.
.. note:: This limitation can be fixed by passing these values through
duk_context (duk_hthread) instead of globals, but at the moment
Duktape public API macros don't access duk_hthread directly.
There is no longer a reason for this limitation because duktape.h
sees the internal structures (even when compiling application
code). A fix is scheduled for Duktape 1.1 release.
Non-re-entrant system calls
---------------------------
Duktape uses some system calls which don't always have re-entrant variants
(or perhaps the re-entrant variants don't work). This mainly impacts the
Date built-in, which uses ``gmtime_r()`` and ``localtime_r()`` on UNIX when
they are available, but falls back to ``gmtime()`` and ``localtime()`` if
the platform doesn't support them.
The impact on multithreading behavior depends on the non-re-entrant system
calls in question.
A few workarounds:
* Implement your own re-entrant native functions (e.g. date/time functions) for
those not provided by your platform. You'll need to change Duktape internals
to make Duktape use the replacements.
* Replace the built-ins (such as ``Date``) entirely with a replacement
written specifically for your platform. This approach may allow you to
avoid changes to Duktape internals as the non-re-entrant calls won't be
used.

2
website/buildsite.py

@ -907,6 +907,7 @@ def generateGuide():
navlinks.append(['#coroutines', 'Coroutines'])
navlinks.append(['#virtualproperties', 'Virtual properties'])
navlinks.append(['#internalproperties', 'Internal properties'])
navlinks.append(['#threading', 'Threading'])
navlinks.append(['#sandboxing', 'Sandboxing'])
navlinks.append(['#performance', 'Performance'])
navlinks.append(['#compiling', 'Compiling'])
@ -948,6 +949,7 @@ def generateGuide():
res += processRawDoc('guide/coroutines.html')
res += processRawDoc('guide/virtualproperties.html')
res += processRawDoc('guide/internalproperties.html')
res += processRawDoc('guide/threading.html')
res += processRawDoc('guide/sandboxing.html')
res += processRawDoc('guide/performance.html')
res += processRawDoc('guide/compiling.html')

1
website/guide/intro.html

@ -144,6 +144,7 @@ wrappers are discussed in detail.</p>
<a href="#coroutines">Coroutines</a>,
<a href="#virtualproperties">Virtual properties</a>,
<a href="#internalproperties">Internal properties</a>,
<a href="#threading">Threading</a>,
<a href="#sandboxing">Sandboxing</a>.
</p>

3
website/guide/programming.html

@ -65,7 +65,8 @@ way or another.</p>
as its first argument: no global variables or states are used, and there are
no restrictions on running multiple, independent Duktape heaps and contexts
at the same time. There are multi-threading restrictions, however: only one
native thread can execute any code within a single heap at any time.</p>
native thread can execute any code within a single heap at any time, see
<a href="#threading">Threading</a>.</p>
<p>To create a Duktape heap and an initial context inside the heap, you can
simply use:</p>

27
website/guide/threading.html

@ -0,0 +1,27 @@
<h1 id="threading">Threading</h1>
<p>Duktape supports a limited form of multithreading:</p>
<ul>
<li>A particular Duktape heap created with <code>duk_create_heap()</code> is
single threaded: only one native thread can execute code in the heap at a
time. The native thread can change over time, as long as two native threads
are not active at the same time in the same Duktape heap.</li>
<li>Duktape heaps are completely isolated from each other. Multiple native
threads can execute code at the same time, as long as there is only one
active native thread per Duktape heap.</li>
</ul>
<p>For some background, a Duktape heap is a single memory management region
regardless of how many Duktape threads exist in the heap (don't confuse native
threads and Duktape threads). Because the Duktape threads in a heap can share
object references, multithreading support would need synchronization for garbage
collection and all object handling. Synchronization would be a major
portability issue, so a practical approach is to limit a Duktape heap to be
single threaded. Duktape heaps don't share anything so there are no threading
limitations between them as a general rule. However, when some platform features
are not available (such as variadic preprocessor macros or re-entrant system calls)
there are some limitations.</p>
<p>See
<a href="https://github.com/svaarala/duktape/blob/master/doc/threading.rst">threading.rst</a>
for a detailed discussion of threading limitations and best practices.</p>
Loading…
Cancel
Save