分类: LINUX
2008-10-24 19:42:17
DBus Inner Principle
Guide
Revision History
Date |
Issue |
Description |
Author |
< |
<0.5> |
First draft |
wangfei |
|
|
|
|
目录
This document explains the inner
principle of dbus.
I will follow
the steps that how user use the dbus to discuss the inner realiziation of dbus.
This is the main
function:
int main(int
argc, char *argv[])
{
loop = init_glib();
init_dbus();
g_idle_add(connect, NULL);
g_main_loop_run(loop);
g_main_loop_unref(loop);
finalize_dbus();
return 0;
}
Follow is the init_dbus,here we can see
two function related to our discuss,first is dbus_bus_get,the other is dbus_connection_setup_with_g_main:
static void
init_dbus(void)
{
DBusError error;
dbus_error_init(&error);
dbus_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
if (dbus_connection == NULL)
g_error("Error when connecting to
the session bus: %s",
error.message);
dbus_connection_setup_with_g_main(dbus_connection,
NULL);
}
The other function is not related to our
discuss ,I list them here,too:
static GMainLoop
*init_glib(void)
{
g_type_init();
return g_main_loop_new(NULL, FALSE);
}
static gboolean
connect(gpointer data)
{
gboolean b;
connection = con_ic_connection_new();
g_assert(connection != NULL);
g_signal_connect(G_OBJECT(connection),
"connection-event",
G_CALLBACK(connection_cb),
GINT_TO_POINTER(USER_DATA_MAGIC));
b = con_ic_connection_connect(connection,
CON_IC_CONNECT_FLAG_NONE);
g_assert(b);
return FALSE;
}
static void
finalize_dbus(void)
{
dbus_connection_unref(dbus_connection);
}
connection_cb is a callback function,which
when receive connection event then
printf some info.
|
Now ,we just need
know that we have registered to the server,and you can image that we open a
socket to the server,then we can communicate to the server.
Here is just to assign some function
pointer,and the most important is add the file descriptor to the main loop to
be selected waiting to be dispatched.
Now we look at the add fd
process:
After fd is added to the
main loop selector,then is the process to dispatch the message.
here is the simple depict
to the message_queue_dispatch,after main function receive the message then will
dispatch to the responding message process callback function,and the function
usually is registered by this way:
static
DBusObjectPathVTable icd_req_vtable = {
.message_function = icd_req_handler,
.unregister_function = NULL
};
dbus_connection_register_object_path(connection,
ICD_REQ_PATH,
&icd_req_vtable,
NULL);
Now
we will see the register process:
Now we just need to know here we register a message handler and how it
is invoked ,later will be discussed detail.
From here we can say:
if you want to use dbus,you first need register to the dbus-daemon
by invoke dbus_bus_get,in essence this step is to get a socket fd to the
server,then the second step is establish a message callback function by invoke dbus_connection_register_object_path
,the third step is to add the socket fd to the main process loop,which when
receive a message or has a message to send will invoke the dispatch function to
receive or send the message to the dbus-daemon,if receive a message,
it will invoke the message function that you
just invoke dbus_connection_register_object_path registerd .
the detailed dispatch
process is like this:
below we will discuss the
whole process of send /receive message ,and when and how the message is
dispatched
Here dbus-deamon set a
watch function to detect the client connection request, and how the server
dispatch the message,then will discuss
the process the server receive the client connect request:
before the server can
process the client connection request,it must first set up the process
handler,below is the setting process:
Here is to create a socket to the
client,then assign some functions to read ,write the socket,and some function
to dispatch the received message and so on.and the most important function is
the function socket_handler_watch,which means when have something read or write
it will be invoked to process,below we will discuss the while process:
the upper just set the
watch handler,but do not show when and how it execute its task:
After these we
know how the client to process the data request,but left a question,when do
these messages are dispatched by the server to the other client?
for server,it will not only process the messages request that the client
send to server,but also the messages client to client,then how it integrate
these to a whole loop:
for every client the fd
will be added to the main loop of server which is the virable need_dispatch
stands for,which when receive messages will dispatch it to clients or processed
by itself.
Now ,I repeat the whole
process with words.
A)
server start,then create a socket to wait be
connected by clients by invoke listen,and set some functions which when client
get in will be executed.
B)
When one client try to connect to the server,it
will invoke accept,then server store the fd to the map associate the
DBusConnection which is created according to fd first to new DBusTransport ,then
to construct to DbusConnection,then will assign some watch function for this
new fd such as reading ,writing function,dispatch function and so on.
C)
When the fd in the server side receive a message,it
will invoke socket_handle_watch to handle the message ,this process order is :
For each method replying
message,first give it to DBusPendingCall,or dbus_connection_send_with_reply_and_block,then to the filters which
is the place to process the messages
to the other clients and the signal process place;if it is the method invoke message,then will pass it to dbus_connection_register_object_path of dbus_connection_register_fallback registerd function until
it return the DBUS_HANDLER_RESULT_HANDLED
,at the last if the message is not processed
it will construct a error message to reply to the invoker.
D)
when the other client receive the message fromm the
socket it will doing the same process logic as the previous step and if needed it
will send reply message.
For more detailed info please see the map at the previous sections,
thanks.