Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15531056
  • 博文数量: 2005
  • 博客积分: 11986
  • 博客等级: 上将
  • 技术积分: 22535
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-17 13:56
文章分类

全部博文(2005)

文章存档

2014年(2)

2013年(2)

2012年(16)

2011年(66)

2010年(368)

2009年(743)

2008年(491)

2007年(317)

分类: LINUX

2009-05-31 17:46:26

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

阅读(2450) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~