1<page xmlns="http://projectmallard.org/1.0/" 2 xmlns:its="http://www.w3.org/2005/11/its" 3 xmlns:xi="http://www.w3.org/2003/XInclude" 4 type="guide" style="task" 5 id="custom-gsource.c"> 6 7 <info> 8 <link type="guide" xref="c#examples"/> 9 10 <credit type="author copyright"> 11 <name>Philip Withnall</name> 12 <email its:translate="no">philip.withnall@collabora.co.uk</email> 13 <years>2015</years> 14 </credit> 15 16 <include href="legal.xml" xmlns="http://www.w3.org/2001/XInclude"/> 17 18 <desc> 19 Tutorial for writing a custom <code>GSource</code> implementation 20 </desc> 21 </info> 22 23 <title>Custom GSources</title> 24 25 <synopsis> 26 <title>Summary</title> 27 28 <p> 29 This article is a tutorial on creating a custom <code>GSource</code>. For 30 the reference documentation, see the 31 <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#GSource">GLib 32 API reference</link>. 33 </p> 34 </synopsis> 35 36 <section id="what-is-gsource"> 37 <title>What is <code>GSource</code>?</title> 38 39 <p> 40 A <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#GSource"><code>GSource</code></link> 41 is an expected event with an associated callback function which will be 42 invoked when that event is received. An event could be a timeout or data 43 being received on a socket, for example. 44 </p> 45 46 <p> 47 GLib contains various types of <code>GSource</code>, but also allows 48 applications to define their own, allowing custom events to be integrated 49 into the main loop. 50 </p> 51 52 <p> 53 The structure of a <code>GSource</code> and its virtual functions are 54 documented in detail in the 55 <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#GSourceFuncs">GLib 56 API reference</link>. 57 </p> 58 </section> 59 60 <section id="queue-source"> 61 <title>A Message Queue Source</title> 62 63 <p> 64 As a running example, a message queue source will be used which dispatches 65 its callback whenever a message is enqueued to a queue internal to the 66 source (potentially from another thread). 67 </p> 68 69 <p> 70 This type of source is useful for efficiently transferring large numbers 71 of messages between main contexts. The alternative is transferring each 72 message as a separate idle <code>GSource</code> using 73 <code>g_source_attach()</code>. For large numbers of messages, this means 74 a lot of allocations and frees of <code>GSource</code>s. 75 </p> 76 77 <section id="gsource-structure"> 78 <title>Structure</title> 79 80 <p> 81 Firstly, a structure for the source needs to be declared. This must 82 contain a <code>GSource</code> as its parent, followed by the private 83 fields for the source: the queue and a function to call to free each 84 message once finished with. 85 </p> 86 <code mime="text/x-csrc"> 87typedef struct { 88 GSource parent; 89 GAsyncQueue *queue; /* owned */ 90 GDestroyNotify destroy_message; 91} MessageQueueSource;</code> 92 </section> 93 94 <section id="prepare-function"> 95 <title>Prepare Function</title> 96 97 <p> 98 Next, the prepare function for the source must be defined. This determines 99 whether the source is ready to be dispatched. As this source is using an 100 in-memory queue, this can be determined by checking the queue’s length: if 101 there are elements in the queue, the source can be dispatched to handle 102 them. 103 </p> 104 <code mime="text/x-csrc"> 105return (g_async_queue_length (message_queue_source->queue) > 0);</code> 106 </section> 107 108 <section id="check-function"> 109 <title>Check Function</title> 110 111 <p> 112 As this source has no file descriptors, the prepare and check functions 113 essentially have the same job, so a check function is not needed. 114 Setting the field to <code>NULL</code> in <code>GSourceFuncs</code> 115 bypasses the check function for this source type. 116 </p> 117 </section> 118 119 <section id="dispatch-function"> 120 <title>Dispatch Function</title> 121 122 <p> 123 For this source, the dispatch function is where the complexity lies. It 124 needs to dequeue a message from the queue, then pass that message to the 125 <code>GSource</code>’s callback function. No messages may be queued: even 126 through the prepare function returned true, another source wrapping the 127 same queue may have been dispatched in the mean time and taken the final 128 message from the queue. Further, if no callback has been set for the 129 <code>GSource</code> (which is allowed), the message must be destroyed and 130 silently dropped. 131 </p> 132 133 <p> 134 If both a message and callback are set, the callback can be invoked on the 135 message and its return value propagated as the return value of the 136 dispatch function. This is <code>FALSE</code> to destroy the 137 <code>GSource</code> and <code>TRUE</code> to keep it alive, just as for 138 <code>GSourceFunc</code> — these semantics are the same for all dispatch 139 function implementations. 140 </p> 141 <code mime="text/x-csrc"> 142/* Pop a message off the queue. */ 143message = g_async_queue_try_pop (message_queue_source->queue); 144 145/* If there was no message, bail. */ 146if (message == NULL) 147 { 148 /* Keep the source around to handle the next message. */ 149 return TRUE; 150 } 151 152/* @func may be %NULL if no callback was specified. 153 * If so, drop the message. */ 154if (func == NULL) 155 { 156 if (message_queue_source->destroy_message != NULL) 157 { 158 message_queue_source->destroy_message (message); 159 } 160 161 /* Keep the source around to consume the next message. */ 162 return TRUE; 163 } 164 165return func (message, user_data);</code> 166 </section> 167 168 <section id="callback"> 169 <title>Callback Functions</title> 170 171 <p> 172 The callback from a <code>GSource</code> does not have to have type 173 <code>GSourceFunc</code>. It can be whatever function type is called in 174 the source’s dispatch function, as long as that type is sufficiently 175 documented. 176 </p> 177 178 <p> 179 Normally, <code>g_source_set_callback()</code> is used to set the 180 callback function for a source instance. With its 181 <code>GDestroyNotify</code>, a strong reference can be held to keep an 182 object alive while the source is still alive: 183 </p> 184 <code mime="text/x-csrc"> 185g_source_set_callback (source, callback_func, 186 g_object_ref (object_to_strong_ref), 187 (GDestroyNotify) g_object_unref);</code> 188 189 <p> 190 However, <code>GSource</code> has a layer of indirection for retrieving 191 this callback, exposed as <code>g_source_set_callback_indirect()</code>. 192 This allows GObject to set a <code>GClosure</code> as the callback for a 193 source, which allows for sources which are automatically destroyed when 194 an object is finalized — a <em>weak</em> reference, in contrast to the 195 <em>strong</em> reference above: 196 </p> 197 <code mime="text/x-csrc"> 198g_source_set_closure (source, 199 g_cclosure_new_object (callback_func, 200 object_to_weak_ref));</code> 201 202 <p> 203 It also allows for a generic, closure-based ‘dummy’ callback, which can 204 be used when a source needs to exist but no action needs to be performed 205 in its callback: 206 </p> 207 <code mime="text/x-csrc"> 208g_source_set_dummy_callback (source);</code> 209 </section> 210 211 <section id="constructor"> 212 <title>Constructor</title> 213 214 <p> 215 Finally, the <code>GSourceFuncs</code> definition of the 216 <code>GSource</code> can be written, alongside a construction function. 217 It is typical practice to expose new source types simply as 218 <code>GSource</code>s, not as the subtype structure; so the constructor 219 returns a <code>GSource*</code>. 220 </p> 221 222 <p> 223 The example constructor here also demonstrates use of a child source to 224 support cancellation conveniently. If the <code>GCancellable</code> is 225 cancelled, the application’s callback will be dispatched and can check 226 for cancellation. (The application code will need to make a pointer to 227 the <code>GCancellable</code> available to its callback, as a field of the 228 callback’s user data set in <code>g_source_set_callback()</code>). 229 </p> 230 <code mime="text/x-csrc"> 231GSource * 232message_queue_source_new (GAsyncQueue *queue, 233 GDestroyNotify destroy_message, 234 GCancellable *cancellable) 235{ 236 GSource *source; /* alias of @message_queue_source */ 237 MessageQueueSource *message_queue_source; /* alias of @source */ 238 239 g_return_val_if_fail (queue != NULL, NULL); 240 g_return_val_if_fail (cancellable == NULL || 241 G_IS_CANCELLABLE (cancellable), NULL); 242 243 source = g_source_new (&message_queue_source_funcs, 244 sizeof (MessageQueueSource)); 245 message_queue_source = (MessageQueueSource *) source; 246 247 /* The caller can overwrite this name with something more useful later. */ 248 g_source_set_name (source, "MessageQueueSource"); 249 250 message_queue_source->queue = g_async_queue_ref (queue); 251 message_queue_source->destroy_message = destroy_message; 252 253 /* Add a cancellable source. */ 254 if (cancellable != NULL) 255 { 256 GSource *cancellable_source; 257 258 cancellable_source = g_cancellable_source_new (cancellable); 259 g_source_set_dummy_callback (cancellable_source); 260 g_source_add_child_source (source, cancellable_source); 261 g_source_unref (cancellable_source); 262 } 263 264 return source; 265}</code> 266 </section> 267 </section> 268 269 <section id="full-listing"> 270 <title>Complete Example</title> 271 272 <listing> 273 <title>Complete Example Code</title> 274 275 <code mime="text/x-csrc"><include xmlns="http://www.w3.org/2001/XInclude" 276 href="samples/example-custom-gsource.c" 277 parse="text"/></code> 278 </listing> 279 </section> 280 281 <section id="further-examples"> 282 <title>Further Examples</title> 283 284 <p> 285 Sources can be more complex than the example given above. In 286 <link href="http://nice.freedesktop.org/">libnice</link>, a custom 287 <code>GSource</code> is needed to poll a set of sockets which changes 288 dynamically. The implementation is given as <code>ComponentSource</code> 289 in <link href="http://cgit.freedesktop.org/libnice/libnice/tree/agent/component.c#n941">component.c</link> 290 and demonstrates a more complex use of the prepare function. 291 </p> 292 293 <p> 294 Another example is a custom source to interface GnuTLS with GLib in its 295 <code>GTlsConnection</code> implementation. 296 <link href="https://gitlab.gnome.org/GNOME/glib-networking/blob/master/tls/gnutls/gtlsconnection-gnutls.c#L1154"><code>GTlsConnectionGnutlsSource</code></link> 297 synchronizes the main thread and a TLS worker thread which performs the 298 blocking TLS operations. 299 </p> 300 </section> 301</page> 302