天天看點

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

繼續閱讀