dbus 源码走读-3 loop的创建

[2022-10-14]

BusContext中创建的第一个较复杂的结构体就是DbusLoop。通过_dbus_loop_new ()实现。

代码位于dbus/dbus-mainloop.c中。

DbusLoop结构体的定义如下:

struct DBusLoop
{
int refcount;
/** DBusPollable => dbus_malloc'd DBusList ** of references to DBusWatch */
DBusHashTable *watches;
DBusPollableSet *pollable_set;
DBusList *timeouts;
int callback_list_serial;
int watch_count;
int timeout_count;
int depth; /**< number of recursive runs */
DBusList *need_dispatch;
/** TRUE if we will skip a watch next time because it was OOM; becomes
* FALSE between polling, and dealing with the results of the poll */
unsigned oom_watch_pending : 1;
}

其中DBusList 是一个双向链表,data是一个void 指针。定义在dbus/dbus-list.h(.c)中。

struct DBusList
{
DBusList *prev; /**< Previous list node. */
DBusList *next; /**< Next list node. */
void *data; /**< Data stored at this element. */
};

DBusHashTable是一个很复杂的结构体,定义在dbus/dbus-hash.h(.c)中,源文件中的注释如下:

/**
* @brief Internals of DBusHashTable.
*
* Hash table internals. Hash tables are opaque objects, they must be
* used via accessor functions.
*/

它的主要成员是DBusHashEntry 数组。包含静态和动态两部分。

DBusHashEntry的定义如下:

/**
* @brief Internal representation of a hash entry.
*
* A single entry (key-value pair) in the hash table.
* Internal to hash table implementation.
*/
struct DBusHashEntry
{
DBusHashEntry *next; /**< Pointer to next entry in this
* hash bucket, or #NULL for end of
* chain.
*/
void *key; /**< Hash key */
void *value; /**< Hash value */
};

另外还有DBusMemPool *entry_pool; 显然这是用来管理hash表内存的。

 DBusLoop中还有一个重要的结构体(DBusPollableSet),该结构的定义如下(dbus/dbus-pollable-set.h):

struct DBusPollableSet {
DBusPollableSetClass *cls;
};

而DBusPollableSetClass也是一个结构体,但该结构体的成员全部是函数指针,因此可以理解为一个接口。但源码中使用了Class,本意应该是模拟c++的类。

struct DBusPollableSetClass {
void (*free) (DBusPollableSet *self);
dbus_bool_t (*add) (DBusPollableSet *self, DBusPollable fd, unsigned int flags, dbus_bool_t enabled);
void (*remove) (DBusPollableSet *self, DBusPollable fd);
void (*enable) (DBusPollableSet *self, DBusPollable fd, unsigned int flags);
void (*disable) (DBusPollableSet *self, DBusPollable fd);
int (*poll) (DBusPollableSet *self, DBusPollableEvent *revents, int max_events, int timeout_ms);
};

从DBusPollableSet和DBusPollableSetClass的关系可以看出,DBusPollableSet类似一个具有多态特性的“类”或“接口"。相当于C++中的抽象类或JAVA中的接口。

给DBusPollabeSet初始化不同的DBusPollableSetClass实例,可以得到不同的行为。这明显模拟了面向对象的多态特性。

DbusLoop结构体的结构就介绍到这里,下一次将走读它的创建过程。

[2022-10-27]

DbusLoop实列的创建就是hash_table watches和pollable_set 的创建。

1)watches hash_table的创建

loop->watches = _dbus_hash_table_new (DBUS_HASH_POLLABLE, NULL, free_watch_table_entry);

_dbus_hash_table_new的原型如下:

DBusHashTable * _dbus_hash_table_new (DBusHashType type, DBusFreeFunction key_free_function, DBusFreeFunction value_free_function)

* @param type the type of hash key to use.
* @param key_free_function function to free hash keys.
* @param value_free_function function to free hash values.
* @returns a new DBusHashTable or #NULL if no memory.

由此可知,watches 表是一个以整型数字为key,DBusList 为值类型的哈希表。(value_free_function 决定了值的类型)

 

2) pollable_set 的创建

loop->pollable_set = _dbus_pollable_set_new (0);

非常简单就是创建了一个DBusPollableSet的实例。而且只分配了内存,并没有对DBusPollableSetClass 的成员赋值。可以预期后续使用它们之前还有相应的赋值操作。

 

_dbus_loop_new()主要就干了这两件事情。但是,DBusLoop到底怎么run起来的,还不清楚。

待继.......

 

posted @ 2022-10-27 10:10  耕读编码  阅读(564)  评论(0)    收藏  举报