VirtualBox

Ignore:
Timestamp:
Jan 30, 2013 3:37:55 PM (12 years ago)
Author:
vboxsync
Message:

IPRT: Merging poll-win.cpp and poll-posix.cpp, part 1.

File:
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/poll.cpp

    r44420 r44469  
    11/* $Id$ */
    22/** @file
    3  * IPRT - Polling I/O Handles, Windows Implementation.
    4  *
    5  * @todo merge poll-win.cpp and poll-posix.cpp, there is lots of common code.
     3 * IPRT - Polling I/O Handles, Windows+Posix Implementation.
    64 */
    75
    86/*
    9  * Copyright (C) 2010 Oracle Corporation
     7 * Copyright (C) 2010-2013 Oracle Corporation
    108 *
    119 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3129*   Header Files                                                               *
    3230*******************************************************************************/
    33 #include <Windows.h>
     31#include <iprt/cdefs.h>
     32#ifdef RT_OS_WINDOWS
     33# include <Windows.h>
     34#else
     35# include <limits.h>
     36# include <errno.h>
     37# include <sys/poll.h>
     38#endif
    3439
    3540#include <iprt/poll.h>
     
    4146#include <iprt/mem.h>
    4247#include <iprt/pipe.h>
     48#include <iprt/socket.h>
    4349#include <iprt/string.h>
    4450#include <iprt/thread.h>
     
    4955#include "internal/socket.h"
    5056#include "internal/magics.h"
     57
     58
     59/*******************************************************************************
     60*   Defined Constants And Macros                                               *
     61*******************************************************************************/
     62/** The maximum poll set size.
     63 * @remarks To help portability, we set this to the Windows limit. We can lift
     64 *          this restriction later if it becomes necessary. */
     65#define RTPOLL_SET_MAX     64
     66
    5167
    5268
     
    7793
    7894/**
    79  * Poll set data, Windows.
     95 * Poll set data.
    8096 */
    8197typedef struct RTPOLLSETINTERNAL
     
    88104    /** The number of valid handles in the set. */
    89105    uint32_t            cHandles;
    90     /** The native handles. */
    91     HANDLE              ahNative[MAXIMUM_WAIT_OBJECTS];
    92     /** Array of handles and IDs. */
    93     RTPOLLSETHNDENT     aHandles[MAXIMUM_WAIT_OBJECTS];
     106    /** The number of allocated handles. */
     107    uint32_t            cHandlesAllocated;
     108
     109#ifdef RT_OS_WINDOWS
     110    /** Pointer to an array of native handles. */
     111    HANDLE             *pahNative;
     112#else
     113    /** Pointer to an array of pollfd structures. */
     114    struct pollfd      *paPollFds;
     115#endif
     116    /** Pointer to an array of handles and IDs. */
     117    RTPOLLSETHNDENT    *paHandles;
    94118} RTPOLLSETINTERNAL;
     119
    95120
    96121
     
    117142    }
    118143
     144#ifdef RT_OS_WINDOWS
    119145    /*
    120146     * Check + prepare the handles before waiting.
     
    125151    for (i = 0; i < cHandles; i++)
    126152    {
    127         switch (pThis->aHandles[i].enmType)
     153        switch (pThis->paHandles[i].enmType)
    128154        {
    129155            case RTHANDLETYPE_PIPE:
    130                 fEvents = rtPipePollStart(pThis->aHandles[i].u.hPipe, pThis, pThis->aHandles[i].fEvents,
    131                                           pThis->aHandles[i].fFinalEntry, fNoWait);
     156                fEvents = rtPipePollStart(pThis->paHandles[i].u.hPipe, pThis, pThis->paHandles[i].fEvents,
     157                                          pThis->paHandles[i].fFinalEntry, fNoWait);
    132158                break;
    133159
    134160            case RTHANDLETYPE_SOCKET:
    135                 fEvents = rtSocketPollStart(pThis->aHandles[i].u.hSocket, pThis, pThis->aHandles[i].fEvents,
    136                                             pThis->aHandles[i].fFinalEntry, fNoWait);
     161                fEvents = rtSocketPollStart(pThis->paHandles[i].u.hSocket, pThis, pThis->paHandles[i].fEvents,
     162                                            pThis->paHandles[i].fFinalEntry, fNoWait);
    137163                break;
    138164
     
    150176
    151177        if (pid)
    152             *pid = pThis->aHandles[i].id;
     178            *pid = pThis->paHandles[i].id;
    153179        if (pfEvents)
    154180            *pfEvents = fEvents;
     
    163189            while (i-- > 0)
    164190            {
    165                 switch (pThis->aHandles[i].enmType)
     191                switch (pThis->paHandles[i].enmType)
    166192                {
    167193                    case RTHANDLETYPE_PIPE:
    168                         rtPipePollDone(pThis->aHandles[i].u.hPipe, pThis->aHandles[i].fEvents,
    169                                        pThis->aHandles[i].fFinalEntry, false);
     194                        rtPipePollDone(pThis->paHandles[i].u.hPipe, pThis->paHandles[i].fEvents,
     195                                       pThis->paHandles[i].fFinalEntry, false);
    170196                        break;
    171197
    172198                    case RTHANDLETYPE_SOCKET:
    173                         rtSocketPollDone(pThis->aHandles[i].u.hSocket, pThis->aHandles[i].fEvents,
    174                                          pThis->aHandles[i].fFinalEntry, false);
     199                        rtSocketPollDone(pThis->paHandles[i].u.hSocket, pThis->paHandles[i].fEvents,
     200                                         pThis->paHandles[i].fFinalEntry, false);
    175201                        break;
    176202
     
    187213     * Wait.
    188214     */
    189     DWORD dwRc = WaitForMultipleObjectsEx(cHandles, &pThis->ahNative[0],
     215    DWORD dwRc = WaitForMultipleObjectsEx(cHandles, pThis->pahNative,
    190216                                          FALSE /*fWaitAll */,
    191217                                          cMillies == RT_INDEFINITE_WAIT ? INFINITE : cMillies,
     
    213239    {
    214240        fEvents = 0;
    215         switch (pThis->aHandles[i].enmType)
     241        switch (pThis->paHandles[i].enmType)
    216242        {
    217243            case RTHANDLETYPE_PIPE:
    218                 fEvents = rtPipePollDone(pThis->aHandles[i].u.hPipe, pThis->aHandles[i].fEvents,
    219                                          pThis->aHandles[i].fFinalEntry, fHarvestEvents);
     244                fEvents = rtPipePollDone(pThis->paHandles[i].u.hPipe, pThis->paHandles[i].fEvents,
     245                                         pThis->paHandles[i].fFinalEntry, fHarvestEvents);
    220246                break;
    221247
    222248            case RTHANDLETYPE_SOCKET:
    223                 fEvents = rtSocketPollDone(pThis->aHandles[i].u.hSocket, pThis->aHandles[i].fEvents,
    224                                            pThis->aHandles[i].fFinalEntry, fHarvestEvents);
     249                fEvents = rtSocketPollDone(pThis->paHandles[i].u.hSocket, pThis->paHandles[i].fEvents,
     250                                           pThis->paHandles[i].fFinalEntry, fHarvestEvents);
    225251                break;
    226252
     
    237263                *pfEvents = fEvents;
    238264            if (pid)
    239                 *pid = pThis->aHandles[i].id;
     265                *pid = pThis->paHandles[i].id;
    240266            rc = VINF_SUCCESS;
    241267        }
    242268    }
     269
     270#else  /* POSIX */
     271
     272    /* clear the revents. */
     273    uint32_t i = pThis->cHandles;
     274    while (i-- > 0)
     275        pThis->paPollFds[i].revents = 0;
     276
     277    int rc = poll(&pThis->paPollFds[0], pThis->cHandles,
     278                  cMillies == RT_INDEFINITE_WAIT || cMillies >= INT_MAX
     279                  ? -1
     280                  : (int)cMillies);
     281    if (rc == 0)
     282        return VERR_TIMEOUT;
     283    if (rc < 0)
     284        return RTErrConvertFromErrno(errno);
     285    for (i = 0; i < pThis->cHandles; i++)
     286        if (pThis->paPollFds[i].revents)
     287        {
     288            if (pfEvents)
     289            {
     290                *pfEvents = 0;
     291                if (pThis->paPollFds[i].revents & (POLLIN
     292# ifdef POLLRDNORM
     293                                                   | POLLRDNORM     /* just in case */
     294# endif
     295# ifdef POLLRDBAND
     296                                                   | POLLRDBAND     /* ditto */
     297# endif
     298# ifdef POLLPRI
     299                                                   | POLLPRI        /* ditto */
     300# endif
     301# ifdef POLLMSG
     302                                                   | POLLMSG        /* ditto */
     303# endif
     304# ifdef POLLWRITE
     305                                                   | POLLWRITE       /* ditto */
     306# endif
     307# ifdef POLLEXTEND
     308                                                   | POLLEXTEND      /* ditto */
     309# endif
     310                                                   )
     311                   )
     312                    *pfEvents |= RTPOLL_EVT_READ;
     313
     314                if (pThis->paPollFds[i].revents & (POLLOUT
     315# ifdef POLLWRNORM
     316                                                   | POLLWRNORM     /* just in case */
     317# endif
     318# ifdef POLLWRBAND
     319                                                   | POLLWRBAND     /* ditto */
     320# endif
     321                                                   )
     322                   )
     323                    *pfEvents |= RTPOLL_EVT_WRITE;
     324
     325                if (pThis->paPollFds[i].revents & (POLLERR | POLLHUP | POLLNVAL
     326# ifdef POLLRDHUP
     327                                                   | POLLRDHUP
     328# endif
     329                                                   )
     330                   )
     331                *pfEvents |= RTPOLL_EVT_ERROR;
     332            }
     333            if (pid)
     334                *pid = pThis->paHandles[i].id;
     335            return VINF_SUCCESS;
     336        }
     337
     338    AssertFailed();
     339    RTThreadYield();
     340    rc = VERR_INTERRUPTED;
     341
     342#endif /* POSIX */
    243343
    244344    return rc;
     
    310410{
    311411    AssertPtrReturn(phPollSet, VERR_INVALID_POINTER);
    312     RTPOLLSETINTERNAL *pThis = (RTPOLLSETINTERNAL *)RTMemAllocZ(sizeof(RTPOLLSETINTERNAL));
     412    RTPOLLSETINTERNAL *pThis = (RTPOLLSETINTERNAL *)RTMemAlloc(sizeof(RTPOLLSETINTERNAL));
    313413    if (!pThis)
    314414        return VERR_NO_MEMORY;
     
    317417    pThis->fBusy                = false;
    318418    pThis->cHandles             = 0;
    319     for (size_t i = 0; i < RT_ELEMENTS(pThis->ahNative); i++)
    320         pThis->ahNative[i]     = INVALID_HANDLE_VALUE;
     419    pThis->cHandlesAllocated    = 0;
     420#ifdef RT_OS_WINDOWS
     421    pThis->pahNative            = NULL;
     422#else
     423    pThis->paPollFds            = NULL;
     424#endif
     425    pThis->paHandles            = NULL;
    321426
    322427    *phPollSet = pThis;
     
    335440
    336441    ASMAtomicWriteU32(&pThis->u32Magic, ~RTPOLLSET_MAGIC);
     442#ifdef RT_OS_WINDOWS
     443    RTMemFree(pThis->pahNative);
     444    pThis->pahNative = NULL;
     445#else
     446    RTMemFree(pThis->paPollFds);
     447    pThis->paPollFds = NULL;
     448#endif
     449    RTMemFree(pThis->paHandles);
     450    pThis->paHandles = NULL;
    337451    RTMemFree(pThis);
    338452
     
    361475     * Set the busy flag and do the job.
    362476     */
    363     AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true,  false), VERR_CONCURRENT_ACCESS);
    364477
    365478    int             rc       = VINF_SUCCESS;
    366     HANDLE          hNative  = INVALID_HANDLE_VALUE;
     479    RTHCINTPTR      hNative  = -1;
    367480    RTHANDLEUNION   uh;
    368481    uh.uInt = 0;
     
    371484        case RTHANDLETYPE_PIPE:
    372485            uh.hPipe = pHandle->u.hPipe;
    373             if (uh.hPipe != NIL_RTPIPE)
    374                 rc = rtPipePollGetHandle(uh.hPipe, fEvents, &hNative);
     486            if (uh.hPipe == NIL_RTPIPE)
     487                return VINF_SUCCESS;
     488            rc = rtPipePollGetHandle(uh.hPipe, fEvents, &hNative);
    375489            break;
    376490
    377491        case RTHANDLETYPE_SOCKET:
    378492            uh.hSocket = pHandle->u.hSocket;
    379             if (uh.hSocket != NIL_RTSOCKET)
    380                 rc = rtSocketPollGetHandle(uh.hSocket, fEvents, &hNative);
     493            if (uh.hSocket == NIL_RTSOCKET)
     494                return VINF_SUCCESS;
     495            rc = rtSocketPollGetHandle(uh.hSocket, fEvents, &hNative);
    381496            break;
    382497
     
    396511            break;
    397512    }
    398     if (   RT_SUCCESS(rc)
    399         && hNative != INVALID_HANDLE_VALUE)
    400     {
     513    if (RT_SUCCESS(rc))
     514    {
     515        AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true,  false), VERR_CONCURRENT_ACCESS);
     516
    401517        uint32_t const i = pThis->cHandles;
    402518
     
    406522        while (j-- > 0)
    407523        {
    408             if (pThis->aHandles[j].id == id)
     524            if (pThis->paHandles[j].id == id)
    409525            {
    410526                rc = VERR_POLL_HANDLE_ID_EXISTS;
    411527                break;
    412528            }
    413             if (   pThis->aHandles[j].enmType == pHandle->enmType
    414                 && pThis->aHandles[j].u.uInt  == uh.uInt)
     529            if (   pThis->paHandles[j].enmType == pHandle->enmType
     530                && pThis->paHandles[j].u.uInt  == uh.uInt)
    415531                iPrev = j;
    416532        }
     
    418534        /* Check that we won't overflow the poll set now. */
    419535        if (    RT_SUCCESS(rc)
    420             &&  i + 1 > RT_ELEMENTS(pThis->ahNative))
     536            &&  i + 1 > RTPOLL_SET_MAX)
    421537            rc = VERR_POLL_SET_IS_FULL;
     538
     539        /* Grow the tables if necessary. */
     540        if (RT_SUCCESS(rc) && i + 1 > pThis->cHandlesAllocated)
     541        {
     542            uint32_t const  c = pThis->cHandlesAllocated + 32;
     543            void           *pvNew;
     544            pvNew = RTMemRealloc(pThis->paHandles, c * sizeof(pThis->paHandles[0]));
     545            if (pvNew)
     546            {
     547                pThis->paHandles = (PRTPOLLSETHNDENT)pvNew;
     548#ifdef RT_OS_WINDOWS
     549                pvNew = RTMemRealloc(pThis->pahNative, c * sizeof(pThis->pahNative[0]));
     550#else
     551                pvNew = RTMemRealloc(pThis->paPollFds, c * sizeof(pThis->paPollFds[0]));
     552#endif
     553                if (pvNew)
     554                {
     555#ifdef RT_OS_WINDOWS
     556                    pThis->pahNative = (HANDLE *)pvNew;
     557#else
     558                    pThis->paPollFds = (struct pollfd *)pvNew;
     559#endif
     560                    pThis->cHandlesAllocated = c;
     561                }
     562                else
     563                    rc = VERR_NO_MEMORY;
     564            }
     565            else
     566                rc = VERR_NO_MEMORY;
     567        }
     568
    422569        if (RT_SUCCESS(rc))
    423570        {
    424571            /* Add the handles to the two parallel arrays. */
    425             pThis->ahNative[i]             = hNative;
    426             pThis->aHandles[i].enmType     = pHandle->enmType;
    427             pThis->aHandles[i].u           = uh;
    428             pThis->aHandles[i].id          = id;
    429             pThis->aHandles[i].fEvents     = fEvents;
    430             pThis->aHandles[i].fFinalEntry = true;
    431             pThis->cHandles = i + 1;
     572#ifdef RT_OS_WINDOWS
     573            pThis->pahNative[i]            = (HANDLE)hNative;
     574#else
     575            pThis->paPollFds[i].fd         = (int)hNative;
     576            pThis->paPollFds[i].revents = 0;
     577            pThis->paPollFds[i].events  = 0;
     578            if (fEvents & RTPOLL_EVT_READ)
     579                pThis->paPollFds[i].events |= POLLIN;
     580            if (fEvents & RTPOLL_EVT_WRITE)
     581                pThis->paPollFds[i].events |= POLLOUT;
     582            if (fEvents & RTPOLL_EVT_ERROR)
     583                pThis->paPollFds[i].events |= POLLERR;
     584#endif
     585            pThis->paHandles[i].enmType     = pHandle->enmType;
     586            pThis->paHandles[i].u           = uh;
     587            pThis->paHandles[i].id          = id;
     588            pThis->paHandles[i].fEvents     = fEvents;
     589            pThis->paHandles[i].fFinalEntry = true;
    432590
    433591            if (iPrev != UINT32_MAX)
    434592            {
    435                 Assert(pThis->aHandles[i].fFinalEntry);
    436                 pThis->aHandles[i].fFinalEntry = false;
    437             }
    438 
    439             rc = VINF_SUCCESS;
     593                Assert(pThis->paHandles[i].fFinalEntry);
     594                pThis->paHandles[i].fFinalEntry = false;
     595            }
     596
     597#if !defined(RT_OS_WINDOWS)
     598            /* Validate the handle by calling poll()  */
     599            if (poll(&pThis->paPollFds[i], 1, 0) >= 0)
     600            {
     601                /* Add the handle info and close the transaction. */
     602                pThis->paHandles[i].enmType = pHandle->enmType;
     603                pThis->paHandles[i].u       = pHandle->u;
     604                pThis->paHandles[i].id      = id;
     605            }
     606            else
     607            {
     608                rc = RTErrConvertFromErrno(errno);
     609                pThis->paPollFds[i].fd = -1;
     610            }
     611#endif
     612
     613            if (RT_SUCCESS(rc))
     614            {
     615                /* Commit */
     616                pThis->cHandles = i + 1;
     617                rc = VINF_SUCCESS;
     618            }
    440619        }
    441620    }
     
    464643    uint32_t    i  = pThis->cHandles;
    465644    while (i-- > 0)
    466         if (pThis->aHandles[i].id == id)
     645        if (pThis->paHandles[i].id == id)
    467646        {
    468647            /* Save some details for the duplicate searching. */
    469             bool            fFinalEntry = pThis->aHandles[i].fFinalEntry;
    470             RTHANDLETYPE    enmType     = pThis->aHandles[i].enmType;
    471             RTHANDLEUNION   uh          = pThis->aHandles[i].u;
     648            bool            fFinalEntry = pThis->paHandles[i].fFinalEntry;
     649            RTHANDLETYPE    enmType     = pThis->paHandles[i].enmType;
     650            RTHANDLEUNION   uh          = pThis->paHandles[i].u;
    472651
    473652            /* Remove the entry. */
     
    476655            if (cToMove)
    477656            {
    478                 memmove(&pThis->aHandles[i], &pThis->aHandles[i + 1], cToMove * sizeof(pThis->aHandles[i]));
    479                 memmove(&pThis->ahNative[i], &pThis->ahNative[i + 1], cToMove * sizeof(pThis->ahNative[i]));
     657                memmove(&pThis->paHandles[i], &pThis->paHandles[i + 1], cToMove * sizeof(pThis->paHandles[i]));
     658#ifdef RT_OS_WINDOWS
     659                memmove(&pThis->pahNative[i], &pThis->pahNative[i + 1], cToMove * sizeof(pThis->pahNative[i]));
     660#else
     661                memmove(&pThis->paPollFds[i], &pThis->paPollFds[i + 1], cToMove * sizeof(pThis->paPollFds[i]));
     662#endif
    480663            }
    481664
     
    483666            if (fFinalEntry)
    484667                while (i-- > 0)
    485                     if (   pThis->aHandles[i].u.uInt  == uh.uInt
    486                         && pThis->aHandles[i].enmType == enmType)
     668                    if (   pThis->paHandles[i].u.uInt  == uh.uInt
     669                        && pThis->paHandles[i].enmType == enmType)
    487670                    {
    488                         Assert(!pThis->aHandles[i].fFinalEntry);
    489                         pThis->aHandles[i].fFinalEntry = true;
     671                        Assert(!pThis->paHandles[i].fFinalEntry);
     672                        pThis->paHandles[i].fFinalEntry = true;
    490673                        break;
    491674                    }
     
    519702    uint32_t    i  = pThis->cHandles;
    520703    while (i-- > 0)
    521         if (pThis->aHandles[i].id == id)
     704        if (pThis->paHandles[i].id == id)
    522705        {
    523706            if (pHandle)
    524707            {
    525                 pHandle->enmType = pThis->aHandles[i].enmType;
    526                 pHandle->u       = pThis->aHandles[i].u;
     708                pHandle->enmType = pThis->paHandles[i].enmType;
     709                pHandle->u       = pThis->paHandles[i].u;
    527710            }
    528711            rc = VINF_SUCCESS;
     
    574757    uint32_t    i  = pThis->cHandles;
    575758    while (i-- > 0)
    576         if (pThis->aHandles[i].id == id)
    577         {
    578             pThis->aHandles[i].fEvents = fEvents;
     759        if (pThis->paHandles[i].id == id)
     760        {
     761            pThis->paHandles[i].fEvents = fEvents;
     762#if !defined(RT_OS_WINDOWS)
     763            pThis->paPollFds[i].events  = 0;
     764            if (fEvents & RTPOLL_EVT_READ)
     765                pThis->paPollFds[i].events |= POLLIN;
     766            if (fEvents & RTPOLL_EVT_WRITE)
     767                pThis->paPollFds[i].events |= POLLOUT;
     768            if (fEvents & RTPOLL_EVT_ERROR)
     769                pThis->paPollFds[i].events |= POLLERR;
     770#endif
    579771            rc = VINF_SUCCESS;
    580772            break;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette