浅析dbus系统loop循环中new_connection消息派发
main
==>_dbus_loop_run
==>_dbus_loop_iterate
==>_dbus_loop_dispatch
==>dbus_connection_dispatch // 会遍历执行&connection->filter_list链表上的所有注册函数filter->function
++>(* filter->function) (connection, message, filter->user_data);
// 暂时先看看filter->function函数什么时候注册
main
**> bus_context_new
**> process_config_first_time_only
**> setup_server
**> dbus_server_set_new_connection_function (server, // 设置回调函数
new_connection_callback,
context, NULL);
最后server->new_connection_function = new_connection_callback;
****> main
****> _dbus_loop_run (bus_context_get_loop (context)) // 执行context->loop为上下文的循环
****> _dbus_loop_iterate
dbus_bool_t
_dbus_loop_iterate (DBusLoop *loop,
dbus_bool_t block)
{
#define N_STACK_DESCRIPTORS 64
......
if (loop->callbacks == NULL)
goto next_iteration;
if (loop->watch_count > N_STACK_DESCRIPTORS) {
fds = dbus_new0 (DBusPollFD, loop->watch_count);
while (fds == NULL)
{
_dbus_wait_for_memory ();
fds = dbus_new0 (DBusPollFD, loop->watch_count);
}
watches_for_fds = dbus_new (WatchCallback*, loop->watch_count);
while (watches_for_fds == NULL)
{
_dbus_wait_for_memory ();
watches_for_fds = dbus_new (WatchCallback*, loop->watch_count);
}
} else {
fds = stack_fds;
watches_for_fds = stack_watches_for_fds;
}
/* fill our array of fds and watches */
n_fds = 0;
link = _dbus_list_get_first_link (&loop->callbacks);
while (link != NULL)
{
......
fds[n_fds].fd = dbus_watch_get_socket (wcb->watch);
fds[n_fds].revents = 0;
fds[n_fds].events = 0;
if (flags & DBUS_WATCH_READABLE)
fds[n_fds].events |= _DBUS_POLLIN;
if (flags & DBUS_WATCH_WRITABLE)
fds[n_fds].events |= _DBUS_POLLOUT;
......
n_ready = _dbus_poll (fds, n_fds, timeout);
// 执行poll,监控_dbus_loop_add_watch函数登记到context->loop->callbacks上的所有watch单元对应的fd.
// add_server_watch 或者 add_connection_watch 或者 add_babysitter_watch都将调用
// _dbus_loop_add_watch向context->loop->callbacks追加watch单元.
}
}
****> server_watch_callback
****> dbus_watch_handle
****> 首先请参考《浅析dbus系统watch函数是如何注册登记的》
****> socket_handle_watch // 感知client链接
****> handle_new_client_fd_and_unlock (server, client_fd)
****> (*server->new_connection_function)(server, connection, new_connection_data)
**> new_connection_callback
**> bus_connections_setup_connection
**> bus_dispatch_add_connection
dbus_bool_t
bus_dispatch_add_connection (DBusConnection *connection)
{
if (!dbus_connection_add_filter (connection,
bus_dispatch_message_filter,
NULL, NULL)) // 调用_dbus_list_append (&connection->filter_list, filter)
return FALSE;
return TRUE;
}
那什么时候引用connection->filter_list链表中登记注册的数据们呢,下面让我们来看看:
main
==>_dbus_loop_run
==>_dbus_loop_iterate
+++++++++++++++++++++++++++++++++++++++++++++
==>bus_connections_setup_connection // 建立新的connection链接
==>_dbus_loop_queue_dispatch // 执行connection->filter_list链表上挂接的所有等待截获新建connection链接的信息的callback们.
dbus_bool_t
_dbus_loop_queue_dispatch (DBusLoop *loop,
DBusConnection *connection)
{
if (_dbus_list_append (&loop->need_dispatch, connection))
{
dbus_connection_ref (connection);
return TRUE;
}
else
return FALSE;
}
==>_dbus_loop_dispatch (loop)
dbus_bool_t
_dbus_loop_dispatch (DBusLoop *loop)
{
......
while (loop->need_dispatch != NULL)
{
DBusConnection *connection = _dbus_list_pop_first (&loop->need_dispatch); // 弹出第一个有效待处理connection.
while (TRUE)
{
DBusDispatchStatus status;
status = dbus_connection_dispatch (connection); // 执行处理
....
}
....
}
......
}
==>_dbus_loop_dispatch
==>status = dbus_connection_dispatch (connection);
==>dbus_connection_dispatch
==>filter->function = bus_dispatch_message_filter
==>bus_dispatch_message_filter
==>bus_dispatch
==>bus_driver_handle_message
static struct
{
const char *name;
const char *in_args;
const char *out_args;
dbus_bool_t (* handler) (DBusConnection *connection,
BusTransaction *transaction,
DBusMessage *message,
DBusError *error);
} message_handlers[] = {
{ "Hello",
"",
DBUS_TYPE_STRING_AS_STRING,
bus_driver_handle_hello },
......
};
==>bus_driver_handle_hello
==>bus_connection_complete
==>d->policy = bus_context_create_client_policy (d->connections->context,
connection,
error);
==>bus_context_create_client_policy
==>bus_policy_create_client_policy(context->policy, connection, error)
==>add_list_to_client (&policy->default_rules, client)
==>add_list_to_client (&policy->at_console_true_rules, client)
==>add_list_to_client (&policy->mandatory_rules, client)
|