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起来的,还不清楚。
待继.......
浙公网安备 33010602011771号