diff options
| author | Richard Jones <rjones@redhat.com> | 2009-04-18 13:17:12 +0100 |
|---|---|---|
| committer | Richard Jones <rjones@redhat.com> | 2009-04-18 13:17:12 +0100 |
| commit | 1765330e07a48dc6f7bdef7007f69ebe606fa731 (patch) | |
| tree | 659ce188bbe1a0568fc4b58504c6de025b9b2e3d /guestfs.pod | |
| parent | 92804dec7c4982d2039f81586bc4a5cacb46217b (diff) | |
| download | libguestfs-1765330e07a48dc6f7bdef7007f69ebe606fa731.tar.gz libguestfs-1765330e07a48dc6f7bdef7007f69ebe606fa731.tar.xz libguestfs-1765330e07a48dc6f7bdef7007f69ebe606fa731.zip | |
Rewrite of main loop impl, start of FileIn/FileOut support.
Diffstat (limited to 'guestfs.pod')
| -rw-r--r-- | guestfs.pod | 151 |
1 files changed, 77 insertions, 74 deletions
diff --git a/guestfs.pod b/guestfs.pod index 6c016000..cce7b90d 100644 --- a/guestfs.pod +++ b/guestfs.pod @@ -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 |
