浅析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; }
|