天天看点

mozilla的分层IO架构

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起着同样的作用。

     通过使用PRFileDesc以及prio所提供的众接口,你可以将一系列的io例程堆积在一起,形成一个io栈,这就是分层的思想。分层的IO可以很方便的加入任何自定义的过滤策略和数据加工策略。突然想到,windows操作系统的drivers目录下有一个叫做tcpip.sys的文件,而unix在/dev目录下亦有一个ip,tcp文件。

本文转自 dog250 51CTO博客,原文链接:http://blog.51cto.com/dog250/1271799

继续阅读