VirtualBox

Changeset 27509 in vbox for trunk/src/VBox/Runtime/r3/win


Ignore:
Timestamp:
Mar 18, 2010 11:47:16 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
59012
Message:

iprt: Poll on sockets on windows (untested). RTPollSetCount -> RTPollSetGetCount.

Location:
trunk/src/VBox/Runtime/r3/win
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/win/pipe-win.cpp

    r27431 r27509  
    10181018
    10191019/**
    1020  * Internal RTPollSetAdd helper that returns one or two handles that should be
    1021  * added to the pollset.
     1020 * Internal RTPollSetAdd helper that returns the handle that should be added to
     1021 * the pollset.
    10221022 *
    10231023 * @returns Valid handle on success, INVALID_HANDLE_VALUE on failure.
    10241024 * @param   hPipe               The pipe handle.
    10251025 * @param   fEvents             The events we're polling for.
    1026  * @param   ph1                 wher to put the primary handle.
    1027  * @param   ph2                 Where to optionally return a 2nd handle.
     1026 * @param   ph                  wher to put the primary handle.
    10281027 */
    1029 int rtPipePollGetHandles(RTPIPE hPipe, uint32_t fEvents, PHANDLE ph1, PHANDLE ph2)
     1028int rtPipePollGetHandle(RTPIPE hPipe, uint32_t fEvents, PHANDLE ph)
    10301029{
    10311030    RTPIPEINTERNAL *pThis = hPipe;
     
    10361035    AssertReturn(!(fEvents & RTPOLL_EVT_WRITE) || !pThis->fRead, VERR_INVALID_PARAMETER);
    10371036
    1038     *ph1 = pThis->Overlapped.hEvent;
    10391037    /* Later: Try register an event handle with the pipe like on OS/2, there is
    10401038       a file control for doing this obviously intended for the OS/2 subsys.
    10411039       The question is whether this still exists on Vista and W7. */
    1042     *ph2 = INVALID_HANDLE_VALUE;
     1040    *ph = pThis->Overlapped.hEvent;
    10431041    return VINF_SUCCESS;
    10441042}
     
    11271125 * @param   hPollSet            The poll set handle (for access checks).
    11281126 * @param   fEvents             The events we're polling for.
     1127 * @param   fFinalEntry         Set if this is the final entry for this handle
     1128 *                              in this poll set.  This can be used for dealing
     1129 *                              with duplicate entries.
    11291130 * @param   fNoWait             Set if it's a zero-wait poll call.  Clear if
    11301131 *                              we'll wait for an event to occur.
    11311132 */
    1132 uint32_t rtPipePollStart(RTPIPE hPipe, RTPOLLSET hPollSet, uint32_t fEvents, bool fNoWait)
     1133uint32_t rtPipePollStart(RTPIPE hPipe, RTPOLLSET hPollSet, uint32_t fEvents, bool fFinalEntry, bool fNoWait)
    11331134{
    11341135    /** @todo All this polling code could be optimized to make fewer system
     
    12071208 * @param   hPipe               The pipe handle.
    12081209 * @param   fEvents             The events we're polling for.
     1210 * @param   fFinalEntry         Set if this is the final entry for this handle
     1211 *                              in this poll set.  This can be used for dealing
     1212 *                              with duplicate entries.  Only keep in mind that
     1213 *                              this method is called in reverse order, so the
     1214 *                              first call will have this set (when the entire
     1215 *                              set was processed).
    12091216 */
    1210 uint32_t rtPipePollDone(RTPIPE hPipe, uint32_t fEvents)
     1217uint32_t rtPipePollDone(RTPIPE hPipe, uint32_t fEvents, bool fFinalEntry)
    12111218{
    12121219    RTPIPEINTERNAL *pThis = hPipe;
  • trunk/src/VBox/Runtime/r3/win/poll-win.cpp

    r27431 r27509  
    22/** @file
    33 * IPRT - Polling I/O Handles, Windows Implementation.
     4 *
     5 * @todo merge poll-win.cpp and poll-posix.cpp, there is lots of common code.
    46 */
    57
     
    4648#include <iprt/thread.h>
    4749#include <iprt/time.h>
     50
    4851#include "internal/pipe.h"
     52#define IPRT_INTERNAL_SOCKET_POLLING_ONLY
     53#include "internal/socket.h"
    4954#include "internal/magics.h"
    5055
     
    6469    /** The events we're waiting for here. */
    6570    uint32_t        fEvents;
     71    /** Set if this is the final entry for this handle.
     72     * If the handle is entered more than once, this will be clear for all but
     73     * the last entry. */
     74    bool            fFinalEntry;
    6675    /** The handle union. */
    6776    RTHANDLEUNION   u;
     
    123132        {
    124133            case RTHANDLETYPE_PIPE:
    125                 fEvents = rtPipePollStart(pThis->aHandles[i].u.hPipe, pThis, pThis->aHandles[i].fEvents, fNoWait);
     134                fEvents = rtPipePollStart(pThis->aHandles[i].u.hPipe, pThis, pThis->aHandles[i].fEvents,
     135                                          pThis->aHandles[i].fFinalEntry, fNoWait);
     136                break;
     137
     138            case RTHANDLETYPE_SOCKET:
     139                fEvents = rtSocketPollStart(pThis->aHandles[i].u.hSocket, pThis, pThis->aHandles[i].fEvents,
     140                                            pThis->aHandles[i].fFinalEntry, fNoWait);
    126141                break;
    127142
     
    155170                {
    156171                    case RTHANDLETYPE_PIPE:
    157                         rtPipePollDone(pThis->aHandles[i].u.hPipe, pThis->aHandles[i].fEvents);
     172                        rtPipePollDone(pThis->aHandles[i].u.hPipe, pThis->aHandles[i].fEvents,
     173                                       pThis->aHandles[i].fFinalEntry);
    158174                        break;
     175
     176                    case RTHANDLETYPE_SOCKET:
     177                        rtSocketPollDone(pThis->aHandles[i].u.hSocket, pThis->aHandles[i].fEvents,
     178                                         pThis->aHandles[i].fFinalEntry);
     179                        break;
     180
    159181                    default:
    160182                        AssertFailed();
     
    198220        {
    199221            case RTHANDLETYPE_PIPE:
    200                 fEvents = rtPipePollDone(pThis->aHandles[i].u.hPipe, pThis->aHandles[i].fEvents);
    201                 break;
     222                rtPipePollDone(pThis->aHandles[i].u.hPipe, pThis->aHandles[i].fEvents,
     223                               pThis->aHandles[i].fFinalEntry);
     224                break;
     225
     226            case RTHANDLETYPE_SOCKET:
     227                rtSocketPollDone(pThis->aHandles[i].u.hSocket, pThis->aHandles[i].fEvents,
     228                                 pThis->aHandles[i].fFinalEntry);
     229                break;
     230
    202231            default:
    203232                AssertFailed();
     
    230259     * Set the busy flag and do the job.
    231260     */
    232     AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true,  false), VERR_WRONG_ORDER);
     261    AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true,  false), VERR_CONCURRENT_ACCESS);
    233262
    234263    int rc;
     
    270299     * Set the busy flag and do the job.
    271300     */
    272     AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true,  false), VERR_WRONG_ORDER);
     301    AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true,  false), VERR_CONCURRENT_ACCESS);
    273302
    274303    int rc = rtPollNoResumeWorker(pThis, cMillies, pfEvents, pid);
     
    305334    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
    306335    AssertReturn(pThis->u32Magic == RTPOLLSET_MAGIC, VERR_INVALID_HANDLE);
    307     AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true,  false), VERR_WRONG_ORDER);
     336    AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true,  false), VERR_CONCURRENT_ACCESS);
    308337
    309338    ASMAtomicWriteU32(&pThis->u32Magic, ~RTPOLLSET_MAGIC);
     
    334363     * Set the busy flag and do the job.
    335364     */
    336     AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true,  false), VERR_WRONG_ORDER);
    337 
    338     int     rc       = VINF_SUCCESS;
    339     HANDLE  hNative  = INVALID_HANDLE_VALUE;
    340     HANDLE  hNative2 = INVALID_HANDLE_VALUE;
     365    AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true,  false), VERR_CONCURRENT_ACCESS);
     366
     367    int             rc       = VINF_SUCCESS;
     368    HANDLE          hNative  = INVALID_HANDLE_VALUE;
     369    RTHANDLEUNION   uh;
     370    uh.uInt = 0;
    341371    switch (pHandle->enmType)
    342372    {
    343373        case RTHANDLETYPE_PIPE:
    344             if (pHandle->u.hPipe != NIL_RTPIPE)
    345                 rc = rtPipePollGetHandles(pHandle->u.hPipe, fEvents, &hNative, &hNative2);
     374            uh.hPipe = pHandle->u.hPipe;
     375            if (uh.hPipe != NIL_RTPIPE)
     376                rc = rtPipePollGetHandle(uh.hPipe, fEvents, &hNative);
    346377            break;
    347378
    348379        case RTHANDLETYPE_SOCKET:
    349             if (pHandle->u.hSocket != NIL_RTSOCKET)
    350                 rc = VERR_NOT_IMPLEMENTED;
     380            uh.hSocket = pHandle->u.hSocket;
     381            if (uh.hSocket != NIL_RTSOCKET)
     382                rc = rtSocketPollGetHandle(uh.hSocket, fEvents, &hNative);
    351383            break;
    352384
     
    372404
    373405        /* Check that the handle ID doesn't exist already. */
    374         uint32_t j = i;
     406        uint32_t iPrev = UINT32_MAX;
     407        uint32_t j     = i;
    375408        while (j-- > 0)
     409        {
    376410            if (pThis->aHandles[j].id == id)
    377411            {
     
    379413                break;
    380414            }
     415            if (   pThis->aHandles[j].enmType == pHandle->enmType
     416                && pThis->aHandles[j].u.uInt  == uh.uInt)
     417                iPrev = j;
     418        }
    381419
    382420        /* Check that we won't overflow the poll set now. */
    383421        if (    RT_SUCCESS(rc)
    384             &&  i + 1 + (hNative2 != INVALID_HANDLE_VALUE) > RT_ELEMENTS(pThis->ahNative))
     422            &&  i + 1 > RT_ELEMENTS(pThis->ahNative))
    385423            rc = VERR_POLL_SET_IS_FULL;
    386424        if (RT_SUCCESS(rc))
    387425        {
    388426            /* Add the handles to the two parallel arrays. */
    389             pThis->ahNative[i]         = hNative;
    390             pThis->aHandles[i].enmType = pHandle->enmType;
    391             pThis->aHandles[i].u       = pHandle->u;
    392             pThis->aHandles[i].id      = id;
    393             pThis->aHandles[i].fEvents = fEvents;
    394             if (hNative2 == INVALID_HANDLE_VALUE)
    395                 pThis->cHandles = i + 1;
    396             else
     427            pThis->ahNative[i]             = hNative;
     428            pThis->aHandles[i].enmType     = pHandle->enmType;
     429            pThis->aHandles[i].u           = uh;
     430            pThis->aHandles[i].id          = id;
     431            pThis->aHandles[i].fEvents     = fEvents;
     432            pThis->aHandles[i].fFinalEntry = true;
     433            pThis->cHandles = i + 1;
     434
     435            if (iPrev != UINT32_MAX)
    397436            {
    398                 pThis->ahNative[i + 1] = hNative2;
    399                 pThis->aHandles[i + 1] = pThis->aHandles[i];
    400                 pThis->cHandles = i + 2;
     437                Assert(pThis->aHandles[i].fFinalEntry);
     438                pThis->aHandles[i].fFinalEntry = false;
    401439            }
    402440
     
    423461     * Set the busy flag and do the job.
    424462     */
    425     AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true,  false), VERR_WRONG_ORDER);
     463    AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true,  false), VERR_CONCURRENT_ACCESS);
    426464
    427465    int         rc = VERR_POLL_HANDLE_ID_NOT_FOUND;
     
    430468        if (pThis->aHandles[i].id == id)
    431469        {
     470            /* Save some details for the duplicate searching. */
     471            bool            fFinalEntry = pThis->aHandles[i].fFinalEntry;
     472            RTHANDLETYPE    enmType     = pThis->aHandles[i].enmType;
     473            RTHANDLEUNION   uh          = pThis->aHandles[i].u;
     474
     475            /* Remove the entry. */
    432476            pThis->cHandles--;
    433477            size_t const cToMove = pThis->cHandles - i;
     
    437481                memmove(&pThis->ahNative[i], &pThis->ahNative[i + 1], cToMove * sizeof(pThis->ahNative[i]));
    438482            }
     483
     484            /* Check for duplicate and set the fFinalEntry flag. */
     485            if (fFinalEntry)
     486                while (i-- > 0)
     487                    if (   pThis->aHandles[i].u.uInt  == uh.uInt
     488                        && pThis->aHandles[i].enmType == enmType)
     489                    {
     490                        Assert(!pThis->aHandles[i].fFinalEntry);
     491                        pThis->aHandles[i].fFinalEntry = true;
     492                        break;
     493                    }
     494
    439495            rc = VINF_SUCCESS;
     496            break;
    440497        }
    441498
     
    459516     * Set the busy flag and do the job.
    460517     */
    461     AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true,  false), VERR_WRONG_ORDER);
     518    AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true,  false), VERR_CONCURRENT_ACCESS);
    462519
    463520    int         rc = VERR_POLL_HANDLE_ID_NOT_FOUND;
     
    480537
    481538
    482 RTDECL(uint32_t) RTPollSetCount(RTPOLLSET hPollSet)
     539RTDECL(uint32_t) RTPollSetGetCount(RTPOLLSET hPollSet)
    483540{
    484541    /*
     
    499556}
    500557
    501 
Note: See TracChangeset for help on using the changeset viewer.

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