Milán Major

netscape-revival

1 branch
Code

nspr-/src/prfile.c

#include <stdarg.h>
#include "prmon.h"
#include "prfile.h"
#include "prglobal.h"

/*
** Generic "machine independent" portion of the NSPR i/o abstraction
*/

PRMonitor *pr_asyncInput;
PRMonitor *pr_asyncOutput;
PRMonitor *pr_fdLock;

#define MAX_FILE_HANDLE         128

extern PRIOMethods _pr_file_methods;
PRFileDesc pr_fdTable[MAX_FILE_HANDLE];

PRFileHandle _PR_InitFileHandle(PROSFD osfd, PRIOMethods *m)
{
    PRFileDesc *fd;

    if( (osfd < 0) || (osfd >= MAX_FILE_HANDLE) ) {
        return -1;
    }

    PR_ASSERT(pr_fdLock != 0);
    PR_EnterMonitor(pr_fdLock);

    fd = &pr_fdTable[osfd];

    fd->osfd    = osfd;
    fd->methods = m;

    PR_ExitMonitor(pr_fdLock);
    return (PRFileHandle)osfd;
}

void _PR_DestroyFileHandle(PRFileHandle hdl)
{
    PRFileDesc *fd;

    fd = PR_HANDLE_TO_DESC(hdl);

    PR_ASSERT(pr_fdLock != 0);
    PR_EnterMonitor(pr_fdLock);

    fd->flags   = 0;
    fd->osfd    = _OS_INVALID_FD_VALUE;
    fd->methods = &_pr_file_methods;

    PR_ExitMonitor(pr_fdLock);
    return;
}

void _PR_InitIO(void)
{
    PRFileDesc *fd;
    int i;

    if (!pr_asyncInput) {
        pr_asyncInput = PR_NewNamedMonitor(0, "async-input");
        pr_asyncOutput = PR_NewNamedMonitor(0, "async-output");
        pr_fdLock = PR_NewNamedMonitor(0, "fd-lock");

        for(i=0; i<MAX_FILE_HANDLE; i++ ) {
            fd = PR_HANDLE_TO_DESC(i);
            fd->osfd = i;
            fd->methods = &_pr_file_methods;
        }

        _OS_InitIO();
    }
}

PR_PUBLIC_API(PRFileHandle) PR_MapFileHandle(PROSFD osfd, void *data, 
                                            PRIOMethods *methods)
{
    PRFileDesc *fd;

    if( (osfd < 0) || (osfd >= MAX_FILE_HANDLE) ) {
        return -1;
    }

    PR_ASSERT(pr_fdLock != 0);
    PR_EnterMonitor(pr_fdLock);

    fd = PR_HANDLE_TO_DESC(osfd);
    fd->flags    = 0;
    fd->osfd     = osfd;
    fd->methods  = methods;
    fd->instance = data;

    if( fd->methods->init ) {
        (*fd->methods->init)(fd);
    }
    PR_ExitMonitor(pr_fdLock);


    return (PRFileHandle)osfd;
}

PR_PUBLIC_API(int32) PR_READ(PRFileHandle hdl, void *buf, int32 size)
{
    PRFileDesc *fd;

    fd = PR_HANDLE_TO_DESC(hdl);
    return (*fd->methods->read)(fd,buf,size);
}

PR_PUBLIC_API(int32) PR_WRITE(PRFileHandle hdl, const void *buf, int32 size)
{
    PRFileDesc *fd;

    fd = PR_HANDLE_TO_DESC(hdl);
    return (*fd->methods->write)(fd,buf,size);
}

PR_PUBLIC_API(int32) PR_CLOSE(PRFileHandle hdl)
{
    PRFileDesc *fd;
    int32 ret;

    fd = PR_HANDLE_TO_DESC(hdl);
    ret = (*fd->methods->close)(fd);

    _PR_DestroyFileHandle(hdl);
    return ret;
}