oFono学习笔记——oFono中的消息机制
摘要
在之前的文章中提到,对于oFono来说所有的操作都是异步的。这也就是说,oFono必须要提供一套机制来通知对象它所关心的事件发生了。依赖这套机制,也使得atom发现及atom间交流成为可能。本文主要试图讲述我所理解的oFono的事件机制。
1. oFono事件机制
为了不让我们在代码中迷失,我们应该对oFono的事件机制有一个大体的概念,这一节主要给出了一个oFono事件机制的overview。oFono的内部采用的是异步事件机制,具体上来说使用的是Publish/Subcribe模型来实现的。采用异步事件机制可以降低模块间的耦合度(Loose Coupling),提高系统的扩展性。图1.1给出了oFono中事件机制的实现原理。
图1.1
对于Publish/Subscribe模型来说,每一个comsumer都需要subscribe一个指定类型的topic。当有topic published到系统后,系统通知topic的subscriber它所关心的topic已经成立或发生,接下来subscriber就可以对topic进行处理了。对应到oFono中,每个atom要对自己所感兴趣的oFono Event进行注册,这样当有Event发布到oFono Core之后,注册了的atom就能收到响应的topic。需要注意的是,oFono的事件并不一定是由atom产生,subscriber也不一定必须是atom。
下面让我们通过一个atom发现的例子走进oFono的消息机制,看看一个atom是如何知道它所依赖的其他atom已经加入到系统当中来。
2.oFono事件机制代码分析
根据上一个章节的内容我们知道要想得到某个事件信息,必须先向oFono Core进行注册,针对atom注册事件的注册函数是:
1 unsigned int __ofono_modem_add_atom_watch(struct ofono_modem *modem, 2 enum ofono_atom_type type, 3 ofono_atom_watch_func notify, 4 void *data, ofono_destroy_func destroy) 5 { 6 struct atom_watch *watch; 7 unsigned int id; 8 GSList *l; 9 struct ofono_atom *atom; 10 11 if (notify == NULL) 12 return 0; 13 14 watch = g_new0(struct atom_watch, 1); 15 16 watch->type = type; 17 watch->item.notify = notify; 18 watch->item.destroy = destroy; 19 watch->item.notify_data = data; 20 21 /*加入到事件队列中*/ 22 id = __ofono_watchlist_add_item(modem->atom_watches, 23 (struct ofono_watchlist_item *)watch); 24 25 /*检查事件是否发生,发生了就deliver事件*/ 26 for (l = modem->atoms; l; l = l->next) { 27 atom = l->data; 28 29 if (atom->type != type || atom->unregister == NULL) 30 continue; 31 /*通知subscriber*/ 32 notify(atom, OFONO_ATOM_WATCH_CONDITION_REGISTERED, data); 33 } 34 35 return id; 36 }
从代码中可以看出来,oFono首先会创建一个watch对象并加入到一个watchlist当中去,这个过程也就是subscriber向oFono进行注册的一个过程。接下来Core会检查所关心的atom是否已经在系统中存在,如果存在则马上通知subscriber。如果此时atom还没又注册到系统中来,subscriber不会收到任何消息,知道所关心的atom注册到系统中来。下面来看看,atom注册时发生了一些什么事。
1 void __ofono_atom_register(struct ofono_atom *atom, 2 void (*unregister)(struct ofono_atom *)) 3 { 4 if (unregister == NULL) 5 return; 6 7 atom->unregister = unregister; 8 /*deliver atom注册事件*/ 9 call_watches(atom, OFONO_ATOM_WATCH_CONDITION_REGISTERED); 10 } 11 12 static void call_watches(struct ofono_atom *atom, 13 enum ofono_atom_watch_condition cond) 14 { 15 struct ofono_modem *modem = atom->modem; 16 GSList *atom_watches = modem->atom_watches->items; 17 GSList *l; 18 struct atom_watch *watch; 19 ofono_atom_watch_func notify; 20 21 for (l = atom_watches; l; l = l->next) { 22 watch = l->data; 23 24 if (watch->type != atom->type) 25 continue; 26 /*将atom注册事件发布给subscribed对象*/ 27 notify = watch->item.notify; 28 notify(atom, cond, watch->item.notify_data); 29 } 30 }
当atom通过__ofono_atom_register函数注册到系统中后,会调用call_watches来通知subscribed的对象它所关心的atom已经加入到系统中,并做响应的处理。
注:在oFono中,针对不同的事件会有不同的watchlist来存储subscriber信息。
3.总结
以上就是我对oFono事件机制的理解,有不对的地方欢迎指正