Editing Documentation/Maemo 5 Developer Guide/DBus/Asynchronous Glib/D-Bus

Warning: You are not logged in. Your IP address will be recorded in this page's edit history.
The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.
Latest revision Your text
Line 1: Line 1:
-
The example code used below can be found in the [http://vcs.maemo.org/svn/maemoexamples/trunk/glib-dbus-async/ garage svn].
+
The example code used below can be found in the [https://garage.maemo.org/svn/maemoexamples/trunk/glib-dbus-signals/ garage svn].
== Asynchronicity in D-Bus clients ==
== Asynchronicity in D-Bus clients ==
Line 13: Line 13:
== Slow Test Server ==
== Slow Test Server ==
-
The only change on the server side is the addition of delays into each of the RPC methods (<code>setvalue1</code>, <code>setvalue2</code>, <code>getvalue1</code> and <code>getvalue2</code>). This delay is added to the start of each function as follows: [http://vcs.maemo.org/svn/maemoexamples/trunk/glib-dbus-async/server.c glib-dbus-async/server.c]
+
The only change on the server side is the addition of delays into each of the RPC methods (<code>setvalue1</code>, <code>setvalue2</code>, <code>getvalue1</code> and <code>getvalue2</code>). This delay is added to the start of each function as follows: glib-dbus-async/server.c
<source lang="c">
<source lang="c">
Line 95: Line 95:
== Asynchronous Method Calls Using Stubs ==
== Asynchronous Method Calls Using Stubs ==
-
When the <code>glib-bindings-tool</code> is run, it already generates the necessary wrapping stubs to support launching asynchronous method calls. What is then left to do is implementing the callback functions correctly, processing the return errors and launching the method call. [http://vcs.maemo.org/svn/maemoexamples/trunk/glib-dbus-async/client-stubs.c glib-dbus-async/client-stubs.c]
+
When the <code>glib-bindings-tool</code> is run, it already generates the necessary wrapping stubs to support launching asynchronous method calls. What is then left to do is implementing the callback functions correctly, processing the return errors and launching the method call. glib-dbus-async/client-stubs.c
<source lang="c">
<source lang="c">
Line 103: Line 103:
</source>
</source>
-
The client has been simplified, so that it now only operates on <code>value1</code>. The callback that is called from the stub code is presented next: [http://vcs.maemo.org/svn/maemoexamples/trunk/glib-dbus-async/client-stubs.c glib-dbus-async/client-stubs.c]
+
The client has been simplified, so that it now only operates on <code>value1</code>. The callback that is called from the stub code is presented next: glib-dbus-async/client-stubs.c
<source lang="c">
<source lang="c">
Line 137: Line 137:
Because the method call does not return any data, the parameters for the callback are at minimum (those three are always received). Handling errors must be performed within the callback, because errors could be delayed from the server, and not visible immediately at launch time.
Because the method call does not return any data, the parameters for the callback are at minimum (those three are always received). Handling errors must be performed within the callback, because errors could be delayed from the server, and not visible immediately at launch time.
-
Note that the callback does not terminate the program on errors. This is done on purpose in order to demonstrate some common asynchronous problems below. The timestamp function is a small utility function to return a pointer to a string, representing the number of seconds because the program started (useful to visualize the order of the different asynchronous events below). [http://vcs.maemo.org/svn/maemoexamples/trunk/glib-dbus-async/client-stubs.c glib-dbus-async/client-stubs.c]
+
Note that the callback does not terminate the program on errors. This is done on purpose in order to demonstrate some common asynchronous problems below. The timestamp function is a small utility function to return a pointer to a string, representing the number of seconds because the program started (useful to visualize the order of the different asynchronous events below). glib-dbus-async/client-stubs.c
<source lang="c">
<source lang="c">
Line 178: Line 178:
</source>
</source>
-
Using the stub code is rather simple. For each generated synchronous version of a method wrapper, there is also the a <code>_async</code> version of the call. The main difference with the parameters is the removal of the <code>GError</code> pointer (because errors are handled in the callback), and the addition of the callback function to use when the method completes, times out or encounters an error.
+
Using the stub code is rather simple. For each generated synchronous version of a method wrapper, there is also the a _async version of the call. The main difference with the parameters is the removal of the <code>GError</code> pointer (because errors are handled in the callback), and the addition of the callback function to use when the method completes, times out or encounters an error.
The main function remains the same from the previous client examples (a once-per-second timer is created and run from the mainloop until the program is terminated).
The main function remains the same from the previous client examples (a once-per-second timer is created and run from the mainloop until the program is terminated).
Line 324: Line 324:
Starting with some known generated stub code to see which parts can possibly be reused with some modifications is usually the easiest solution. This is shown in the last step of this example, in order to make a version of the asynchronous client that works without the stub generator.
Starting with some known generated stub code to see which parts can possibly be reused with some modifications is usually the easiest solution. This is shown in the last step of this example, in order to make a version of the asynchronous client that works without the stub generator.
-
The first step is to take a peek at the stub-generated code for the <code>setvalue1</code> call (when used asynchronously): [http://vcs.maemo.org/svn/maemoexamples/trunk/glib-dbus-async/value-client-stub.h glib-dbus-async/value-client-stub.h]
+
The first step is to take a peek at the stub-generated code for the <code>setvalue1</code> call (when used asynchronously): glib-dbus-async/value-client-stub.h
<source lang="c">
<source lang="c">
Line 362: Line 362:
</source>
</source>
-
What is notable in the code snippet above is that the <code>_async</code> method creates a temporary small structure that holds the pointer to the callback function and a copy of the userdata pointer. This small structure is then passed to <code>dbus_g_proxy_begin_call</code>, along with the address of the generated callback wrapper function (<code>org_maemo_Value_setvalue1_async_callback</code>). The GLib async launcher also takes a function pointer to a function to be used when the supplied "user-data" (in this case, the small structure) needs to be disposed of after the call. Because it uses <code>g_new</code> to allocate the small structure, it passes <code>g_free</code> as the freeing function. Next comes the argument specification for the method call, which obeys the same rules as the LibOSSO ones.
+
What is notable in the code snippet above is that the _async method creates a temporary small structure that holds the pointer to the callback function and a copy of the userdata pointer. This small structure is then passed to <code>dbus_g_proxy_begin_call</code>, along with the address of the generated callback wrapper function (<code>org_maemo_Value_setvalue1_async_callback</code>). The GLib async launcher also takes a function pointer to a function to be used when the supplied "user-data" (in this case, the small structure) needs to be disposed of after the call. Because it uses <code>g_new</code> to allocate the small structure, it passes <code>g_free</code> as the freeing function. Next comes the argument specification for the method call, which obeys the same rules as the LibOSSO ones.
On RPC completion, the generated callback is invoked and it gets the real callback function pointer and the userdata as its "user-data" parameter. Firs it collects the exit code for the call with <code>dbus_g_proxy_end_call</code>, unpacks the data and invokes the real callback. After returning, the GLib wrappers (which called the generated callback) calls g_free to release the small structure, and the whole RPC launch ends.
On RPC completion, the generated callback is invoked and it gets the real callback function pointer and the userdata as its "user-data" parameter. Firs it collects the exit code for the call with <code>dbus_g_proxy_end_call</code>, unpacks the data and invokes the real callback. After returning, the GLib wrappers (which called the generated callback) calls g_free to release the small structure, and the whole RPC launch ends.
Line 368: Line 368:
The next step is to re-implement pretty much the same logic, but also dispose of the small structure because the callback is implemented directly, not as a wrapper-callback (it also omits the need for one memory allocation and one free).
The next step is to re-implement pretty much the same logic, but also dispose of the small structure because the callback is implemented directly, not as a wrapper-callback (it also omits the need for one memory allocation and one free).
-
The first step for that is to implement the RPC asynchronous launch code: [http://vcs.maemo.org/svn/maemoexamples/trunk/glib-dbus-async/client-glib.c glib-dbus-async/client-glib.c]
+
The first step for that is to implement the RPC asynchronous launch code: glib-dbus-async/client-glib.c
<source lang="c">
<source lang="c">
Line 413: Line 413:
</source>
</source>
-
And the callback that is invoked on method call completion timeouts or errors: [http://vcs.maemo.org/svn/maemoexamples/trunk/glib-dbus-async/client-glib.c glib-dbus-async/client-glib.c]
+
And the callback that is invoked on method call completion timeouts or errors: glib-dbus-async/client-glib.c
<source lang="c">
<source lang="c">
Line 457: Line 457:
</source>
</source>
-
The generated stub code is no longer needed, so the dependency rules for the stubless GLib version are different: [http://vcs.maemo.org/svn/maemoexamples/trunk/glib-dbus-async/Makefile glib-dbus-async/Makefile]
+
The generated stub code is no longer needed, so the dependency rules for the stubless GLib version are different: glib-dbus-async/Makefile
<source lang="make">
<source lang="make">

Learn more about Contributing to the wiki.


Please note that all contributions to maemo.org wiki may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see maemo.org wiki:Copyrights for details). Do not submit copyrighted work without permission!


Cancel | Editing help (opens in new window)