/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * 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 the Initial Developer are Copyright (C) 1998-2000
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#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;
            syspoll[index].events = 0;
            pds[index].out_flags = 0;
        }
    }

    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;
                            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 */
                }
            }
        }
        else
        {
            pd->out_flags = 0;
        }
    }

    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 = PR_IntervalToMicroseconds( remaining % 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
#endif

PRInt32 _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 */

