Libeio 源码简单阅读

March 03, 2012 | 0 Minute Read

libeio 和 libev同一个作者写的吧,看网上有一篇文章说是node.js用的这个来做异步文件操作的。

http://cvs.schmorp.de/libeio/

大概过了了一下,代码很少,全部放到一个文件里面,也不复杂,只是宏用的有点多,看起来不是很明了。其实就是把异步操作放到request里面,然后启动几个工作线程,工作线程就会去队列里面那request处理。没有看到什么印象特别深刻的地方。


struct eio_req 每个用户的异步操作都放到一个request结构里面去吧。然后后续操作会把这个request放到“待处理队列”,“已经处理的队列”。这个request结构和我代码里面自己写的一个request也差不多呵呵,一些状态啊,缓存指针啊,回调函数啊,等等,看来我水平也不错滴!libeio 源码简单阅读 - widebright - widebright的个人空间

操作这两个队列有两个锁,下面的那些函数,reqq_push 啊等都要事先获取锁。这队列还是有优先级的。

static etp_reqq req_queue; //待处理的request

static etp_reqq res_queue; //已经处理完的request


etp_submit

reqq_push (&res_queue, req)  把它加到request队列,等等处理

etp_maybe_start_thread()  //这个检查线程是否足够了,或者启动工作线程etp_start_thread()

代码里面写了,很多异步函数,最后都是调用etp_submit把request放到队列里面去而已

eio_req *eio_wd_open (const char *path, int pri, eio_cb cb, void *data)

{

REQ (EIO_WD_OPEN); PATH; SEND;

}

eio_req *eio_read (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data)

{

REQ (EIO_READ); req->int1 = fd; req->offs = offset; req->size = length; req->ptr2 = buf; SEND;

}

REQ这里会申请内存,建一个request,然后初始化那些。SEND其实就是调用的etp_submit函数了。


工作线程是

X_THREAD_PROC (etp_proc)

  req = reqq_shift (&req_queue);   //从request队列里面取出request

  ETP_EXECUTE (self, req);   // 一个wrapper函数,调用实际的系统io函数,比如read、 write啊等等。

  if (!reqq_push (&res_queue, req) && want_poll_cb)  //工作完了,把它放到完成队列里面去。

etp_poll () 这个应该是给用户调用的

etp_maybe_start_thread

req = reqq_shift (&res_queue); //从已经完成的request队列里面取出request,

done_poll_cb () 调用用户设置的的回调函数