1 {{+bindTo:partials.standard_nacl_article}}
2 <h1>PPB_MessageLoop Struct Reference</h1>
4 <!-- Generated by Doxygen 1.7.6.1 -->
10 <!-- doxytag: class="PPB_MessageLoop" --><h2>
11 Data Fields</h2><table class="memberdecls">
13 <tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___message_loop__1__0.html#a2bbe000366ee68200cb97d956b9e33ef">Create</a> )(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td></tr>
14 <tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___message_loop__1__0.html#ab3ac0fdbe4c56d687bcf316552f0a6f6">GetForMainThread</a> )(void)</td></tr>
15 <tr><td class="memItemLeft" align="right" valign="top"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___message_loop__1__0.html#a8049f2ad6395195a673d801b1eeb65df">GetCurrent</a> )(void)</td></tr>
16 <tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___message_loop__1__0.html#ad7e1c1fb0baf6a0446ffb241a6b226b9">AttachToCurrentThread</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> message_loop)</td></tr>
17 <tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___message_loop__1__0.html#a2262dd5022845450f77b3601578cc22d">Run</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> message_loop)</td></tr>
18 <tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___message_loop__1__0.html#a77b0e82e183d5295b0d765f70c4fe7ff">PostWork</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> message_loop, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback, int64_t delay_ms)</td></tr>
19 <tr><td class="memItemLeft" align="right" valign="top">int32_t(* </td><td class="memItemRight" valign="bottom"><a class="el" href="struct_p_p_b___message_loop__1__0.html#adbbdc03661c9ac41df82fffcc566603d">PostQuit</a> )(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> message_loop, <a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a> should_destroy)</td></tr>
21 <hr /><a name="details" id="details"></a><h2>Detailed Description</h2>
22 <div class="textblock"><p>A message loop allows PPAPI calls to be issued on a thread. </p>
23 <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>
24 <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="struct_p_p_b___message_loop__1__0.html#a2262dd5022845450f77b3601578cc22d" title="Runs the thread message loop.">Run()</a>.</p>
25 <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>
26 <p>Typical usage: On the main thread:</p>
28 <li>Create the thread yourself (using pthreads).</li>
29 <li>Create the message loop resource.</li>
30 <li>Pass the message loop resource to your thread's main function.</li>
31 <li>Call <a class="el" href="struct_p_p_b___message_loop__1__0.html#a77b0e82e183d5295b0d765f70c4fe7ff" title="Schedules work to run on the given message loop.">PostWork()</a> on the message loop to run functions on the thread.</li>
33 <p>From the background thread's main function:</p>
35 <li>Call <a class="el" href="struct_p_p_b___message_loop__1__0.html#ad7e1c1fb0baf6a0446ffb241a6b226b9" 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>
36 <li>Call <a class="el" href="struct_p_p_b___message_loop__1__0.html#a2262dd5022845450f77b3601578cc22d" title="Runs the thread message loop.">Run()</a> with the message loop resource.</li>
38 <p>Your callbacks should look like this: </p>
39 <div class="fragment"><pre class="fragment"> <span class="keywordtype">void</span> DoMyWork(<span class="keywordtype">void</span>* user_data, int32_t status) {
40 <span class="keywordflow">if</span> (status != <a class="code" href="group___enums.html#gga06fc87d81c62e9abb8790b6e5713c55ba5c394615cfa8eaceba77ecedb65dc9cb" title="This value is returned by a function on successful synchronous completion or is passed as a result to...">PP_OK</a>) {
41 Cleanup(); <span class="comment">// e.g. free user_data.</span>
42 <span class="keywordflow">return</span>;
44 ... <span class="keywordflow">do</span> your work...
46 </pre></div><p> For a C++ example, see ppapi/utility/threading/simple_thread.h</p>
47 <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="struct_p_p_b___message_loop__1__0.html#a77b0e82e183d5295b0d765f70c4fe7ff" title="Schedules work to run on the given message loop.">PostWork()</a>).</p>
48 <p>THREAD HANDLING</p>
49 <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="struct_p_p_b___message_loop__1__0.html#ab3ac0fdbe4c56d687bcf316552f0a6f6" title="Returns a resource identifying the message loop for the main thread.">GetForMainThread()</a> or, if your code is on the main thread, GetForCurrentThread() will also work.</p>
50 <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>
51 <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="struct_p_p_b___message_loop__1__0.html#a8049f2ad6395195a673d801b1eeb65df" title="Returns a reference to the PPB_MessageLoop object attached to the current thread.">GetCurrent()</a> function.</p>
52 <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>
53 <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 <a class="el" href="group___functions.html#ga340e452b4931d17bd44928769490e282" title="PP_BlockUntilComplete() is used in place of an actual completion callback to request blocking behavio...">PP_BlockUntilComplete()</a>). 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>
54 <p>DESTRUCTION AND ERROR HANDLING</p>
55 <p>Often, your application will associate memory with completion callbacks. For example, the C++ CompletionCallbackFactory 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>
56 <p>There are a number of cases where posted callbacks will never be run:</p>
58 <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>
61 <li>You create a message loop, post callbacks to it, and never run it.</li>
64 <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>
66 <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>
67 <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>
68 <p>Therefore, you should check for errors from PostWork and destroy any associated memory to avoid leaks. If you're using the C++ CompletionCallbackFactory, use the following pattern: </p>
69 <div class="fragment"><pre class="fragment"> pp::CompletionCallback callback = factory_.NewOptionalCallback(...);
70 int32_t result = message_loop.PostWork(callback);
71 <span class="keywordflow">if</span> (result != <a class="code" href="group___enums.html#gga06fc87d81c62e9abb8790b6e5713c55ba5c394615cfa8eaceba77ecedb65dc9cb" title="This value is returned by a function on successful synchronous completion or is passed as a result to...">PP_OK</a>)
73 </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>
74 </div><hr /><h2>Field Documentation</h2>
75 <a class="anchor" id="ad7e1c1fb0baf6a0446ffb241a6b226b9"></a><!-- doxytag: member="PPB_MessageLoop::AttachToCurrentThread" ref="ad7e1c1fb0baf6a0446ffb241a6b226b9" args=")(PP_Resource message_loop)" -->
77 <div class="memproto">
78 <table class="memname">
80 <td class="memname">int32_t(* <a class="el" href="struct_p_p_b___message_loop__1__0.html#ad7e1c1fb0baf6a0446ffb241a6b226b9">PPB_MessageLoop::AttachToCurrentThread</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> message_loop)</td>
85 <p>Sets the given message loop resource as being the associated message loop for the currently running thread. </p>
86 <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>
87 <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>
88 <dl class="return"><dt><b>Returns:</b></dt><dd><ul>
89 <li>PP_OK: The message loop was successfully attached to the thread and is ready to use.</li>
90 <li>PP_ERROR_BADRESOURCE: The given message loop resource is invalid.</li>
91 <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>
92 <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>
97 <a class="anchor" id="a2bbe000366ee68200cb97d956b9e33ef"></a><!-- doxytag: member="PPB_MessageLoop::Create" ref="a2bbe000366ee68200cb97d956b9e33ef" args=")(PP_Instance instance)" -->
99 <div class="memproto">
100 <table class="memname">
102 <td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___message_loop__1__0.html#a2bbe000366ee68200cb97d956b9e33ef">PPB_MessageLoop::Create</a>)(<a class="el" href="group___typedefs.html#ga89b662403e6a687bb914b80114c0d19d">PP_Instance</a> instance)</td>
107 <p>Creates a message loop resource. </p>
108 <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>
111 <a class="anchor" id="a8049f2ad6395195a673d801b1eeb65df"></a><!-- doxytag: member="PPB_MessageLoop::GetCurrent" ref="a8049f2ad6395195a673d801b1eeb65df" args=")(void)" -->
112 <div class="memitem">
113 <div class="memproto">
114 <table class="memname">
116 <td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___message_loop__1__0.html#a8049f2ad6395195a673d801b1eeb65df">PPB_MessageLoop::GetCurrent</a>)(void)</td>
121 <p>Returns a reference to the PPB_MessageLoop object attached to the current thread. </p>
122 <p>If there is no attached message loop, the return value will be 0. </p>
125 <a class="anchor" id="ab3ac0fdbe4c56d687bcf316552f0a6f6"></a><!-- doxytag: member="PPB_MessageLoop::GetForMainThread" ref="ab3ac0fdbe4c56d687bcf316552f0a6f6" args=")(void)" -->
126 <div class="memitem">
127 <div class="memproto">
128 <table class="memname">
130 <td class="memname"><a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a>(* <a class="el" href="struct_p_p_b___message_loop__1__0.html#ab3ac0fdbe4c56d687bcf316552f0a6f6">PPB_MessageLoop::GetForMainThread</a>)(void)</td>
135 <p>Returns a resource identifying the message loop for the main thread. </p>
136 <p>The main thread always has a message loop created by the system. </p>
139 <a class="anchor" id="adbbdc03661c9ac41df82fffcc566603d"></a><!-- doxytag: member="PPB_MessageLoop::PostQuit" ref="adbbdc03661c9ac41df82fffcc566603d" args=")(PP_Resource message_loop, PP_Bool should_destroy)" -->
140 <div class="memitem">
141 <div class="memproto">
142 <table class="memname">
144 <td class="memname">int32_t(* <a class="el" href="struct_p_p_b___message_loop__1__0.html#adbbdc03661c9ac41df82fffcc566603d">PPB_MessageLoop::PostQuit</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> message_loop, <a class="el" href="group___enums.html#ga4f272d99be14aacafe08dfd4ef830918">PP_Bool</a> should_destroy)</td>
149 <p>Posts a quit message to the given message loop's work queue. </p>
150 <p>Work posted before that point will be processed before quitting.</p>
151 <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 <a class="el" href="struct_p_p_b___message_loop__1__0.html#adbbdc03661c9ac41df82fffcc566603d" title="Posts a quit message to the given message loop's work queue.">PostQuit()</a> the main thread loop.</p>
152 <dl class="params"><dt><b>Parameters:</b></dt><dd>
153 <table class="params">
154 <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>
158 <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="struct_p_p_b___message_loop__1__0.html#a2262dd5022845450f77b3601578cc22d" title="Runs the thread message loop.">Run()</a> again. If you destroy it, it will be detached from the current thread.</p>
159 <dl class="return"><dt><b>Returns:</b></dt><dd><ul>
160 <li>PP_OK: The request to quit was successfully posted.</li>
161 <li>PP_ERROR_BADRESOURCE: The message loop was invalid.</li>
162 <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>
167 <a class="anchor" id="a77b0e82e183d5295b0d765f70c4fe7ff"></a><!-- doxytag: member="PPB_MessageLoop::PostWork" ref="a77b0e82e183d5295b0d765f70c4fe7ff" args=")(PP_Resource message_loop, struct PP_CompletionCallback callback, int64_t delay_ms)" -->
168 <div class="memitem">
169 <div class="memproto">
170 <table class="memname">
172 <td class="memname">int32_t(* <a class="el" href="struct_p_p_b___message_loop__1__0.html#a77b0e82e183d5295b0d765f70c4fe7ff">PPB_MessageLoop::PostWork</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> message_loop, struct <a class="el" href="struct_p_p___completion_callback.html">PP_CompletionCallback</a> callback, int64_t delay_ms)</td>
177 <p>Schedules work to run on the given message loop. </p>
178 <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="struct_p_p_b___message_loop__1__0.html#a2262dd5022845450f77b3601578cc22d" title="Runs the thread message loop.">Run()</a>.</p>
179 <dl class="params"><dt><b>Parameters:</b></dt><dd>
180 <table class="params">
181 <tr><td class="paramname">message_loop</td><td>The message loop resource.</td></tr>
182 <tr><td class="paramname">callback</td><td>The completion callback to execute from the message loop.</td></tr>
183 <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>
187 <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>
188 <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++ CompletionCallbackFactory), you will need to free this or manually run the callback. See "Destruction and error
190 <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="struct_p_p_b___message_loop__1__0.html#a2262dd5022845450f77b3601578cc22d" title="Runs the thread message loop.">Run()</a>.</p>
191 <dl class="return"><dt><b>Returns:</b></dt><dd><ul>
192 <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>
193 <li>PP_ERROR_BADRESOURCE: The given message loop resource is invalid.</li>
194 <li>PP_ERROR_BADARGUMENT: The function pointer for the completion callback is null (this will be the case if you pass <a class="el" href="group___functions.html#ga340e452b4931d17bd44928769490e282" title="PP_BlockUntilComplete() is used in place of an actual completion callback to request blocking behavio...">PP_BlockUntilComplete()</a>).</li>
195 <li>PP_ERROR_FAILED: The message loop has been destroyed. </li>
200 <a class="anchor" id="a2262dd5022845450f77b3601578cc22d"></a><!-- doxytag: member="PPB_MessageLoop::Run" ref="a2262dd5022845450f77b3601578cc22d" args=")(PP_Resource message_loop)" -->
201 <div class="memitem">
202 <div class="memproto">
203 <table class="memname">
205 <td class="memname">int32_t(* <a class="el" href="struct_p_p_b___message_loop__1__0.html#a2262dd5022845450f77b3601578cc22d">PPB_MessageLoop::Run</a>)(<a class="el" href="group___typedefs.html#gafdc3895ee80f4750d0d95ae1b677e9b7">PP_Resource</a> message_loop)</td>
210 <p>Runs the thread message loop. </p>
211 <p>Running the message loop is required for you to get issued completion callbacks on the thread.</p>
212 <p>The message loop identified by the argument must have been previously successfully attached to the current thread.</p>
213 <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>
214 <dl class="return"><dt><b>Returns:</b></dt><dd><ul>
215 <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="struct_p_p_b___message_loop__1__0.html#adbbdc03661c9ac41df82fffcc566603d" title="Posts a quit message to the given message loop's work queue.">PostQuit()</a>.</li>
216 <li>PP_ERROR_BADRESOURCE: The given message loop resource is invalid.</li>
217 <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="struct_p_p_b___message_loop__1__0.html#ad7e1c1fb0baf6a0446ffb241a6b226b9" title="Sets the given message loop resource as being the associated message loop for the currently running t...">AttachToCurrentThread()</a>.</li>
218 <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>
223 <hr />The documentation for this struct was generated from the following file:<ul>
224 <li><a class="el" href="ppb__message__loop_8h.html">ppb_message_loop.h</a></li>
226 </div><!-- contents -->
227 {{/partials.standard_nacl_article}}