[glib] gio: Document thread safety of the streams API



commit 3add5e2837d83b253acfd861dbf8bb980076e4f0
Author: Philip Withnall <philip withnall collabora co uk>
Date:   Fri Sep 26 14:01:16 2014 +0100

    gio: Document thread safety of the streams API
    
    Specifically, GIOStream and the TLS connection streams.
    
    Includes wording adapted from suggestions by Dan Winship
    <danw gnome org>.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=735754

 gio/ginputstream.c         |    5 ++++-
 gio/giostream.c            |   22 ++++++++++++++++++++++
 gio/goutputstream.c        |    5 ++++-
 gio/gtlsclientconnection.c |    4 ++++
 gio/gtlsconnection.c       |    9 +++++++--
 gio/gtlsserverconnection.c |    4 ++++
 6 files changed, 45 insertions(+), 4 deletions(-)
---
diff --git a/gio/ginputstream.c b/gio/ginputstream.c
index 8030256..af89492 100644
--- a/gio/ginputstream.c
+++ b/gio/ginputstream.c
@@ -40,7 +40,10 @@
  * (g_input_stream_skip()). 
  *
  * To copy the content of an input stream to an output stream without 
- * manually handling the reads and writes, use g_output_stream_splice(). 
+ * manually handling the reads and writes, use g_output_stream_splice().
+ *
+ * See the documentation for #GIOStream for details of thread safety of
+ * streaming APIs.
  *
  * All of these functions have async variants too.
  **/
diff --git a/gio/giostream.c b/gio/giostream.c
index 8ca0e4e..19522cb 100644
--- a/gio/giostream.c
+++ b/gio/giostream.c
@@ -60,6 +60,28 @@
  * #GIOStream may still be open. However, some streams may support
  * "half-closed" states where one direction of the stream is actually shut down.
  *
+ * Operations on #GIOStreams cannot be started while another operation on the
+ * #GIOStream or its substreams is in progress. Specifically, an application can
+ * read from the #GInputStream and write to the #GOutputStream simultaneously
+ * (either in separate threads, or as asynchronous operations in the same
+ * thread), but an application cannot start any #GIOStream operation while there
+ * is a #GIOStream, #GInputStream or #GOutputStream operation in progress, and
+ * an application can’t start any #GInputStream or #GOutputStream operation
+ * while there is a #GIOStream operation in progress.
+ *
+ * This is a product of individual stream operations being associated with a
+ * given #GMainContext (the thread-default context at the time the operation was
+ * started), rather than entire streams being associated with a single
+ * #GMainContext.
+ *
+ * GIO may run operations on #GIOStreams from other (worker) threads, and this
+ * may be exposed to application code in the behaviour of wrapper streams, such
+ * as #GBufferedInputStream or #GTlsConnection. With such wrapper APIs,
+ * application code may only run operations on the base (wrapped) stream when
+ * the wrapper stream is idle. Note that the semantics of such operations may
+ * not be well-defined due to the state the wrapper stream leaves the base
+ * stream in (though they are guaranteed not to crash).
+ *
  * Since: 2.22
  */
 
diff --git a/gio/goutputstream.c b/gio/goutputstream.c
index 1816e8d..9320f8e 100644
--- a/gio/goutputstream.c
+++ b/gio/goutputstream.c
@@ -40,7 +40,10 @@
  * (g_output_stream_flush()). 
  *
  * To copy the content of an input stream to an output stream without 
- * manually handling the reads and writes, use g_output_stream_splice(). 
+ * manually handling the reads and writes, use g_output_stream_splice().
+ *
+ * See the documentation for #GIOStream for details of thread safety of
+ * streaming APIs.
  *
  * All of these functions have async variants too.
  **/
diff --git a/gio/gtlsclientconnection.c b/gio/gtlsclientconnection.c
index 7513ed1..99ff9a8 100644
--- a/gio/gtlsclientconnection.c
+++ b/gio/gtlsclientconnection.c
@@ -156,6 +156,10 @@ g_tls_client_connection_default_init (GTlsClientConnectionInterface *iface)
  * must have pollable input and output streams) which is assumed to
  * communicate with the server identified by @server_identity.
  *
+ * See the documentation for #GTlsConnection:base-io-stream for restrictions
+ * on when application code can run operations on the @base_io_stream after
+ * this function has returned.
+ *
  * Returns: (transfer full) (type GTlsClientConnection): the new
  * #GTlsClientConnection, or %NULL on error
  *
diff --git a/gio/gtlsconnection.c b/gio/gtlsconnection.c
index bd06516..f4a8225 100644
--- a/gio/gtlsconnection.c
+++ b/gio/gtlsconnection.c
@@ -95,7 +95,11 @@ g_tls_connection_class_init (GTlsConnectionClass *klass)
   /**
    * GTlsConnection:base-io-stream:
    *
-   * The #GIOStream that the connection wraps
+   * The #GIOStream that the connection wraps. The connection holds a reference
+   * to this stream, and may run operations on the stream from other threads
+   * throughout its lifetime. Consequently, after the #GIOStream has been
+   * constructed, application code may only run its own operations on this
+   * stream when no #GIOStream operations are running.
    *
    * Since: 2.28
    */
@@ -621,7 +625,8 @@ g_tls_connection_get_peer_certificate_errors (GTlsConnection *conn)
  * on @conn, this will send a close notification regardless of the
  * setting of this property. If you explicitly want to do an unclean
  * close, you can close @conn's #GTlsConnection:base-io-stream rather
- * than closing @conn itself.
+ * than closing @conn itself, but note that this may only be done when no other
+ * operations are pending on @conn or the base I/O stream.
  *
  * Since: 2.28
  */
diff --git a/gio/gtlsserverconnection.c b/gio/gtlsserverconnection.c
index 4c2f486..518af55 100644
--- a/gio/gtlsserverconnection.c
+++ b/gio/gtlsserverconnection.c
@@ -71,6 +71,10 @@ g_tls_server_connection_default_init (GTlsServerConnectionInterface *iface)
  * Creates a new #GTlsServerConnection wrapping @base_io_stream (which
  * must have pollable input and output streams).
  *
+ * See the documentation for #GTlsConnection:base-io-stream for restrictions
+ * on when application code can run operations on the @base_io_stream after
+ * this function has returned.
+ *
  * Returns: (transfer full) (type GTlsServerConnection): the new
  * #GTlsServerConnection, or %NULL on error
  *


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]