浅析dbus系统watch函数是如何注册登记的
main
==>bus_context_new
==>process_config_first_time_only
==>dbus_server_listen
==>(* listen_funcs[j].func)(entries[i], &server, &tmp_error);
==>_dbus_server_listen_socket
static const struct {
DBusServerListenResult (* func) (DBusAddressEntry *entry,
DBusServer **server_p,
DBusError *error);
} listen_funcs[] = {
{ _dbus_server_listen_socket } // for tcp:
, { _dbus_server_listen_platform_specific } // for unix:
#ifdef DBUS_BUILD_TESTS
, { _dbus_server_listen_debug_pipe }
#endif
};
==>_dbus_server_listen_platform_specific
==>*server_p = _dbus_server_new_for_domain_socket (path, FALSE, error);
==**>_dbus_server_new_for_socket
==> socket_server->watch[i] = _dbus_watch_new (fds[i], DBUS_WATCH_READABLE,
TRUE,socket_handle_watch, socket_server, NULL)
//--> watch->handler = socket_handle_watch
==>_dbus_server_init_base (&socket_server->base, &socket_vtable, address)
//--> server->watches = _dbus_watch_list_new ();
==>_dbus_server_add_watch(&socket_server->base, socket_server->watch[i])
dbus_bool_t
_dbus_server_add_watch (DBusServer *server,
DBusWatch *watch) // 将watch添加到server的watches链表上[luther.gliethttp]
{
HAVE_LOCK_CHECK (server);
return protected_change_watch (server, watch,
_dbus_watch_list_add_watch,
NULL, NULL, FALSE);
}
==>protected_change_watch
static dbus_bool_t
protected_change_watch (DBusServer *server,
DBusWatch *watch,
DBusWatchAddFunction add_function,
DBusWatchRemoveFunction remove_function,
DBusWatchToggleFunction toggle_function,
dbus_bool_t enabled)
{
DBusWatchList *watches;
dbus_bool_t retval;
HAVE_LOCK_CHECK (server);
/* This isn't really safe or reasonable; a better pattern is the "do
* everything, then drop lock and call out" one; but it has to be
* propagated up through all callers
*/
watches = server->watches; // server->watches已经在_dbus_server_init_base (&socket_server->base, &socket_vtable, address)
// 中,执行了初始化server->watches = _dbus_watch_list_new ();
if (watches)
{
server->watches = NULL;
_dbus_server_ref_unlocked (server);
SERVER_UNLOCK (server);
if (add_function)
retval = (* add_function) (watches, watch); // 执行_dbus_watch_list_add_watch添加该watch,到watches链表中.
else if (remove_function)
{
retval = TRUE;
(* remove_function) (watches, watch);
}
else
{
retval = TRUE;
(* toggle_function) (watches, watch, enabled);
}
SERVER_LOCK (server);
server->watches = watches;
_dbus_server_unref_unlocked (server);
return retval;
}
else
return FALSE;
}
==>_dbus_watch_list_add_watch
dbus_bool_t
_dbus_watch_list_add_watch (DBusWatchList *watch_list,
DBusWatch *watch)
{
if (!_dbus_list_append (&watch_list->watches, watch))
return FALSE;
_dbus_watch_ref (watch);
if (watch_list->add_watch_function != NULL) // 这时的watch_list->add_watch_function等于NULL,最后将等于add_server_watch
{
_dbus_verbose ("Adding watch on fd %d\n",
dbus_watch_get_socket (watch));
if (!(* watch_list->add_watch_function) (watch,
watch_list->watch_data))
{
_dbus_list_remove_last (&watch_list->watches, watch);
_dbus_watch_unref (watch);
return FALSE;
}
}
return TRUE;
}
// 看看watch_list->add_watch_function怎么生成的.
watch_list->add_watch_function
main
==>bus_context_new
==>process_config_first_time_only
==>setup_server
static dbus_bool_t
setup_server (BusContext *context,
DBusServer *server,
char **auth_mechanisms,
DBusError *error)
{
BusServerData *bd;
bd = dbus_new0 (BusServerData, 1);
if (bd == NULL || !dbus_server_set_data (server,
server_data_slot,
bd, free_server_data))
{
dbus_free (bd);
BUS_SET_OOM (error);
return FALSE;
}
bd->context = context;
if (!dbus_server_set_auth_mechanisms (server, (const char**) auth_mechanisms))
{
BUS_SET_OOM (error);
return FALSE;
}
dbus_server_set_new_connection_function (server,
new_connection_callback,
context, NULL);
if (!dbus_server_set_watch_functions (server, // 注册watch_list->add_watch_function回调函数add_server_watch
add_server_watch,
remove_server_watch,
NULL,
server,
NULL))
{
BUS_SET_OOM (error);
return FALSE;
}
if (!dbus_server_set_timeout_functions (server,
add_server_timeout,
remove_server_timeout,
NULL,
server, NULL))
{
BUS_SET_OOM (error);
return FALSE;
}
return TRUE;
}
==>dbus_server_set_watch_functions(server, add_server_watch, remove_server_watch, NULL, server, NULL);
==>_dbus_watch_list_set_functions(watches, add_function, remove_function, toggled_function, data, free_data_function);
dbus_bool_t
_dbus_watch_list_set_functions (DBusWatchList *watch_list,
DBusAddWatchFunction add_function,
DBusRemoveWatchFunction remove_function,
DBusWatchToggledFunction toggled_function,
void *data,
DBusFreeFunction free_data_function)
{
/* Add watches with the new watch function, failing on OOM */
if (add_function != NULL)
{
link = _dbus_list_get_first_link (&watch_list->watches); // 遍历已经添加到watch_list->watches链表上的所有watch单元.
while (link != NULL)
{
DBusList *next = _dbus_list_get_next_link (&watch_list->watches,
link);
if (!(* add_function) (link->data, data)) { // 对链表上的每个watch单元执行add_server_watch操作.[luther.gliethttp]
......
}
link = next;
}
}
if (watch_list->watch_free_data_function != NULL)
(* watch_list->watch_free_data_function) (watch_list->watch_data);
watch_list->add_watch_function = add_function;
watch_list->remove_watch_function = remove_function;
watch_list->watch_toggled_function = toggled_function;
watch_list->watch_data = data;
watch_list->watch_free_data_function = free_data_function;
return TRUE;
}
==>watch_list->add_watch_function = add_server_watch;
watch_list->watch_data = (DBusServer*)server;
static dbus_bool_t
add_server_watch (DBusWatch *watch,
void *data)
{
DBusServer *server = data;
BusContext *context;
context = server_get_context (server);
return _dbus_loop_add_watch (context->loop, // 向context->loop添加一个需要被watch的单元.
watch, server_watch_callback, server,
NULL);
}
static dbus_bool_t
server_watch_callback (DBusWatch *watch,
unsigned int condition,
void *data)
{
/* FIXME this can be done in dbus-mainloop.c
* if the code in activation.c for the babysitter
* watch handler is fixed.
*/
return dbus_watch_handle (watch, condition);
==> socket_handle_watch
}
dbus_bool_t
_dbus_loop_add_watch (DBusLoop *loop,
DBusWatch *watch,
DBusWatchFunction function,
void *data,
DBusFreeFunction free_data_func)
{
WatchCallback *wcb;
wcb = watch_callback_new (watch, function, data, free_data_func);
if (wcb == NULL)
return FALSE;
if (!add_callback (loop, (Callback*) wcb))
{
wcb->callback.free_data_func = NULL; /* don't want to have this side effect */
callback_unref ((Callback*) wcb);
return FALSE;
}
return TRUE;
}
static dbus_bool_t
add_callback (DBusLoop *loop,
Callback *cb)
{
if (!_dbus_list_append (&loop->callbacks, cb)) // 追加到context->loop->callbacks链表中
return FALSE;
loop->callback_list_serial += 1;
switch (cb->type)
{
case CALLBACK_WATCH:
loop->watch_count += 1; // context->loop->watch_count计数加1
break;
case CALLBACK_TIMEOUT:
loop->timeout_count += 1;
break;
}
return TRUE;
}
|