docs: Expand introduction to mention using async calls over sync ones
authorPhilip Withnall <philip.withnall@collabora.co.uk>
Wed, 18 Feb 2015 17:01:18 +0000 (17:01 +0000)
committerPhilip Withnall <philip.withnall@collabora.co.uk>
Tue, 3 Mar 2015 18:27:45 +0000 (18:27 +0000)
As discussed on the mailing list (see the whole thread):
    https://mail.gnome.org/archives/desktop-devel-list/2015-February/msg00126.html

Expand the GIO documentation introduction to talk a little about when to
use async and sync functions, and how the former should almost always be
preferred over the latter.

Link to this from the GFile documentation, which is an entry point for a
lot of async calls.

https://bugzilla.gnome.org/show_bug.cgi?id=744722

docs/reference/gio/overview.xml
gio/gfile.c

index 46b49ca..78cc08c 100644 (file)
 
     </simplesect>
 
+    <simplesect id="async-programming"><title>Asynchronous Programming</title>
+
+    <para>
+      Many GIO functions come in two versions: synchronous and asynchronous,
+      denoted by an <code>_async</code> suffix. It is important to use these
+      appropriately: synchronous calls should not be used from
+      within a main loop which is shared with other code, such as one in the
+      application’s main thread. Synchronous calls block until they complete,
+      and I/O operations can take noticeable amounts of time (even on ‘fast’
+      SSDs). Blocking a main loop iteration while waiting for I/O means that
+      other sources in the main loop will not be dispatched, such as input and
+      redraw handlers for the application’s UI. This can cause the application
+      to ‘freeze’ until I/O completes.
+    </para>
+
+    <para>
+      A few self-contained groups of functions, such as code generated by
+      <link linkend="gdbus-codegen"><application>gdbus-codegen</application></link>,
+      use a different convention: functions are asynchronous default, and it is
+      the <emphasis>synchronous</emphasis> version which has a
+      <code>_sync</code>
+      suffix. Aside from naming differences, they should be treated the same
+      way as functions following the normal convention above.
+    </para>
+
+    <para>
+      The asynchronous (<code>_async</code>) versions of functions return
+      control to the caller immediately, after scheduling the I/O in the kernel
+      and adding a callback for it to the main loop. This callback will be
+      invoked when the operation has completed. From the callback, the paired
+      <code>_finish</code> function should be called to retrieve the return
+      value of the I/O operation, and any errors which occurred. For more
+      information on using and implementing asynchronous functions, see
+      <link linkend="GAsyncResult.description"><type>GAsyncResult</type></link>
+      and <link linkend="GTask.description"><type>GTask</type></link>.
+    </para>
+
+    <para>
+      By starting multiple asynchronous operations in succession, they will be
+      executed in parallel (up to an arbitrary limit imposed by GIO’s internal
+      worker thread pool).
+    </para>
+
+    <para>
+      The synchronous versions of functions can be used early in application
+      startup when there is no main loop to block, for example to load initial
+      configuration files. They can also be used for I/O on files which are
+      guaranteed to be small and on the local disk. Note that the user’s home
+      directory is not guaranteed to be on the local disk.
+    </para>
+    </simplesect>
+
     <simplesect><title>Security</title>
 
 <para>
index 22f7423..8925215 100644 (file)
  * the operation, producing a GAsyncResult which is then passed to the
  * function's matching _finish() operation.
  *
- * Some #GFile operations do not have synchronous analogs, as they may
- * take a very long time to finish, and blocking may leave an application
- * unusable. Notable cases include:
+ * It is highly recommended to use asynchronous calls when running within a
+ * shared main loop, such as in the main thread of an application. This avoids
+ * I/O operations blocking other sources on the main loop from being dispatched.
+ * Synchronous I/O operations should be performed from worker threads. See the
+ * [introduction to asynchronous programming section][async-programming] for
+ * more.
+ *
+ * Some #GFile operations almost always take a noticeable amount of time, and
+ * so do not have synchronous analogs. Notable cases include:
  * - g_file_mount_mountable() to mount a mountable file.
  * - g_file_unmount_mountable_with_operation() to unmount a mountable file.
  * - g_file_eject_mountable_with_operation() to eject a mountable file.