mozilla的IO实现是分层的,本质上和BIO是一样的,只是写法不同罢了,最上层,mozilla封装了一个结构体:
struct PRFileDesc {
const PRIOMethods *methods; //本层的IO函数的实现
PRFilePrivate *secret;
PRFileDesc *lower, *higher; //上下两层,如此所有的层次可以三个三个连成链表
void (PR_CALLBACK *dtor)(PRFileDesc *fd);
PRDescIdentity identity; //标识
};
关于mozilla对分层io描述符的实现请参考nsprpub/pr/src/io/prio.c和nsprpub/pr/src/io/prlayer.c,特别值得一提的是最具有代表性的push操作:
PR_IMPLEMENT(PRStatus) PR_PushIOLayer(PRFileDesc *stack, PRDescIdentity id, PRFileDesc *fd)
{
PRFileDesc *insert = PR_GetIdentitiesLayer(stack, id);
if (stack == insert) { //插入在当前IO栈的顶端
PRFileDesc copy = *stack;
*stack = *fd;
*fd = copy;
fd->higher = stack;
stack->lower = fd;
stack->higher = NULL;
} else { //插入在当前IO栈的任意位置
fd->lower = insert;
fd->higher = insert->higher;
insert->higher->lower = fd;
insert->higher = fd;
}
return PR_SUCCESS;
}
和OpenSSL的BIO_push是十分类似的,只是BIO_push只能在顶端push,是真正的push,而mozilla的实现命名为insert倒是更好。类似的,PR_CreateIOLayerStub和OpenSSL的BIO_new很类似,都是初始化一个新的“要插入”的io描述符,BIO_next在mozilla中直接通过结构体引用,即fd->lower,BIO中的BIO_METHOD实现了本层的io策略,而mozilla的prio实现中的PRIOMethods起着同样的作用。
struct PRFileDesc {
const PRIOMethods *methods; //本层的IO函数的实现
PRFilePrivate *secret;
PRFileDesc *lower, *higher; //上下两层,如此所有的层次可以三个三个连成链表
void (PR_CALLBACK *dtor)(PRFileDesc *fd);
PRDescIdentity identity; //标识
};
关于mozilla对分层io描述符的实现请参考nsprpub/pr/src/io/prio.c和nsprpub/pr/src/io/prlayer.c,特别值得一提的是最具有代表性的push操作:
PR_IMPLEMENT(PRStatus) PR_PushIOLayer(PRFileDesc *stack, PRDescIdentity id, PRFileDesc *fd)
{
PRFileDesc *insert = PR_GetIdentitiesLayer(stack, id);
if (stack == insert) { //插入在当前IO栈的顶端
PRFileDesc copy = *stack;
*stack = *fd;
*fd = copy;
fd->higher = stack;
stack->lower = fd;
stack->higher = NULL;
} else { //插入在当前IO栈的任意位置
fd->lower = insert;
fd->higher = insert->higher;
insert->higher->lower = fd;
insert->higher = fd;
}
return PR_SUCCESS;
}
和OpenSSL的BIO_push是十分类似的,只是BIO_push只能在顶端push,是真正的push,而mozilla的实现命名为insert倒是更好。类似的,PR_CreateIOLayerStub和OpenSSL的BIO_new很类似,都是初始化一个新的“要插入”的io描述符,BIO_next在mozilla中直接通过结构体引用,即fd->lower,BIO中的BIO_METHOD实现了本层的io策略,而mozilla的prio实现中的PRIOMethods起着同样的作用。
通过使用PRFileDesc以及prio所提供的众接口,你可以将一系列的io例程堆积在一起,形成一个io栈,这就是分层的思想。分层的IO可以很方便的加入任何自定义的过滤策略和数据加工策略。突然想到,windows操作系统的drivers目录下有一个叫做tcpip.sys的文件,而unix在/dev目录下亦有一个ip,tcp文件。
本文转自 dog250 51CTO博客,原文链接:http://blog.51cto.com/dog250/1271799