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

📄 uxpoll.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 2 页
字号:
                            FD_SET(osfd, &rd);                        }                        if (in_flags_read & PR_POLL_WRITE)                        {                            pd->out_flags |= _PR_POLL_READ_SYS_WRITE;                            FD_SET(osfd, &wt);                        }                        if (in_flags_write & PR_POLL_READ)                        {                            pd->out_flags |= _PR_POLL_WRITE_SYS_READ;                            FD_SET(osfd, &rd);                        }                        if (in_flags_write & PR_POLL_WRITE)                        {                            pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE;                            FD_SET(osfd, &wt);                        }                        if (pd->in_flags & PR_POLL_EXCEPT) FD_SET(osfd, &ex);                    }                }                else                {                    if (0 == ready)                    {                        PRPollDesc *prev;                        for (prev = pds; prev < pd; prev++)                        {                            prev->out_flags = 0;                        }                    }                    ready += 1;  /* this will cause an abrupt return */                    pd->out_flags = PR_POLL_NVAL;  /* bogii */                }            }        }    }    if (0 != ready) return ready;  /* no need to block */    remaining = timeout;    start = PR_IntervalNow();retry:    if (timeout != PR_INTERVAL_NO_TIMEOUT)    {        PRInt32 ticksPerSecond = PR_TicksPerSecond();        tv.tv_sec = remaining / ticksPerSecond;        tv.tv_usec = remaining - (ticksPerSecond * tv.tv_sec);        tv.tv_usec = (PR_USEC_PER_SEC * tv.tv_usec) / ticksPerSecond;        tvp = &tv;    }    ready = _MD_SELECT(maxfd + 1, &rd, &wt, &ex, tvp);    if (ready == -1 && errno == EINTR)    {        if (timeout == PR_INTERVAL_NO_TIMEOUT) goto retry;        else        {            elapsed = (PRIntervalTime) (PR_IntervalNow() - start);            if (elapsed > timeout) ready = 0;  /* timed out */            else            {                remaining = timeout - elapsed;                goto retry;            }        }    }    /*    ** Now to unravel the select sets back into the client's poll    ** descriptor list. Is this possibly an area for pissing away    ** a few cycles or what?    */    if (ready > 0)    {        ready = 0;        for (pd = pds, epd = pd + npds; pd < epd; pd++)        {            PRInt16 out_flags = 0;            if ((NULL != pd->fd) && (0 != pd->in_flags))            {                PRInt32 osfd;                bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);                PR_ASSERT(NULL != bottom);                osfd = bottom->secret->md.osfd;                if (FD_ISSET(osfd, &rd))                {                    if (pd->out_flags & _PR_POLL_READ_SYS_READ)                        out_flags |= PR_POLL_READ;                    if (pd->out_flags & _PR_POLL_WRITE_SYS_READ)                        out_flags |= PR_POLL_WRITE;                }                 if (FD_ISSET(osfd, &wt))                {                    if (pd->out_flags & _PR_POLL_READ_SYS_WRITE)                        out_flags |= PR_POLL_READ;                    if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE)                        out_flags |= PR_POLL_WRITE;                }                 if (FD_ISSET(osfd, &ex)) out_flags |= PR_POLL_EXCEPT;            }            pd->out_flags = out_flags;            if (out_flags) ready++;        }        PR_ASSERT(ready > 0);    }    else if (ready < 0)    {        err = _MD_ERRNO();        if (err == EBADF)        {            /* Find the bad fds */            ready = 0;            for (pd = pds, epd = pd + npds; pd < epd; pd++)            {                pd->out_flags = 0;                if ((NULL != pd->fd) && (0 != pd->in_flags))                {                    bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);                    if (fcntl(bottom->secret->md.osfd, F_GETFL, 0) == -1)                    {                        pd->out_flags = PR_POLL_NVAL;                        ready++;                    }                }            }            PR_ASSERT(ready > 0);        }        else _PR_MD_MAP_SELECT_ERROR(err);    }    return ready;}  /* NativeThreadSelect */#endif  /* !defined(_PR_USE_POLL) */static PRInt32 LocalThreads(    PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout){    PRPollDesc *pd, *epd;    PRInt32 ready, pdcnt;    _PRUnixPollDesc *unixpds, *unixpd;    /*     * XXX     *        PRPollDesc has a PRFileDesc field, fd, while the IOQ     *        is a list of PRPollQueue structures, each of which contains     *        a _PRUnixPollDesc. A _PRUnixPollDesc struct contains     *        the OS file descriptor, osfd, and not a PRFileDesc.     *        So, we have allocate memory for _PRUnixPollDesc structures,     *        copy the flags information from the pds list and have pq     *        point to this list of _PRUnixPollDesc structures.     *     *        It would be better if the memory allocation can be avoided.     */    unixpd = unixpds = (_PRUnixPollDesc*)        PR_MALLOC(npds * sizeof(_PRUnixPollDesc));    if (NULL == unixpds)    {        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);        return -1;    }    ready = 0;    for (pdcnt = 0, pd = pds, epd = pd + npds; pd < epd; pd++)    {        PRFileDesc *bottom;        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 */                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)                    {                        unixpd->osfd = bottom->secret->md.osfd;                        unixpd->in_flags = 0;                        if (in_flags_read & PR_POLL_READ)                        {                            unixpd->in_flags |= _PR_UNIX_POLL_READ;                            pd->out_flags |= _PR_POLL_READ_SYS_READ;                        }                        if (in_flags_read & PR_POLL_WRITE)                        {                            unixpd->in_flags |= _PR_UNIX_POLL_WRITE;                            pd->out_flags |= _PR_POLL_READ_SYS_WRITE;                        }                        if (in_flags_write & PR_POLL_READ)                        {                            unixpd->in_flags |= _PR_UNIX_POLL_READ;                            pd->out_flags |= _PR_POLL_WRITE_SYS_READ;                        }                        if (in_flags_write & PR_POLL_WRITE)                        {                            unixpd->in_flags |= _PR_UNIX_POLL_WRITE;                            pd->out_flags |= _PR_POLL_WRITE_SYS_WRITE;                        }                        if ((in_flags_read | in_flags_write) & PR_POLL_EXCEPT)                        {                            unixpd->in_flags |= _PR_UNIX_POLL_EXCEPT;                        }                        unixpd++; pdcnt++;                    }                }                else                {                    if (0 == ready)                    {                        PRPollDesc *prev;                        for (prev = pds; prev < pd; prev++)                        {                            prev->out_flags = 0;                        }                    }                    ready += 1;  /* this will cause an abrupt return */                    pd->out_flags = PR_POLL_NVAL;  /* bogii */                }            }        }    }    if (0 != ready)    {        /* no need to block */        PR_DELETE(unixpds);        return ready;    }    ready = _PR_WaitForMultipleFDs(unixpds, pdcnt, timeout);    /*     * Copy the out_flags from the _PRUnixPollDesc structures to the     * user's PRPollDesc structures and free the allocated memory     */    unixpd = unixpds;    for (pd = pds, epd = pd + npds; pd < epd; pd++)    {        PRInt16 out_flags = 0;        if ((NULL != pd->fd) && (0 != pd->in_flags))        {            /*             * take errors from the poll operation,             * the R/W bits from the request             */            if (0 != unixpd->out_flags)            {                if (unixpd->out_flags & _PR_UNIX_POLL_READ)                {                    if (pd->out_flags & _PR_POLL_READ_SYS_READ)                        out_flags |= PR_POLL_READ;                    if (pd->out_flags & _PR_POLL_WRITE_SYS_READ)                        out_flags |= PR_POLL_WRITE;                }                if (unixpd->out_flags & _PR_UNIX_POLL_WRITE)                {                    if (pd->out_flags & _PR_POLL_READ_SYS_WRITE)                        out_flags |= PR_POLL_READ;                    if (pd->out_flags & _PR_POLL_WRITE_SYS_WRITE)                        out_flags |= PR_POLL_WRITE;                }                if (unixpd->out_flags & _PR_UNIX_POLL_EXCEPT)                    out_flags |= PR_POLL_EXCEPT;                if (unixpd->out_flags & _PR_UNIX_POLL_ERR)                    out_flags |= PR_POLL_ERR;                if (unixpd->out_flags & _PR_UNIX_POLL_NVAL)                    out_flags |= PR_POLL_NVAL;                if (unixpd->out_flags & _PR_UNIX_POLL_HUP)                    out_flags |= PR_POLL_HUP;            }            unixpd++;        }        pd->out_flags = out_flags;    }    PR_DELETE(unixpds);    return ready;}  /* LocalThreads */#if defined(_PR_USE_POLL)#define NativeThreads NativeThreadPoll#else#define NativeThreads NativeThreadSelect#endifPRInt32 _MD_pr_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout){    PRInt32 rv = 0;    PRThread *me = _PR_MD_CURRENT_THREAD();    if (_PR_PENDING_INTERRUPT(me))    {        me->flags &= ~_PR_INTERRUPT;        PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);        return -1;    }    if (0 == npds) PR_Sleep(timeout);    else if (_PR_IS_NATIVE_THREAD(me))        rv = NativeThreads(pds, npds, timeout);    else rv = LocalThreads(pds, npds, timeout);    return rv;}  /* _MD_pr_poll */#endif  /* defined(_PR_PTHREADS) */               /* uxpoll.c */

⌨️ 快捷键说明

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