Rewrite of main loop impl, start of FileIn/FileOut support.
[libguestfs.git] / guestfs.pod
index 6c01600..cce7b90 100644 (file)
@@ -86,9 +86,8 @@ C<guestfs_h> is the opaque type representing a connection handle.
 Create a handle by calling C<guestfs_create>.  Call C<guestfs_close>
 to free the handle and release all resources used.
 
-Handles and operations on handles are not thread safe.  However you
-can use a separate handle for each thread (but not on the same disk
-image).
+For information on using multiple handles and threads, see the section
+MULTIPLE HANDLES AND MULTIPLE THREADS below.
 
 =head2 guestfs_create
 
@@ -312,34 +311,21 @@ this function with C<cb> set to C<NULL>.
 
 =head2 NON-BLOCKING ACTIONS
 
-XXX NOT IMPLEMENTED YET XXX
+XXX This section was documented in previous versions but never
+implemented in a way which matched the documentation.  For now I have
+removed the documentation, pending a working implementation.  See also
+C<src/guestfs-actions.c> in the source.
 
-C<guestfs_set_reply_callback> is the most interesting callback to
-play with, since it allows you to perform actions without blocking.
 
-For example:
+=head2 guestfs_set_send_callback
 
- do_it ()
- {
-   start_call ();
-   guestfs_main_loop_run (); /* --> blocks, then calls my_cb */
- }
+ typedef void (*guestfs_send_cb) (guestfs_h *g, void *opaque);
+ void guestfs_set_send_callback (guestfs_h *handle,
+                                 guestfs_send_cb cb,
+                                 void *opaque);
 
- start_call ()
- {
-   guestfs_set_reply_callback (handle, my_cb, data);
-   guestfs_nb_[action] (handle, [other parameters ...]);
-   /* returns immediately */
- }
- my_cb (guestfs_h *handle, void *data, XDR *xdr)
- {
-   retval = guestfs_nb_[action]_r (handle, xdr);
-   /* ... */
- }
-
-There are C<guestfs_nb_*> and C<guestfs_nb_*_r> functions
-corresponding to every C<guestfs_*> action in the high-level API.
+The callback function C<cb> will be called whenever a message
+which is queued for sending, has been sent.
 
 =head2 guestfs_set_reply_callback
 
@@ -400,9 +386,10 @@ non-blocking wait for the child process to finish booting up.
 
 =head2 EVENT MAIN LOOP
 
-To use the low-level event API, you have to provide an event "main
-loop".  You can write your own, but if you don't want to write one,
-two are provided for you:
+To use the low-level event API and/or to use handles from multiple
+threads, you have to provide an event "main loop".  You can write your
+own, but if you don't want to write one, two types are provided for
+you:
 
 =over 4
 
@@ -410,8 +397,8 @@ two are provided for you:
 
 A simple main loop that is implemented using L<select(2)>.
 
-This is the default main loop unless you call C<guestfs_set_main_loop>
-or C<guestfs_glib_set_main_loop>.
+This is the default main loop for new guestfs handles, unless you
+call C<guestfs_set_main_loop> after a handle is created.
 
 =item libguestfs-glib
 
@@ -421,67 +408,83 @@ without hanging during long or slow operations.
 
 =back
 
-=head2 guestfs_set_main_loop
+=head2 MULTIPLE HANDLES AND MULTIPLE THREADS
+
+The support for multiple handles and multiple threads is modelled
+after glib (although doesn't require glib, if you use the select-based
+main loop).
+
+L<http://library.gnome.org/devel/glib/unstable/glib-The-Main-Event-Loop.html>
+
+You will need to create one main loop for each thread that wants to
+use libguestfs.  Each guestfs handle should be confined to one thread.
+If you try to pass guestfs handles between threads, you will get
+undefined results.
+
+If you only want to use guestfs handles from one thread in your
+program, but your program has other threads doing other things, then
+you don't need to do anything special.
 
- void guestfs_set_main_loop (guestfs_main_loop *);
+=head2 SINGLE THREAD CASE
 
-This call sets the current main loop to the list of callbacks
-contained in the C<guestfs_main_loop> structure.
+In the single thread case, there is a single select-based main loop
+created for you.  All guestfs handles will use this main loop to
+execute high level API actions.
 
-Only one main loop implementation can be used by libguestfs, so
-calling this replaces the previous one.  (So this is something that
-has to be done by the main program, but only the main program "knows"
-that it is a GTK+ program or whatever).
+=head2 MULTIPLE THREADS CASE
+
+In the multiple threads case, you will need to create a main loop for
+each thread that wants to use libguestfs.
+
+To create main loops for other threads, use
+C<guestfs_create_main_loop> or C<guestfs_glib_create_main_loop>.
+
+Then you will need to attach each handle to the thread-specific main
+loop by calling:
+
+ handle = guestfs_create ();
+ guestfs_set_main_loop (handle, main_loop_of_current_thread);
+
+=head2 guestfs_set_main_loop
 
-You should call this early in the main program, certainly before
-calling C<guestfs_create>.
+ void guestfs_set_main_loop (guestfs_h *handle,
+                             guestfs_main_loop *main_loop);
 
-=head2 guestfs_glib_set_main_loop
+Sets the main loop used by high level API actions for this handle.  By
+default, the select-based main loop is used (see
+C<guestfs_get_default_main_loop>).
 
- void guestfs_glib_set_main_loop (GMainLoop *);
+You only need to use this in multi-threaded programs, where multiple
+threads want to use libguestfs.  Create a main loop for each thread,
+then call this function.
 
-This helper calls C<guestfs_set_main_loop> with the correct callbacks
-for integrating with the GLib main loop.
+You cannot pass guestfs handles between threads.
 
-The libguestfs-glib main loop is contained in a separate library, so
-that libguestfs doesn't depend on the whole of GLib:
+=head2 guestfs_get_main_loop
 
- #include <glib.h>
- #include <guestfs-glib.h>
+ guestfs_main_loop *guestfs_get_main_loop (guestfs_h *handle);
 
- main ()
- {
-   GMainLoop *loop =
-     g_main_loop_new (g_main_context_default (), 1);
-   ...
-   guestfs_glib_set_main_loop (loop);
-   ...
-   g_main_loop_run (loop);
- }
+Return the main loop used by C<handle>.
 
-To use this main loop you must link with C<-lguestfs-glib>.  (See also
-the GLib and GTK+ documentation).
+=head2 guestfs_get_default_main_loop
 
-=head2 guestfs_main_loop_run
+ guestfs_main_loop *guestfs_get_default_main_loop (void);
 
- void guestfs_main_loop_run (void);
+Return the default select-based main loop.
 
-This calls the main loop.
+=head2 guestfs_create_main_loop
 
-For some types of main loop you may want or prefer to call another
-function, eg. C<g_main_loop_run>, or the main loop may already be
-invoked by another part of your program.  In those cases, ignore this
-call.
+ guestfs_main_loop *guestfs_create_main_loop (void);
 
-=head2 guestfs_main_loop_quit
+This creates a select-based main loop.  You should create one main
+loop for each additional thread that needs to use libguestfs.
 
- void guestfs_main_loop_quit (void);
+=head2 guestfs_free_main_loop
 
-This instructs the main loop to quit.  In other words,
-C<guestfs_main_loop_run> will return.
+ void guestfs_free_main_loop (guestfs_main_loop *);
 
-For some types of main loop you may want or prefer to call another
-function, eg. C<g_main_loop_quit>.  In those cases, ignore this call.
+Free the select-based main loop which was previously allocated with
+C<guestfs_create_main_loop>.
 
 =head2 WRITING A CUSTOM MAIN LOOP