X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;ds=sidebyside;f=guestfs.pod;h=cce7b90db7bc964686339626f35869e20e8db01f;hb=bb07a7f858da5d07c57360e62c0ddfd24ce6be45;hp=6c0160006e0e4d644095826c07f96b191572a133;hpb=ec89b939882564b0f7a481298e06111b7578d60d;p=libguestfs.git diff --git a/guestfs.pod b/guestfs.pod index 6c01600..cce7b90 100644 --- a/guestfs.pod +++ b/guestfs.pod @@ -86,9 +86,8 @@ C is the opaque type representing a connection handle. Create a handle by calling C. Call C 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 set to C. =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 in the source. -C 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 and C functions -corresponding to every C action in the high-level API. +The callback function C 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. -This is the default main loop unless you call C -or C. +This is the default main loop for new guestfs handles, unless you +call C 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 + +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 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 or C. + +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. + 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). - 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 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 - #include + 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. -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, 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 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. In those cases, ignore this call. +Free the select-based main loop which was previously allocated with +C. =head2 WRITING A CUSTOM MAIN LOOP