分类: 虚拟化
2012-03-24 11:24:44
一、初始化时的函数栈
virNetSocketAddIOCallback()(当然这是以virNetSocket类型的数据结构为例,所谓virNetSocket类型的数据结构是指这类数据结构都是以virNetSocket开头,表现为virNetSocket*形式,例如:virNetSocketPtr)
virEventAddHandle()
addHandleImpl() <==================> virEventPollAddHandle()(通过virEventRegisterImpl函数来实现对应)
在virEventPollAddHandle()函数中将数据填充到eventLoop.handles[]数组中,下面我们就关注怎么用eventLoop.handles[]数组的。
备注:
virNetServerNew 用来建立virNetServerPtr数据结构的同时(这数据结构用来描述remote模式下的server),还调用virEventRegisterDefaultImpl()函数,virEventRegisterDefaultImpl()函数调用virEventRegisterImpl函数来填充addHandleImpl()。
二、event的处理
main() (daemon/libvirtd.c)
virNetServerRun()
virEventRunDefaultImpl()
(在一个while循环中,循环的判断条件是 !srv->quit,srv->quit默认是0,表示server一直在运行,当收到一些信号是该变量才会变成1,表示server退出了,循环也跟着退出)
virEventPollRunOnce()
在virEventPollRunOnce()函数中,调用poll函数,来循环struct pollfd* fds(表示fd的数组),fds的初始化函数是virEventPollMakePollFDs(),在该函数中用eventLoop.handles[]数组来初始化fds。
当poll监视的fds数组中有事件发生,poll退出,返回值>0,virEventPollRunOnce()继续,其接着调用virEventPollDispatchHandles()来处理发生的事件。
在virEventPollDispatchHandles()函数中调用eventLoop.handles[index].cb(初始化注册的回调函数),index通过对比fds数组中fd和eventLoop.handles[]数组中的fd来得到。
三、总结
转了一圈,我们发现当我们调用virNetSocketAddIOCallback()函数后,一旦client->sock->fd有事件发生,就会调用我们调用函数注册的回调函数virNetServerClientDispatchEvent(),所谓回调函数应该就是这种意思。