glib: Document with-glib-lock.
authorMatt Birkholz <matt@birchwood-abbey.net>
Sat, 17 Mar 2018 19:44:55 +0000 (12:44 -0700)
committerMatt Birkholz <matt@birchwood-abbey.net>
Sat, 17 Mar 2018 19:44:55 +0000 (12:44 -0700)
src/glib/glib.pkg
src/glib/glib.scm
src/glib/glib.texi

index 0776325be37de2ea7b07d090e3c86bfdb6a8e0af..767f34c4aa217d42a82f705660a5ecf665e9b244 100644 (file)
@@ -114,7 +114,6 @@ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
   (export ()
          stop-glib-thread)
   (import (glib)
-         glib-mutex                    ;exposed by integrated with-glib-lock
          with-glib-lock
          assert-glib-locked
          run-glib-cleanups
index 1fbdd0b9f767a44874ac4b5fd8a34846d2d51d79..ef1aac4c450999986f67ec835c9bd6e95010bc1e 100644 (file)
@@ -133,13 +133,11 @@ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 (define (without-glib-lock thunk)
   (without-thread-mutex-lock glib-mutex thunk))
 
-#;(define-integrable (assert-glib-locked operator) #f)
 (define (assert-glib-locked operator)
   ;; Useful at least when debugging single threaded worlds.
   (if (not (eq? (current-thread) (thread-mutex-owner glib-mutex)))
       (outf-error ";glib not locked: "operator"\n")))
 
-#;(define-integrable (assert-without-interruption operator) #f)
 (define (assert-without-interruption operator)
   (if (not (get-thread-event-block))
       (outf-error ";not without-interruption: "operator"\n")))
index 12a386c04d1ec5efa50498ece393a8bb56857720..817dcf95665c5c298857260f09e2808718af572b 100644 (file)
@@ -84,6 +84,31 @@ Scheme's representative of a toolkit resource is dropped and
 collected, the toolkit resource is freed, just as the C/Unix FFI's
 malloced aliens are automatically freed.
 
+The GLib library, and thus libraries build ``on top'' of GLib, are not
+ready for multiple threads.  This is not an issue in single-processing
+worlds, but future multi-processing worlds will need to ensure that
+just one Scheme thread is ``in'' the toolkits.  As of version 0.7, the
+@code{with-glib-lock} procedure is provided.  It serializes access to
+the toolkits by locking a mutex.  If the current thread has not used
+this procedure to lock GLib, every callout to the toolkits will write
+a warning line to stderr.
+
+Callbacks occur during callouts and execute while GLib is locked
+(assuming GLib was locked when the callout was made).  Thus using
+@code{with-glib-lock} in a callback will cause a deadlock.
+
+@anchor{with-glib-lock}
+@deffn Procedure with-glib-lock thunk
+Locks GLib's mutex for the duration of @var{thunk}.  Thus this
+procedure cannot be used inside @var{thunk} or the current thread will
+deadlock in the attempt to lock GLib's mutex twice.
+@end deffn
+
+@deffn Procedure without-glib-lock thunk
+Invokes @var{thunk} after releasing the current thread's lock on
+GLib's mutex, and acquires a lock again before returning.
+@end deffn
+
 @node API Reference, Implementation Notes, Introduction, Top
 @unnumberedsec The GLib Package
 
@@ -208,6 +233,10 @@ password, Scheme's @code{call-with-pass-phrase} procedure is called.
 If the ports are GCed or the stack unwound, pending operations are
 cancelled.  Re-winding the stack is an error.
 
+These procedures do @emph{not} require you to lock GLib first.  They
+seek to acquire the lock and so cannot be used while the current
+thread holds the lock; it will deadlock.
+
 @deffn Procedure open-input-gfile uri
 Returns an input port that reads from @var{uri}.
 @end deffn
@@ -222,7 +251,8 @@ Returns a list of strings --- the names of the ``children'' of
 @end deffn
 
 A more direct interface to GIO's GFile operations is provided by the
-following 8 classes and 18 operations.
+following 8 classes and 18 operations.  These procedures @emph{do}
+require that the current thread lock GLib (@pxref{with-glib-lock}).
 
 @verbatim
     <gfile>
@@ -523,6 +553,11 @@ the target filesystem.
 @node Debugging Facilities, , GIO, API Reference
 @section Debugging Facilities
 
+@deffn Procedure assert-glib-locked name
+If the current thread does not own GLib's mutex, emit a warning line
+on stderr.
+@end deffn
+
 @deffn Procedure stop-glib-thread
 A convenient procedure to call in an emergency.
 @end deffn
@@ -566,14 +601,14 @@ In the example call to @code{gtk-label-get-text} above, a Scheme
 object represents the GtkLabel.  It is a gtk-label instance, whose
 class is a specialization of the abstract gtk-object class.
 
-@unnumberedsec Glib Thread
+@unnumberedsec GLib Thread
 
-When the Glib system loads, it starts a toolkit main loop with Scheme
+When the GLib system loads, it starts a toolkit main loop with Scheme
 attached as an custom idle task.  The main loop then re-starts Scheme,
 which creates a thread to ``run'' the toolkit (actually, return to
 it).  Thus Scheme threads multitask with the toolkit.  Scheme runs as
 an idle task in the toolkit, and the toolkit runs in a Scheme thread.
-A program using the Glib system does not call @code{g_main_loop_run}.
+A program using the GLib system does not call @code{g_main_loop_run}.
 It need only create toolkit objects and attach signal handlers to
 them.