You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/CMakeLists.txt
+2-2Lines changed: 2 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -24,9 +24,9 @@
24
24
# # # Required minimum version statement
25
25
cmake_minimum_required(VERSION3.5.0)
26
26
27
-
find_package(PythonInterp3)
27
+
find_package(Python3COMPONENTSInterpreter)
28
28
29
-
if (NOTPYTHONINTERP_FOUND)
29
+
if (NOTPython3_Interpreter_FOUND)
30
30
message(FATAL_ERROR"sol2 documentation cannot be generated as python 3 has not been found: install or set the python 3 interpreter for the docs to find it and be sure to pip install sphinx")
Copy file name to clipboardExpand all lines: docs/source/api/coroutine.rst
+32-56Lines changed: 32 additions & 56 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,61 +3,37 @@ coroutine
3
3
*resumable/yielding functions from Lua*
4
4
5
5
6
-
A ``coroutine`` is a :doc:`reference<reference>` to a function in Lua that can be called multiple times to yield a specific result. It is run on the :doc:`lua_State<state>` that was used to create it (see :doc:`thread<thread>` for an example on how to get a coroutine that runs on a thread separate from your usual "main" :doc:`lua_State<state>`).
6
+
A ``coroutine`` is a :doc:`reference<reference>` to a function in Lua that can be called multiple times to yield a specific result. It is a cooperative function. It is run on the :doc:`lua_State<state>` that was used to create it (see :doc:`thread<thread>` for an example on how to get a coroutine that runs on a stack space separate from your usual "main" stack space:doc:`lua_State<state>`).
7
7
8
-
The ``coroutine`` object is entirely similar to the :doc:`protected_function<protected_function>` object, with additional member functions to check if a coroutine has yielded (:doc:`call_status::yielded<types>`) and is thus runnable again, whether it has completed (:ref:`call_status::ok<call-status>`) and thus cannot yield anymore values, or whether it has suffered an error (see :ref:`status()<status>` and :ref:`call_status<call-status>`'s error codes).
8
+
The ``coroutine`` object is entirely similar to the :doc:`protected_function<protected_function>` object, with additional member functions to check if a coroutine has yielded (:doc:`call_status::yielded<types>`) and is thus runnable again, whether it has completed (:ref:`call_status::ok<call-status>`) and thus cannot yield anymore values, or whether it has suffered an error (see :ref:`status()<thread-status>`'s and :ref:`call_status<call-status>`'s error codes).
9
9
10
10
For example, you can work with a coroutine like this:
Note that this code doesn't check for errors: to do so, you can call the function and assign it as ``auto result = loop_coroutine();``, then check ``result.valid()`` as is the case with :doc:`protected_function<protected_function>`.
35
27
36
-
for (int counter = 0; // start from 0
37
-
counter < 10 && cr; // we want 10 values, and we only want to run if the coroutine "cr" is valid
38
-
// Alternative: counter < 10 && cr.valid()
39
-
++counter) {
40
-
// Call the coroutine, does the computation and then suspends
41
-
int value = cr();
42
-
}
28
+
Finally, you can run this coroutine on another stack space (NOT a different computer thread: Lua uses the term 'thread' a bit strangely, as we follow its usage of the term, but it is NOT a separate thread) by doing the following:
43
29
44
-
Note that this code doesn't check for errors: to do so, you can call the function and assign it as ``auto result = cr();``, then check ``result.valid()`` as is the case with :doc:`protected_function<protected_function>`. Finally, you can run this coroutine on another thread by doing the following:
// Call the coroutine, does the computation and then suspends
59
-
int value = cr();
60
-
}
61
37
62
38
The following are the members of ``sol::coroutine``:
63
39
@@ -73,44 +49,44 @@ members
73
49
Grabs the coroutine at the specified index given a ``lua_State*``.
74
50
75
51
.. code-block:: cpp
76
-
:caption: returning the coroutine's status
52
+
:caption: returning the coroutine's status
77
53
:name: sol-coroutine-status
78
54
79
-
call_status status() const noexcept;
55
+
call_status status() const noexcept;
80
56
81
57
Returns the status of a coroutine.
82
58
83
59
84
60
.. code-block:: cpp
85
-
:caption: checks for an error
61
+
:caption: checks for an error
86
62
:name: sol-coroutine-error
87
63
88
-
bool error() const noexcept;
64
+
bool error() const noexcept;
89
65
90
66
Checks if an error occured when the coroutine was run.
91
67
92
68
.. _runnable:
93
69
94
70
.. code-block:: cpp
95
-
:caption: runnable and explicit operator bool
71
+
:caption: runnable and explicit operator bool
96
72
:name: sol-coroutine-runnable
97
73
98
-
bool runnable () const noexcept;
99
-
explicit operator bool() const noexcept;
74
+
bool runnable () const noexcept;
75
+
explicit operator bool() const noexcept;
100
76
101
77
These functions allow you to check if a coroutine can still be called (has more values to yield and has not errored). If you have a coroutine object ``coroutine my_co = /*...*/``, you can either check ``runnable()`` or do ``if ( my_co ) { /* use coroutine */ }``.
Calls the coroutine. The second ``operator()`` lets you specify the templated return types using the ``my_co(sol::types<int, std::string>, ...)`` syntax. Check ``status()`` afterwards for more information about the success of the run or just check the coroutine object in an ifs tatement, as shown :ref:`above<runnable>`.
92
+
Calls the coroutine. The second ``operator()`` lets you specify the templated return types using the ``my_co(sol::types<int, std::string>, ...)`` syntax. Check ``status()`` afterwards for more information about the success of the run or just check the coroutine object in an ifs tatement, as shown :ref:`above<runnable>`.
Copy file name to clipboardExpand all lines: docs/source/threading.rst
+4-2Lines changed: 4 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,9 +5,9 @@ Lua has no thread safety. sol does not force thread safety bottlenecks anywhere.
5
5
6
6
Assume any access or any call on Lua affects the whole ``sol::state``/``lua_State*`` (because it does, in a fair bit of cases). Therefore, every call to a state should be blocked off in C++ with some kind of access control (when you're working with multiple C++ threads). When you start hitting the same state from multiple threads, race conditions (data or instruction) can happen.
7
7
8
-
Individual Lua coroutines might be able to run on separate C++-created threads without tanking the state utterly, since each Lua coroutine has the capability to run on an independent Lua execution stack (Lua confusingly calls it a ``thread`` in the C API, but it really just means a separate execution stack) as well as some other associated bits and pieces that won't quite interfere with the global state.
8
+
To handle multithreaded environments, it is encouraged to either spawn a Lua state (``sol::state``) for each thread you are working with and keep inter-state communication to synchronized serialization points. This means that 3 C++ threads should have 3 Lua states, and access between them should be controlled using some kind of synchronized C++ mechanism (actual transfer between states must be done by serializing the value into C++ and then re-pushing it into the other state).
9
9
10
-
To handle multithreaded environments, it is encouraged to either spawn a Lua state (``sol::state``) for each thread you are working with and keep inter-state communication to synchronized serialization points. This means that 3 C++ threads should each have their own Lua state, and access between them should be controlled using some kind of synchronized C++ mechanism (actual transfer between states must be done by serializing the value into C++ and then re-pushing it into the other state).
10
+
`Here is an example of a processor that explicitly serializes`_ Lua returns into C++ values, and Lua functions into state-transferrable byte code to do work.
11
11
12
12
Using coroutines and Lua's threads might also buy you some concurrency and parallelism (**unconfirmed and likely untrue, do not gamble on this**), but remember that Lua's 'threading' technique is ultimately cooperative and requires explicit yielding and resuming (simplified as function calls for :doc:`sol::coroutine<api/coroutine>`).
13
13
@@ -37,3 +37,5 @@ Here's an example of explicit state transferring below:
0 commit comments