1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 2<html> 3<head> 4<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 5<title>Thread-Safety</title> 6<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css"> 7<meta name="generator" content="DocBook XSL Stylesheets V1.79.1"> 8<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset"> 9<link rel="up" href="../signals2.html" title="Chapter 35. Boost.Signals2"> 10<link rel="prev" href="../boost/signals2/trackable.html" title="Class trackable"> 11<link rel="next" href="faq.html" title="Frequently Asked Questions"> 12</head> 13<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> 14<table cellpadding="2" width="100%"><tr> 15<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td> 16<td align="center"><a href="../../../index.html">Home</a></td> 17<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td> 18<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> 19<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> 20<td align="center"><a href="../../../more/index.htm">More</a></td> 21</tr></table> 22<hr> 23<div class="spirit-nav"> 24<a accesskey="p" href="../boost/signals2/trackable.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../signals2.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="faq.html"><img src="../../../doc/src/images/next.png" alt="Next"></a> 25</div> 26<div class="section"> 27<div class="titlepage"><div><div><h2 class="title" style="clear: both"> 28<a name="signals2.thread-safety"></a>Thread-Safety</h2></div></div></div> 29<div class="toc"><dl class="toc"> 30<dt><span class="section"><a href="thread-safety.html#id-1.3.36.7.2">Introduction</a></span></dt> 31<dt><span class="section"><a href="thread-safety.html#id-1.3.36.7.3">Signals and combiners</a></span></dt> 32<dt><span class="section"><a href="thread-safety.html#id-1.3.36.7.4">Connections and other classes</a></span></dt> 33</dl></div> 34<div class="section"> 35<div class="titlepage"><div><div><h3 class="title"> 36<a name="id-1.3.36.7.2"></a>Introduction</h3></div></div></div> 37<p> 38 The primary motivation for Boost.Signals2 is to provide a version of 39 the original Boost.Signals library which can be used safely in a 40 multi-threaded environment. 41 This is achieved primarily through two changes from the original Boost.Signals 42 API. One is the introduction of a new automatic connection management scheme 43 relying on <code class="computeroutput">shared_ptr</code> and <code class="computeroutput">weak_ptr</code>, 44 as described in the <a class="link" href="tutorial.html#signals2.tutorial.connection-management" title="Automatic Connection Management (Intermediate)">tutorial</a>. 45 The second change was the introduction of a <code class="computeroutput">Mutex</code> template type 46 parameter to the <code class="computeroutput"><a class="link" href="../boost/signals2/signal.html" title="Class template signal">signal</a></code> class. This section details how 47 the library employs these changes to provide thread-safety, and 48 the limits of the provided thread-safety. 49 </p> 50</div> 51<div class="section"> 52<div class="titlepage"><div><div><h3 class="title"> 53<a name="id-1.3.36.7.3"></a>Signals and combiners</h3></div></div></div> 54<p> 55 Each signal object default-constructs a <code class="computeroutput">Mutex</code> object to protect 56 its internal state. Furthermore, a <code class="computeroutput">Mutex</code> is created 57 each time a new slot is connected to the signal, to protect the 58 associated signal-slot connection. 59 </p> 60<p> 61 A signal's mutex is automatically locked whenever any of the 62 signal's methods are called. The mutex is usually held until the 63 method completes, however there is one major exception to this rule. When 64 a signal is invoked by calling 65 <code class="computeroutput"><a class="link" href="../boost/signals2/signal.html#id-1_3_36_6_9_3_1_2_25_1-bb">signal::operator()</a></code>, 66 the invocation first acquires a lock on the signal's mutex. Then 67 it obtains a handle to the signal's slot list and combiner. Next 68 it releases the signal's mutex, before invoking the combiner to 69 iterate through the slot list. Thus no mutexes are held by the 70 signal while a slot is executing. This design choice 71 makes it impossible for user code running in a slot 72 to deadlock against any of the 73 mutexes used internally by the Boost.Signals2 library. 74 It also prevents slots from accidentally causing 75 recursive locking attempts on any of the library's internal mutexes. 76 Therefore, if you invoke a signal concurrently from multiple threads, 77 it is possible for the signal's combiner to be invoked concurrently 78 and thus the slots to execute concurrently. 79 </p> 80<p> 81 During a combiner invocation, the following steps are performed in order to 82 find the next callable slot while iterating through the signal's 83 slot list. 84 </p> 85<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 86<li class="listitem"><p>The <code class="computeroutput">Mutex</code> associated with the connection to the 87 slot is locked.</p></li> 88<li class="listitem"><p>All the tracked <code class="computeroutput">weak_ptr</code> associated with the 89 slot are copied into temporary <code class="computeroutput">shared_ptr</code> which 90 will be kept alive until the invocation is done with the slot. If this fails due 91 to any of the 92 <code class="computeroutput">weak_ptr</code> being expired, the connection is 93 automatically disconnected. Therefore a slot will never be run 94 if any of its tracked <code class="computeroutput">weak_ptr</code> have expired, 95 and none of its tracked <code class="computeroutput">weak_ptr</code> will 96 expire while the slot is running. 97 </p></li> 98<li class="listitem"><p> 99 The slot's connection is checked to see if it is blocked 100 or disconnected, and then the connection's mutex is unlocked. If the connection 101 was either blocked or disconnected, we 102 start again from the beginning with the next slot in the slot list. 103 Otherwise, we commit to executing the slot when the combiner next 104 dereferences the slot call iterator (unless the combiner should increment 105 the iterator without ever dereferencing it). 106 </p></li> 107</ul></div> 108<p> 109 Note that since we unlock the connection's mutex before executing 110 its associated slot, it is possible a slot will still be executing 111 after it has been disconnected by a 112 <code class="computeroutput"><a class="link" href="../boost/signals2/connection.html#id-1_3_36_6_2_1_1_1_8_1-bb">connection::disconnect</a>()</code>, if 113 the disconnect was called concurrently with signal invocation. 114 </p> 115<p> 116 You may have noticed above that during signal invocation, the invocation only 117 obtains handles to the signal's slot list and combiner while holding the 118 signal's mutex. Thus concurrent signal invocations may still wind up 119 accessing the 120 same slot list and combiner concurrently. So what happens if the slot list is modified, 121 for example by connecting a new slot, while a signal 122 invocation is in progress concurrently? If the slot list is already in use, 123 the signal performs a deep copy of the slot list before modifying it. 124 Thus the a concurrent signal invocation will continue to use the old unmodified slot list, 125 undisturbed by modifications made to the newly created deep copy of the slot list. 126 Future signal invocations will receive a handle to the newly created deep 127 copy of the slot list, and the old slot list will be destroyed once it 128 is no longer in use. Similarly, if you change a signal's combiner with 129 <code class="computeroutput"><a class="link" href="../boost/signals2/signal.html#id-1_3_36_6_9_3_1_2_26_2-bb">signal::set_combiner</a></code> 130 while a signal invocation is running concurrently, the concurrent 131 signal invocation will continue to use the old combiner undisturbed, 132 while future signal invocations will receive a handle to the new combiner. 133 </p> 134<p> 135 The fact that concurrent signal invocations use the same combiner object 136 means you need to insure any custom combiner you write is thread-safe. 137 So if your combiner maintains state which is modified when the combiner 138 is invoked, you 139 may need to protect that state with a mutex. Be aware, if you hold 140 a mutex in your combiner while dereferencing slot call iterators, 141 you run the risk of deadlocks and recursive locking if any of 142 the slots cause additional mutex locking to occur. One way to avoid 143 these perils is for your combiner to release any locks before 144 dereferencing a slot call iterator. The combiner classes provided by 145 the Boost.Signals2 library are all thread-safe, since they do not maintain 146 any state across invocations. 147 </p> 148<p> 149 Suppose a user writes a slot which connects another slot to the invoking signal. 150 Will the newly connected slot be run during the same signal invocation in 151 which the new connection was made? The answer is no. Connecting a new slot 152 modifies the signal's slot list, and as explained above, a signal invocation 153 already in progress will not see any modifications made to the slot list. 154 </p> 155<p> 156 Suppose a user writes a slot which disconnects another slot from the invoking signal. 157 Will the disconnected slot be prevented from running during the same signal invocation, 158 if it appears later in the slot list than the slot which disconnected it? 159 This time the answer is yes. Even if the disconnected slot is still 160 present in the signal's slot list, each slot is checked to see if it is 161 disconnected or blocked immediately before it is executed (or not executed as 162 the case may be), as was described in more detail above. 163 </p> 164</div> 165<div class="section"> 166<div class="titlepage"><div><div><h3 class="title"> 167<a name="id-1.3.36.7.4"></a>Connections and other classes</h3></div></div></div> 168<p> 169 The methods of the <code class="computeroutput"><a class="link" href="../boost/signals2/connection.html" title="Class connection">signals2::connection</a></code> class are thread-safe, 170 with the exception of assignment and swap. This is achived via locking the mutex 171 associated with the object's underlying signal-slot connection. Assignment and 172 swap are not thread-safe because the mutex protects the underlying connection 173 which a <code class="computeroutput"><a class="link" href="../boost/signals2/connection.html" title="Class connection">signals2::connection</a></code> object references, not 174 the <code class="computeroutput"><a class="link" href="../boost/signals2/connection.html" title="Class connection">signals2::connection</a></code> object itself. That is, 175 there may be many copies of a <code class="computeroutput"><a class="link" href="../boost/signals2/connection.html" title="Class connection">signals2::connection</a></code> object, 176 all of which reference the same underlying connection. There is not a mutex 177 for each <code class="computeroutput"><a class="link" href="../boost/signals2/connection.html" title="Class connection">signals2::connection</a></code> object, there is only 178 a single mutex protecting the underlying connection they reference. 179 </p> 180<p>The <code class="computeroutput"><a class="link" href="../boost/signals2/shared_connection_block.html" title="Class shared_connection_block">shared_connection_block</a></code> class obtains some thread-safety 181 from the <code class="computeroutput">Mutex</code> protecting the underlying connection which is blocked 182 and unblocked. The internal reference counting which is used to keep track of 183 how many <code class="computeroutput"><a class="link" href="../boost/signals2/shared_connection_block.html" title="Class shared_connection_block">shared_connection_block</a></code> objects are asserting 184 blocks on their underlying connection is also thread-safe (the implementation 185 relies on <code class="computeroutput">shared_ptr</code> for the reference counting). 186 However, individual <code class="computeroutput"><a class="link" href="../boost/signals2/shared_connection_block.html" title="Class shared_connection_block">shared_connection_block</a></code> objects 187 should not be accessed concurrently by multiple threads. As long as two 188 threads each have their own <code class="computeroutput"><a class="link" href="../boost/signals2/shared_connection_block.html" title="Class shared_connection_block">shared_connection_block</a></code> object, 189 then they may use them in safety, even if both <code class="computeroutput"><a class="link" href="../boost/signals2/shared_connection_block.html" title="Class shared_connection_block">shared_connection_block</a></code> 190 objects are copies and refer to the same underlying connection. 191 </p> 192<p> 193 The <code class="computeroutput"><a class="link" href="../boost/signals2/slot.html" title="Class template slot">signals2::slot</a></code> class has no internal mutex locking 194 built into it. It is expected that slot objects will be created then 195 connected to a signal in a single thread. Once they have been copied into 196 a signal's slot list, they are protected by the mutex associated with 197 each signal-slot connection. 198 </p> 199<p>The <code class="computeroutput"><a class="link" href="../boost/signals2/trackable.html" title="Class trackable">signals2::trackable</a></code> class does NOT provide 200 thread-safe automatic connection management. In particular, it leaves open the 201 possibility of a signal invocation calling into a partially destructed object 202 if the trackable-derived object is destroyed in a different thread from the 203 one invoking the signal. 204 <code class="computeroutput"><a class="link" href="../boost/signals2/trackable.html" title="Class trackable">signals2::trackable</a></code> is only provided as a convenience 205 for porting single-threaded code from Boost.Signals to Boost.Signals2. 206 </p> 207</div> 208</div> 209<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 210<td align="left"><p><small>Last revised: June 12, 2007 at 14:01:23 -0400</small></p></td> 211<td align="right"><div class="copyright-footer">Copyright © 2001-2004 Douglas Gregor<br>Copyright © 2007-2009 Frank Mori Hess<p>Distributed under the Boost 212 Software License, Version 1.0. (See accompanying file 213 <code class="filename">LICENSE_1_0.txt</code> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)</p> 214</div></td> 215</tr></table> 216<hr> 217<div class="spirit-nav"> 218<a accesskey="p" href="../boost/signals2/trackable.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../signals2.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="faq.html"><img src="../../../doc/src/images/next.png" alt="Next"></a> 219</div> 220</body> 221</html> 222