blob: 4d250a84061b2cb448cda73d6c1bc94f6f3c32bd [file] [log] [blame]
{{+bindTo:partials.standard_nacl_api}}
<h1>pp::MessageLoop Class Reference</h1>
<div id="doxygen-ref">
{{- dummy div to appease doxygen -}}
<div>
<!-- Generated by Doxygen 1.7.6.1 -->
</div>
<!--header-->
<div class="contents">
<!-- doxytag: class="pp::MessageLoop" --><!-- doxytag: inherits="pp::Resource" --><div class="dynheader">
Inheritance diagram for pp::MessageLoop:</div>
<div class="dyncontent">
<div class="center"><img src="classpp_1_1_message_loop__inherit__graph.png" border="0" usemap="#pp_1_1_message_loop_inherit__map" alt="Inheritance graph" /></div>
<map name="pp_1_1_message_loop_inherit__map" id="pp_1_1_message_loop_inherit__map">
<area shape="rect" id="node2" href="classpp_1_1_resource.html" title="A reference counted module resource." alt="" coords="20,5,124,32"></area></map>
<center><span class="legend">[<a href="graph_legend.html">legend</a>]</span></center></div>
<p><a href="classpp_1_1_message_loop-members.html">List of all members.</a></p>
<h2>
Public Member Functions</h2><table class="memberdecls">
<tr><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classpp_1_1_message_loop.html#a424cabb7ac0b27aed54a6485dd880533">MessageLoop</a> ()</td></tr>
<tr><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classpp_1_1_message_loop.html#a985004b1e2b2bb09f62cb59b320c6625">MessageLoop</a> (const <a class="el" href="classpp_1_1_instance_handle.html">InstanceHandle</a> &amp;instance)</td></tr>
<tr><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classpp_1_1_message_loop.html#ab7c519d456320eda6aa57548e9574b44">MessageLoop</a> (const <a class="el" href="classpp_1_1_message_loop.html">MessageLoop</a> &amp;other)</td></tr>
<tr><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classpp_1_1_message_loop.html#a2019e1f3f291bf4d87cdb41efea187e7">MessageLoop</a> (PP_Resource pp_message_loop)</td></tr>
<tr><td class="memItemLeft" align="right" valign="top">int32_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classpp_1_1_message_loop.html#ad5373c3f4b64dbb34d2a8334a23d0f95">AttachToCurrentThread</a> ()</td></tr>
<tr><td class="memItemLeft" align="right" valign="top">int32_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classpp_1_1_message_loop.html#ad5ac96f80c12d701acfbe558e8fb3a4c">Run</a> ()</td></tr>
<tr><td class="memItemLeft" align="right" valign="top">int32_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classpp_1_1_message_loop.html#a2c24506ef8be1745d29983b2d7803e36">PostWork</a> (const <a class="el" href="classpp_1_1_completion_callback.html">CompletionCallback</a> &amp;callback, int64_t delay_ms=0)</td></tr>
<tr><td class="memItemLeft" align="right" valign="top">int32_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classpp_1_1_message_loop.html#a2311af860834b866076fb518ac27eab5">PostQuit</a> (bool should_destroy)</td></tr>
</table><h2>
Static Public Member Functions</h2><table class="memberdecls">
<tr><td class="memItemLeft" align="right" valign="top">static <a class="el" href="classpp_1_1_message_loop.html">MessageLoop</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classpp_1_1_message_loop.html#a70558dd2cfda90b4869dc9960223f7ed">GetForMainThread</a> ()</td></tr>
<tr><td class="memItemLeft" align="right" valign="top">static <a class="el" href="classpp_1_1_message_loop.html">MessageLoop</a>&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classpp_1_1_message_loop.html#abba91f736f52838f28961a571f79f09a">GetCurrent</a> ()</td></tr>
</table>
<hr /><a name="details" id="details"></a><h2>Detailed Description</h2>
<div class="textblock"><p>A message loop allows PPAPI calls to be issued on a thread. </p>
<p>You may not issue any API calls on a thread without creating a message loop. It also allows you to post work to the message loop for a thread.</p>
<p>To process work posted to the message loop, as well as completion callbacks for asynchronous operations, you must run the message loop via <a class="el" href="classpp_1_1_message_loop.html#ad5ac96f80c12d701acfbe558e8fb3a4c" title="Runs the thread message loop.">Run()</a>.</p>
<p>Note the system manages the lifetime of the instance (and all associated resources). If the instance is deleted from the page, background threads may suddenly see their PP_Resource handles become invalid. In this case, calls will fail with PP_ERROR_BADRESOURCE. If you need to access data associated with your instance, you will probably want to create some kind of threadsafe proxy object that can handle asynchronous destruction of the instance object.</p>
<p>Typical usage: On the main thread:</p>
<ul>
<li>Create the thread yourself (using pthreads).</li>
<li>Create the message loop resource.</li>
<li>Pass the message loop resource to your thread's main function.</li>
<li>Call <a class="el" href="classpp_1_1_message_loop.html#a2c24506ef8be1745d29983b2d7803e36" title="Schedules work to run on the given message loop.">PostWork()</a> on the message loop to run functions on the thread.</li>
</ul>
<p>From the background thread's main function:</p>
<ul>
<li>Call <a class="el" href="classpp_1_1_message_loop.html#ad5373c3f4b64dbb34d2a8334a23d0f95" title="Sets the given message loop resource as being the associated message loop for the currently running t...">AttachToCurrentThread()</a> with the message loop resource.</li>
<li>Call <a class="el" href="classpp_1_1_message_loop.html#ad5ac96f80c12d701acfbe558e8fb3a4c" title="Runs the thread message loop.">Run()</a> with the message loop resource.</li>
</ul>
<p>Your callbacks should look like this: </p>
<div class="fragment"><pre class="fragment"> <span class="keywordtype">void</span> DoMyWork(<span class="keywordtype">void</span>* user_data, int32_t status) {
<span class="keywordflow">if</span> (status != PP_OK) {
Cleanup(); <span class="comment">// e.g. free user_data.</span>
<span class="keywordflow">return</span>;
}
... <span class="keywordflow">do</span> your work...
}
</pre></div><p> For a C++ example, see ppapi/utility/threading/simple_thread.h</p>
<p>(You can also create the message loop resource on the background thread, but then the main thread will have no reference to it should you want to call <a class="el" href="classpp_1_1_message_loop.html#a2c24506ef8be1745d29983b2d7803e36" title="Schedules work to run on the given message loop.">PostWork()</a>).</p>
<p>THREAD HANDLING</p>
<p>The main thread has an implicitly created message loop. The main thread is the thread where PPP_InitializeModule and PPP_Instance functions are called. You can retrieve a reference to this message loop by calling <a class="el" href="classpp_1_1_message_loop.html#a70558dd2cfda90b4869dc9960223f7ed">GetForMainThread()</a> or, if your code is on the main thread, <a class="el" href="classpp_1_1_message_loop.html#abba91f736f52838f28961a571f79f09a">GetCurrent()</a> will also work.</p>
<p>Some special threads created by the system can not have message loops. In particular, the background thread created for audio processing has this requirement because it's intended to be highly responsive to keep up with the realtime requirements of audio processing. You can not make PPAPI calls from these threads.</p>
<p>Once you associate a message loop with a thread, you don't have to keep a reference to it. The system will hold a reference to the message loop for as long as the thread is running. The current message loop can be retrieved using the <a class="el" href="classpp_1_1_message_loop.html#abba91f736f52838f28961a571f79f09a">GetCurrent()</a> function.</p>
<p>It is legal to create threads in your plugin without message loops, but PPAPI calls will fail unless explicitly noted in the documentation.</p>
<p>You can create a message loop object on a thread and never actually run the message loop. This will allow you to call blocking PPAPI calls (via PP_BlockUntilComplete()). If you make any asynchronous calls, the callbacks from those calls will be queued in the message loop and never run. The same thing will happen if work is scheduled after the message loop exits and the message loop is not run again.</p>
<p>DESTRUCTION AND ERROR HANDLING</p>
<p>Often, your application will associate memory with completion callbacks. For example, the C++ <a class="el" href="classpp_1_1_completion_callback_factory.html" title="CompletionCallbackFactory&lt;T&gt; may be used to create CompletionCallback objects that are bound to membe...">CompletionCallbackFactory</a> has a small amount of heap-allocated memory for each callback. This memory will be leaked if the callback is never run. To avoid this memory leak, you need to be careful about error handling and shutdown.</p>
<p>There are a number of cases where posted callbacks will never be run:</p>
<ul>
<li>You tear down the thread (via pthreads) without "destroying" the message loop (via PostQuit with should_destroy = PP_TRUE). In this case, any tasks in the message queue will be lost.</li>
</ul>
<ul>
<li>You create a message loop, post callbacks to it, and never run it.</li>
</ul>
<ul>
<li>You quit the message loop via PostQuit with should_destroy set to PP_FALSE. In this case, the system will assume the message loop will be run again later and keep your tasks.</li>
</ul>
<p>To do proper shutdown, call PostQuit with should_destroy = PP_TRUE. This will prohibit future work from being posted, and will allow the message loop to run until all pending tasks are run.</p>
<p>If you post a callback to a message loop that's been destroyed, or to an invalid message loop, PostWork will return an error and will not run the callback. This is true even for callbacks with the "required" flag set, since the system may not even know what thread to issue the error callback on.</p>
<p>Therefore, you should check for errors from PostWork and destroy any associated memory to avoid leaks. If you're using the C++ <a class="el" href="classpp_1_1_completion_callback_factory.html" title="CompletionCallbackFactory&lt;T&gt; may be used to create CompletionCallback objects that are bound to membe...">CompletionCallbackFactory</a>, use the following pattern: </p>
<div class="fragment"><pre class="fragment"> <a class="code" href="classpp_1_1_completion_callback.html" title="This API enables you to implement and receive callbacks when Pepper operations complete asynchronousl...">pp::CompletionCallback</a> callback = factory_.NewOptionalCallback(...);
int32_t result = message_loop.PostWork(callback);
<span class="keywordflow">if</span> (result != PP_OK)
callback.<a class="code" href="classpp_1_1_completion_callback.html#a7795404cc15a4f96523c28db21d364c4" title="Run() is used to run the CompletionCallback.">Run</a>(result);
</pre></div><p> This will run the callback with an error value, and assumes that the implementation of your callback checks the "result" argument and returns immediately on error. </p>
</div><hr /><h2>Constructor &amp; Destructor Documentation</h2>
<a class="anchor" id="a424cabb7ac0b27aed54a6485dd880533"></a><!-- doxytag: member="pp::MessageLoop::MessageLoop" ref="a424cabb7ac0b27aed54a6485dd880533" args="()" -->
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classpp_1_1_message_loop.html#a424cabb7ac0b27aed54a6485dd880533">pp::MessageLoop::MessageLoop</a> </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td></td>
</tr>
</table>
</div>
<div class="memdoc">
<p>Creates an <a class="el" href="classpp_1_1_resource.html#a859068e34cdc2dc0b78754c255323aa9" title="This functions determines if this resource is invalid or uninitialized.">is_null()</a> <a class="el" href="classpp_1_1_message_loop.html" title="A message loop allows PPAPI calls to be issued on a thread.">MessageLoop</a> resource. </p>
</div>
</div>
<a class="anchor" id="a985004b1e2b2bb09f62cb59b320c6625"></a><!-- doxytag: member="pp::MessageLoop::MessageLoop" ref="a985004b1e2b2bb09f62cb59b320c6625" args="(const InstanceHandle &amp;instance)" -->
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classpp_1_1_message_loop.html#a424cabb7ac0b27aed54a6485dd880533">pp::MessageLoop::MessageLoop</a> </td>
<td>(</td>
<td class="paramtype">const <a class="el" href="classpp_1_1_instance_handle.html">InstanceHandle</a> &amp;&#160;</td>
<td class="paramname"><em>instance</em></td><td>)</td>
<td><code> [explicit]</code></td>
</tr>
</table>
</div>
<div class="memdoc">
<p>Creates a message loop associated with the given instance. </p>
<p>The resource will be <a class="el" href="classpp_1_1_resource.html#a859068e34cdc2dc0b78754c255323aa9" title="This functions determines if this resource is invalid or uninitialized.">is_null()</a> on failure.</p>
<p>This may be called from any thread. After your thread starts but before issuing any other PPAPI calls on it, you must associate it with a message loop by calling AttachToCurrentThread. </p>
</div>
</div>
<a class="anchor" id="ab7c519d456320eda6aa57548e9574b44"></a><!-- doxytag: member="pp::MessageLoop::MessageLoop" ref="ab7c519d456320eda6aa57548e9574b44" args="(const MessageLoop &amp;other)" -->
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classpp_1_1_message_loop.html#a424cabb7ac0b27aed54a6485dd880533">pp::MessageLoop::MessageLoop</a> </td>
<td>(</td>
<td class="paramtype">const <a class="el" href="classpp_1_1_message_loop.html">MessageLoop</a> &amp;&#160;</td>
<td class="paramname"><em>other</em></td><td>)</td>
<td></td>
</tr>
</table>
</div>
<div class="memdoc">
</div>
</div>
<a class="anchor" id="a2019e1f3f291bf4d87cdb41efea187e7"></a><!-- doxytag: member="pp::MessageLoop::MessageLoop" ref="a2019e1f3f291bf4d87cdb41efea187e7" args="(PP_Resource pp_message_loop)" -->
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname"><a class="el" href="classpp_1_1_message_loop.html#a424cabb7ac0b27aed54a6485dd880533">pp::MessageLoop::MessageLoop</a> </td>
<td>(</td>
<td class="paramtype">PP_Resource&#160;</td>
<td class="paramname"><em>pp_message_loop</em></td><td>)</td>
<td><code> [explicit]</code></td>
</tr>
</table>
</div>
<div class="memdoc">
<p>Takes an additional ref to the resource. </p>
</div>
</div>
<hr /><h2>Member Function Documentation</h2>
<a class="anchor" id="ad5373c3f4b64dbb34d2a8334a23d0f95"></a><!-- doxytag: member="pp::MessageLoop::AttachToCurrentThread" ref="ad5373c3f4b64dbb34d2a8334a23d0f95" args="()" -->
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">int32_t <a class="el" href="classpp_1_1_message_loop.html#ad5373c3f4b64dbb34d2a8334a23d0f95">pp::MessageLoop::AttachToCurrentThread</a> </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td></td>
</tr>
</table>
</div>
<div class="memdoc">
<p>Sets the given message loop resource as being the associated message loop for the currently running thread. </p>
<p>You must call this function exactly once on a thread before making any PPAPI calls. A message loop can only be attached to one thread, and the message loop can not be changed later. The message loop will be attached as long as the thread is running or until you quit with should_destroy set to PP_TRUE.</p>
<p>If this function fails, attempting to run the message loop will fail. Note that you can still post work to the message loop: it will get queued up should the message loop eventually be successfully attached and run.</p>
<dl class="return"><dt><b>Returns:</b></dt><dd><ul>
<li>PP_OK: The message loop was successfully attached to the thread and is ready to use.</li>
<li>PP_ERROR_BADRESOURCE: The given message loop resource is invalid.</li>
<li>PP_ERROR_INPROGRESS: The current thread already has a message loop attached. This will always be the case for the main thread, which has an implicit system-created message loop attached.</li>
<li>PP_ERROR_WRONG_THREAD: The current thread type can not have a message loop attached to it. See the interface level discussion about these special threads, which include realtime audio threads. </li>
</ul>
</dd></dl>
</div>
</div>
<a class="anchor" id="abba91f736f52838f28961a571f79f09a"></a><!-- doxytag: member="pp::MessageLoop::GetCurrent" ref="abba91f736f52838f28961a571f79f09a" args="()" -->
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">static <a class="el" href="classpp_1_1_message_loop.html">MessageLoop</a> <a class="el" href="classpp_1_1_message_loop.html#abba91f736f52838f28961a571f79f09a">pp::MessageLoop::GetCurrent</a> </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td><code> [static]</code></td>
</tr>
</table>
</div>
<div class="memdoc">
</div>
</div>
<a class="anchor" id="a70558dd2cfda90b4869dc9960223f7ed"></a><!-- doxytag: member="pp::MessageLoop::GetForMainThread" ref="a70558dd2cfda90b4869dc9960223f7ed" args="()" -->
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">static <a class="el" href="classpp_1_1_message_loop.html">MessageLoop</a> <a class="el" href="classpp_1_1_message_loop.html#a70558dd2cfda90b4869dc9960223f7ed">pp::MessageLoop::GetForMainThread</a> </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td><code> [static]</code></td>
</tr>
</table>
</div>
<div class="memdoc">
</div>
</div>
<a class="anchor" id="a2311af860834b866076fb518ac27eab5"></a><!-- doxytag: member="pp::MessageLoop::PostQuit" ref="a2311af860834b866076fb518ac27eab5" args="(bool should_destroy)" -->
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">int32_t <a class="el" href="classpp_1_1_message_loop.html#a2311af860834b866076fb518ac27eab5">pp::MessageLoop::PostQuit</a> </td>
<td>(</td>
<td class="paramtype">bool&#160;</td>
<td class="paramname"><em>should_destroy</em></td><td>)</td>
<td></td>
</tr>
</table>
</div>
<div class="memdoc">
<p>Posts a quit message to the given message loop's work queue. </p>
<p>Work posted before that point will be processed before quitting.</p>
<p>This may be called on the message loop registered for the current thread, or it may be called on the message loop registered for another thread. It is an error to attempt to quit the main thread loop.</p>
<dl class="params"><dt><b>Parameters:</b></dt><dd>
<table class="params">
<tr><td class="paramname">should_destroy</td><td>Marks the message loop as being in a destroyed state and prevents further posting of messages.</td></tr>
</table>
</dd>
</dl>
<p>If you quit a message loop without setting should_destroy, it will still be attached to the thread and you can still run it again by calling <a class="el" href="classpp_1_1_message_loop.html#ad5ac96f80c12d701acfbe558e8fb3a4c" title="Runs the thread message loop.">Run()</a> again. If you destroy it, it will be detached from the current thread.</p>
<dl class="return"><dt><b>Returns:</b></dt><dd><ul>
<li>PP_OK: The request to quit was successfully posted.</li>
<li>PP_ERROR_BADRESOURCE: The message loop was invalid.</li>
<li>PP_ERROR_WRONG_THREAD: You are attempting to quit the main thread. The main thread's message loop is managed by the system and can't be quit. </li>
</ul>
</dd></dl>
</div>
</div>
<a class="anchor" id="a2c24506ef8be1745d29983b2d7803e36"></a><!-- doxytag: member="pp::MessageLoop::PostWork" ref="a2c24506ef8be1745d29983b2d7803e36" args="(const CompletionCallback &amp;callback, int64_t delay_ms=0)" -->
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">int32_t <a class="el" href="classpp_1_1_message_loop.html#a2c24506ef8be1745d29983b2d7803e36">pp::MessageLoop::PostWork</a> </td>
<td>(</td>
<td class="paramtype">const <a class="el" href="classpp_1_1_completion_callback.html">CompletionCallback</a> &amp;&#160;</td>
<td class="paramname"><em>callback</em>, </td>
</tr>
<tr>
<td class="paramkey"></td>
<td></td>
<td class="paramtype">int64_t&#160;</td>
<td class="paramname"><em>delay_ms</em> = <code>0</code>&#160;</td>
</tr>
<tr>
<td></td>
<td>)</td>
<td></td><td></td>
</tr>
</table>
</div>
<div class="memdoc">
<p>Schedules work to run on the given message loop. </p>
<p>This may be called from any thread. Posted work will be executed in the order it was posted when the message loop is <a class="el" href="classpp_1_1_message_loop.html#ad5ac96f80c12d701acfbe558e8fb3a4c" title="Runs the thread message loop.">Run()</a>.</p>
<dl class="params"><dt><b>Parameters:</b></dt><dd>
<table class="params">
<tr><td class="paramname">callback</td><td>A pointer to the completion callback to execute from the message loop.</td></tr>
<tr><td class="paramname">delay_ms</td><td>The number of milliseconds to delay execution of the given completion callback. Passing 0 means it will get queued normally and executed in order.</td></tr>
</table>
</dd>
</dl>
<p>The completion callback will be called with PP_OK as the "result" parameter if it is run normally. It is good practice to check for PP_OK and return early otherwise.</p>
<p>The "required" flag on the completion callback is ignored. If there is an error posting your callback, the error will be returned from PostWork and the callback will never be run (because there is no appropriate place to run your callback with an error without causing unexpected threading problems). If you associate memory with the completion callback (for example, you're using the C++ <a class="el" href="classpp_1_1_completion_callback_factory.html" title="CompletionCallbackFactory&lt;T&gt; may be used to create CompletionCallback objects that are bound to membe...">CompletionCallbackFactory</a>), you will need to free this or manually run the callback. See "Desctruction and error
handling" above.</p>
<p>You can call this function before the message loop has started and the work will get queued until the message loop is run. You can also post work after the message loop has exited as long as should_destroy was PP_FALSE. It will be queued until the next invocation of <a class="el" href="classpp_1_1_message_loop.html#ad5ac96f80c12d701acfbe558e8fb3a4c" title="Runs the thread message loop.">Run()</a>.</p>
<dl class="return"><dt><b>Returns:</b></dt><dd><ul>
<li>PP_OK: The work was posted to the message loop's queue. As described above, this does not mean that the work has been or will be executed (if you never run the message loop after posting).</li>
<li>PP_ERROR_BADRESOURCE: The given message loop resource is invalid.</li>
<li>PP_ERROR_BADARGUMENT: The function pointer for the completion callback is null (this will be the case if you pass PP_BlockUntilComplete()).</li>
<li>PP_ERROR_FAILED: The message loop has been destroyed. </li>
</ul>
</dd></dl>
</div>
</div>
<a class="anchor" id="ad5ac96f80c12d701acfbe558e8fb3a4c"></a><!-- doxytag: member="pp::MessageLoop::Run" ref="ad5ac96f80c12d701acfbe558e8fb3a4c" args="()" -->
<div class="memitem">
<div class="memproto">
<table class="memname">
<tr>
<td class="memname">int32_t <a class="el" href="classpp_1_1_message_loop.html#ad5ac96f80c12d701acfbe558e8fb3a4c">pp::MessageLoop::Run</a> </td>
<td>(</td>
<td class="paramname"></td><td>)</td>
<td></td>
</tr>
</table>
</div>
<div class="memdoc">
<p>Runs the thread message loop. </p>
<p>Running the message loop is required for you to get issued completion callbacks on the thread.</p>
<p>The message loop identified by the argument must have been previously successfully attached to the current thread.</p>
<p>You may not run nested message loops. Since the main thread has an implicit message loop that the system runs, you may not call Run on the main thread.</p>
<dl class="return"><dt><b>Returns:</b></dt><dd><ul>
<li>PP_OK: The message loop was successfully run. Note that on success, the message loop will only exit when you call <a class="el" href="classpp_1_1_message_loop.html#a2311af860834b866076fb518ac27eab5" title="Posts a quit message to the given message loop's work queue.">PostQuit()</a>.</li>
<li>PP_ERROR_BADRESOURCE: The given message loop resource is invalid.</li>
<li>PP_ERROR_WRONG_THREAD: You are attempting to run a message loop that has not been successfully attached to the current thread. Call <a class="el" href="classpp_1_1_message_loop.html#ad5373c3f4b64dbb34d2a8334a23d0f95" title="Sets the given message loop resource as being the associated message loop for the currently running t...">AttachToCurrentThread()</a>.</li>
<li>PP_ERROR_INPROGRESS: You are attempting to call Run in a nested fashion (Run is already on the stack). This will occur if you attempt to call run on the main thread's message loop (see above). </li>
</ul>
</dd></dl>
</div>
</div>
<hr />The documentation for this class was generated from the following file:<ul>
<li><a class="el" href="message__loop_8h.html">message_loop.h</a></li>
</ul>
</div><!-- contents -->
</div>
{{/partials.standard_nacl_api}}