⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uxpoll.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- *//*  * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is the Netscape Portable Runtime (NSPR). *  * The Initial Developer of the Original Code is Netscape * Communications Corporation.  Portions created by Netscape are  * Copyright (C) 1998-2000 Netscape Communications Corporation.  All * Rights Reserved. *  * Contributor(s): *  * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable  * instead of those above.  If you wish to allow use of your  * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL.  If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */#if defined(_PR_PTHREADS)#error "This file should not be compiled"#else  /* defined(_PR_PTHREADS) */#include "primpl.h"#include <sys/time.h>#include <fcntl.h>#ifdef _PR_USE_POLL#include <poll.h>#endif#if defined(_PR_USE_POLL)static PRInt32 NativeThreadPoll(    PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout){    /*     * This function is mostly duplicated from ptio.s's PR_Poll().     */    PRInt32 ready = 0;    /*     * For restarting poll() if it is interrupted by a signal.     * We use these variables to figure out how much time has     * elapsed and how much of the timeout still remains.     */    PRIntn index, msecs;    struct pollfd *syspoll = NULL;    PRIntervalTime start, elapsed, remaining;    syspoll = (struct pollfd*)PR_MALLOC(npds * sizeof(struct pollfd));    if (NULL == syspoll)    {        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);        return -1;    }    for (index = 0; index < npds; ++index)    {        PRFileDesc *bottom;        PRInt16 in_flags_read = 0, in_flags_write = 0;        PRInt16 out_flags_read = 0, out_flags_write = 0;        if ((NULL != pds[index].fd) && (0 != pds[index].in_flags))        {            if (pds[index].in_flags & PR_POLL_READ)            {                in_flags_read = (pds[index].fd->methods->poll)(                    pds[index].fd,                    pds[index].in_flags & ~PR_POLL_WRITE,                    &out_flags_read);            }            if (pds[index].in_flags & PR_POLL_WRITE)            {                in_flags_write = (pds[index].fd->methods->poll)(                    pds[index].fd,                    pds[index].in_flags & ~PR_POLL_READ,                    &out_flags_write);            }            if ((0 != (in_flags_read & out_flags_read))            || (0 != (in_flags_write & out_flags_write)))            {                /* this one is ready right now */                if (0 == ready)                {                    /*                     * We will return without calling the system                     * poll function.  So zero the out_flags                     * fields of all the poll descriptors before                     * this one.                     */                    int i;                    for (i = 0; i < index; i++)                    {                        pds[i].out_flags = 0;                    }                }                ready += 1;                pds[index].out_flags = out_flags_read | out_flags_write;            }            else            {                pds[index].out_flags = 0;  /* pre-condition */                /* now locate the NSPR layer at the bottom of the stack */                bottom = PR_GetIdentitiesLayer(pds[index].fd, PR_NSPR_IO_LAYER);                PR_ASSERT(NULL != bottom);  /* what to do about that? */                if ((NULL != bottom)                && (_PR_FILEDESC_OPEN == bottom->secret->state))                {                    if (0 == ready)                    {                        syspoll[index].fd = bottom->secret->md.osfd;                        syspoll[index].events = 0;  /* pre-condition */                        if (in_flags_read & PR_POLL_READ)                        {                            pds[index].out_flags |=                                _PR_POLL_READ_SYS_READ;                            syspoll[index].events |= POLLIN;                        }                        if (in_flags_read & PR_POLL_WRITE)                        {                            pds[index].out_flags |=                                _PR_POLL_READ_SYS_WRITE;                            syspoll[index].events |= POLLOUT;                        }                        if (in_flags_write & PR_POLL_READ)                        {                            pds[index].out_flags |=                                _PR_POLL_WRITE_SYS_READ;                            syspoll[index].events |= POLLIN;                        }                        if (in_flags_write & PR_POLL_WRITE)                        {                            pds[index].out_flags |=                                _PR_POLL_WRITE_SYS_WRITE;                            syspoll[index].events |= POLLOUT;                        }                        if (pds[index].in_flags & PR_POLL_EXCEPT)                            syspoll[index].events |= POLLPRI;                    }                }                else                {                    if (0 == ready)                    {                        int i;                        for (i = 0; i < index; i++)                        {                            pds[i].out_flags = 0;                        }                    }                    ready += 1;  /* this will cause an abrupt return */                    pds[index].out_flags = PR_POLL_NVAL;  /* bogii */                }            }        }        else        {            /* make poll() ignore this entry */            syspoll[index].fd = -1;        }    }    if (0 == ready)    {        switch (timeout)        {            case PR_INTERVAL_NO_WAIT: msecs = 0; break;            case PR_INTERVAL_NO_TIMEOUT: msecs = -1; break;            default:                msecs = PR_IntervalToMilliseconds(timeout);                start = PR_IntervalNow();        }retry:        ready = _MD_POLL(syspoll, npds, msecs);        if (-1 == ready)        {            PRIntn oserror = errno;            if (EINTR == oserror)            {                if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry;                else if (timeout == PR_INTERVAL_NO_WAIT) ready = 0;                else                {                    elapsed = (PRIntervalTime)(PR_IntervalNow() - start);                    if (elapsed > timeout) ready = 0;  /* timed out */                    else                    {                        remaining = timeout - elapsed;                        msecs = PR_IntervalToMilliseconds(remaining);                        goto retry;                    }                }            }            else _PR_MD_MAP_POLL_ERROR(oserror);        }        else if (ready > 0)        {            for (index = 0; index < npds; ++index)            {                PRInt16 out_flags = 0;                if ((NULL != pds[index].fd) && (0 != pds[index].in_flags))                {                    if (0 != syspoll[index].revents)                    {                        /*                        ** Set up the out_flags so that it contains the                        ** bits that the highest layer thinks are nice                        ** to have. Then the client of that layer will                        ** call the appropriate I/O function and maybe                        ** the protocol will make progress.                        */                        if (syspoll[index].revents & POLLIN)                        {                            if (pds[index].out_flags                            & _PR_POLL_READ_SYS_READ)                            {                                out_flags |= PR_POLL_READ;                            }                            if (pds[index].out_flags                            & _PR_POLL_WRITE_SYS_READ)                            {                                out_flags |= PR_POLL_WRITE;                            }                        }                        if (syspoll[index].revents & POLLOUT)                        {                            if (pds[index].out_flags                            & _PR_POLL_READ_SYS_WRITE)                            {                                out_flags |= PR_POLL_READ;                            }                            if (pds[index].out_flags                            & _PR_POLL_WRITE_SYS_WRITE)                            {                                out_flags |= PR_POLL_WRITE;                            }                        }                        if (syspoll[index].revents & POLLPRI)                            out_flags |= PR_POLL_EXCEPT;                        if (syspoll[index].revents & POLLERR)                            out_flags |= PR_POLL_ERR;                        if (syspoll[index].revents & POLLNVAL)                            out_flags |= PR_POLL_NVAL;                        if (syspoll[index].revents & POLLHUP)                            out_flags |= PR_POLL_HUP;                    }                }                pds[index].out_flags = out_flags;            }        }    }    PR_DELETE(syspoll);    return ready;}  /* NativeThreadPoll */#endif  /* defined(_PR_USE_POLL) */#if !defined(_PR_USE_POLL)static PRInt32 NativeThreadSelect(    PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout){    /*     * This code is almost a duplicate of w32poll.c's _PR_MD_PR_POLL().     */    fd_set rd, wt, ex;    PRFileDesc *bottom;    PRPollDesc *pd, *epd;    PRInt32 maxfd = -1, ready, err;    PRIntervalTime remaining, elapsed, start;    struct timeval tv, *tvp = NULL;    FD_ZERO(&rd);    FD_ZERO(&wt);    FD_ZERO(&ex);    ready = 0;    for (pd = pds, epd = pd + npds; pd < epd; pd++)    {        PRInt16 in_flags_read = 0, in_flags_write = 0;        PRInt16 out_flags_read = 0, out_flags_write = 0;        if ((NULL != pd->fd) && (0 != pd->in_flags))        {            if (pd->in_flags & PR_POLL_READ)            {                in_flags_read = (pd->fd->methods->poll)(                    pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read);            }            if (pd->in_flags & PR_POLL_WRITE)            {                in_flags_write = (pd->fd->methods->poll)(                    pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write);            }            if ((0 != (in_flags_read & out_flags_read))            || (0 != (in_flags_write & out_flags_write)))            {                /* this one's ready right now */                if (0 == ready)                {                    /*                     * We will have to return without calling the                     * system poll/select function.  So zero the                     * out_flags fields of all the poll descriptors                     * before this one.                     */                    PRPollDesc *prev;                    for (prev = pds; prev < pd; prev++)                    {                        prev->out_flags = 0;                    }                }                ready += 1;                pd->out_flags = out_flags_read | out_flags_write;            }            else            {                pd->out_flags = 0;  /* pre-condition */                /* make sure this is an NSPR supported stack */                bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);                PR_ASSERT(NULL != bottom);  /* what to do about that? */                if ((NULL != bottom)                && (_PR_FILEDESC_OPEN == bottom->secret->state))                {                    if (0 == ready)                    {                        PRInt32 osfd = bottom->secret->md.osfd;                        if (osfd > maxfd) maxfd = osfd;                        if (in_flags_read & PR_POLL_READ)                        {                            pd->out_flags |= _PR_POLL_READ_SYS_READ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -