VirtualBox

Changeset 44487 in vbox


Ignore:
Timestamp:
Jan 31, 2013 12:37:42 PM (12 years ago)
Author:
vboxsync
Message:

IPRT: Poll on OS/2.

Location:
trunk/src/VBox/Runtime
Files:
1 deleted
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/Makefile.kmk

    r44472 r44487  
    477477        r3/isofs.cpp \
    478478        r3/path.cpp \
     479        r3/poll.cpp \
    479480        r3/process.cpp \
    480481        r3/socket.cpp \
     
    572573        r3/win/path-win.cpp \
    573574        r3/win/pipe-win.cpp \
    574         r3/poll.cpp \
    575575        r3/win/process-win.cpp \
    576576        r3/win/RTLogWriteDebugger-win.cpp \
     
    646646        r3/posix/RTPathUserDocuments-posix.cpp \
    647647        r3/posix/pipe-posix.cpp \
    648         r3/poll.cpp \
    649648        r3/posix/process-posix.cpp \
    650649        r3/posix/process-creation-posix.cpp \
     
    712711        r3/os2/mp-os2.cpp \
    713712        r3/os2/pipe-os2.cpp \
    714         r3/os2/poll-os2.cpp \
    715713        r3/os2/rtProcInitExePath-os2.cpp \
    716714        r3/os2/sched-os2.cpp \
     
    801799        r3/posix/path2-posix.cpp \
    802800        r3/posix/pipe-posix.cpp \
    803         r3/poll.cpp \
    804801        r3/posix/process-posix.cpp \
    805802        r3/posix/process-creation-posix.cpp \
     
    866863        r3/posix/RTPathUserDocuments-posix.cpp \
    867864        r3/posix/pipe-posix.cpp \
    868         r3/poll.cpp \
    869865        r3/posix/process-posix.cpp \
    870866        r3/posix/process-creation-posix.cpp \
     
    925921        r3/posix/RTPathUserDocuments-posix.cpp \
    926922        r3/posix/pipe-posix.cpp \
    927         r3/poll.cpp \
    928923        r3/posix/process-posix.cpp \
    929924        r3/posix/process-creation-posix.cpp \
     
    999994        r3/posix/pathhost-posix.cpp \
    1000995        r3/posix/pipe-posix.cpp \
    1001         r3/poll.cpp \
    1002996        r3/posix/process-posix.cpp \
    1003997        r3/posix/process-creation-posix.cpp \
  • trunk/src/VBox/Runtime/include/internal/pipe.h

    r44469 r44487  
    55
    66/*
    7  * Copyright (C) 2010 Oracle Corporation
     7 * Copyright (C) 2010-2013 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2929
    3030#include <iprt/pipe.h>
    31 /* Requires Windows.h on windows. */
    3231
    3332RT_C_DECLS_BEGIN
     
    4241 * @param   phNative            Where to put the primary handle.
    4342 */
    44 int rtPipePollGetHandle(RTPIPE hPipe, uint32_t fEvents, PRTHCINTPTR phNative);
     43int         rtPipePollGetHandle(RTPIPE hPipe, uint32_t fEvents, PRTHCINTPTR phNative);
    4544
    46 #ifdef RT_OS_WINDOWS
     45/**
     46 * Internal RTPoll helper that polls the pipe handle and, if @a fNoWait is
     47 * clear, starts whatever actions we've got running during the poll call.
     48 *
     49 * @returns 0 if no pending events, actions initiated if @a fNoWait is clear.
     50 *          Event mask (in @a fEvents) and no actions if the handle is ready
     51 *          already.
     52 *          UINT32_MAX (asserted) if the pipe handle is busy in I/O or a
     53 *          different poll set.
     54 *
     55 * @param   hPipe               The pipe handle.
     56 * @param   hPollSet            The poll set handle (for access checks).
     57 * @param   fEvents             The events we're polling for.
     58 * @param   fFinalEntry         Set if this is the final entry for this handle
     59 *                              in this poll set.  This can be used for dealing
     60 *                              with duplicate entries.
     61 * @param   fNoWait             Set if it's a zero-wait poll call.  Clear if
     62 *                              we'll wait for an event to occur.
     63 */
    4764uint32_t    rtPipePollStart(RTPIPE hPipe, RTPOLLSET hPollSet, uint32_t fEvents, bool fFinalEntry, bool fNoWait);
     65
     66/**
     67 * Called after a WaitForMultipleObjects returned in order to check for pending
     68 * events and stop whatever actions that rtPipePollStart() initiated.
     69 *
     70 * @returns Event mask or 0.
     71 *
     72 * @param   hPipe               The pipe handle.
     73 * @param   fEvents             The events we're polling for.
     74 * @param   fFinalEntry         Set if this is the final entry for this handle
     75 *                              in this poll set.  This can be used for dealing
     76 *                              with duplicate entries.  Only keep in mind that
     77 *                              this method is called in reverse order, so the
     78 *                              first call will have this set (when the entire
     79 *                              set was processed).
     80 * @param   fHarvestEvents      Set if we should check for pending events.
     81 */
    4882uint32_t    rtPipePollDone(RTPIPE hPipe, uint32_t fEvents, bool fFinalEntry, bool fHarvestEvents);
    49 #endif /* RT_OS_WINDOWS */
    5083
    5184RT_C_DECLS_END
  • trunk/src/VBox/Runtime/include/internal/socket.h

    r44469 r44487  
    6363
    6464int         rtSocketPollGetHandle(RTSOCKET hSocket, uint32_t fEvents, PRTHCINTPTR phNative);
    65 #ifdef RT_OS_WINDOWS
    6665uint32_t    rtSocketPollStart(RTSOCKET hSocket, RTPOLLSET hPollSet, uint32_t fEvents, bool fFinalEntry, bool fNoWait);
    6766uint32_t    rtSocketPollDone(RTSOCKET hSocket, uint32_t fEvents, bool fFinalEntry, bool fHarvestEvents);
    68 #endif /* RT_OS_WINDOWS */
    6967
    7068RT_C_DECLS_END
  • trunk/src/VBox/Runtime/r3/os2/pipe-os2.cpp

    r44462 r44487  
    763763    if (RT_FAILURE(rc))
    764764        return rc;
     765
    765766    rc = rtPipeOs2EnsureSem(pThis);
     767    if (RT_SUCCESS(rc) && cMillies > 0)
     768    {
     769        /* Stop polling attempts if we might block. */
     770        if (pThis->hPollSet == NIL_RTPOLLSET)
     771            pThis->hPollSet = (RTPOLLSET)(uintptr_t)0xbeef0042;
     772        else
     773            rc = VERR_WRONG_ORDER;
     774    }
    766775    if (RT_SUCCESS(rc))
    767776    {
     
    771780             * Check the handle state.
    772781             */
     782            APIRET orc;
     783            if (cMillies > 0)
     784            {
     785                ULONG ulIgnore;
     786                orc = DosResetEventSem(pThis->hev, &ulIgnore);
     787                AssertMsg(orc == NO_ERROR || orc == ERROR_ALREADY_RESET, ("%d\n", orc));
     788            }
     789
    773790            PIPESEMSTATE aStates[4]; RT_ZERO(aStates);
    774             APIRET orc = DosQueryNPipeSemState((HSEM)pThis->hev, &aStates[0], sizeof(aStates));
     791            orc = DosQueryNPipeSemState((HSEM)pThis->hev, &aStates[0], sizeof(aStates));
    775792            if (orc != NO_ERROR)
    776793            {
     
    789806            Assert(aStates[i].fStatus == NPSS_WSPACE || aStates[i].fStatus == NPSS_RDATA || aStates[i].fStatus == NPSS_EOI);
    790807            if (   aStates[i].fStatus != NPSS_EOI
    791                 && aStates[0].usAvail > 0)
     808                && aStates[i].usAvail > 0)
    792809                break;
    793810
     
    822839        if (rc == VERR_BROKEN_PIPE)
    823840            pThis->fBrokenPipe = true;
     841        if (cMillies > 0)
     842            pThis->hPollSet = NIL_RTPOLLSET;
    824843    }
    825844
     
    860879
    861880
    862 #if 0
    863 /**
    864  * Internal RTPollSetAdd helper that returns the handle that should be added to
    865  * the pollset.
    866  *
    867  * @returns Valid handle on success, INVALID_HANDLE_VALUE on failure.
    868  * @param   hPipe               The pipe handle.
    869  * @param   fEvents             The events we're polling for.
    870  * @param   ph                  where to put the primary handle.
    871  */
    872 int rtPipePollGetHandle(RTPIPE hPipe, uint32_t fEvents, PHANDLE ph)
     881int rtPipePollGetHandle(RTPIPE hPipe, uint32_t fEvents, PRTHCINTPTR phNative)
    873882{
    874883    RTPIPEINTERNAL *pThis = hPipe;
     
    876885    AssertReturn(pThis->u32Magic == RTPIPE_MAGIC, VERR_INVALID_HANDLE);
    877886
    878     AssertReturn(!(fEvents & RTPOLL_EVT_READ) || pThis->fRead, VERR_INVALID_PARAMETER);
     887    AssertReturn(!(fEvents & RTPOLL_EVT_READ)  || pThis->fRead, VERR_INVALID_PARAMETER);
    879888    AssertReturn(!(fEvents & RTPOLL_EVT_WRITE) || !pThis->fRead, VERR_INVALID_PARAMETER);
    880889
    881     /* Later: Try register an event handle with the pipe like on OS/2, there is
    882        a file control for doing this obviously intended for the OS/2 subsys.
    883        The question is whether this still exists on Vista and W7. */
    884     *ph = pThis->Overlapped.hEvent;
    885     return VINF_SUCCESS;
     890    int rc = RTCritSectEnter(&pThis->CritSect);
     891    if (RT_SUCCESS(rc))
     892    {
     893        rc = rtPipeOs2EnsureSem(pThis);
     894        if (RT_SUCCESS(rc))
     895            *phNative = (RTHCINTPTR)pThis->hev;
     896        RTCritSectLeave(&pThis->CritSect);
     897    }
     898    return rc;
    886899}
    887900
     
    893906 * @param   pThis               The pipe handle.
    894907 * @param   fEvents             The desired events.
     908 * @param   fResetEvtSem        Whether to reset the event semaphore.
    895909 */
    896 static uint32_t rtPipePollCheck(RTPIPEINTERNAL *pThis, uint32_t fEvents)
    897 {
     910static uint32_t rtPipePollCheck(RTPIPEINTERNAL *pThis, uint32_t fEvents, bool fResetEvtSem)
     911{
     912    /*
     913     * Reset the event semaphore if we're gonna wait.
     914     */
     915    APIRET orc;
     916    ULONG ulIgnore;
     917    if (fResetEvtSem)
     918    {
     919        orc = DosResetEventSem(pThis->hev, &ulIgnore);
     920        AssertMsg(orc == NO_ERROR || orc == ERROR_ALREADY_RESET, ("%d\n", orc));
     921    }
     922
     923    /*
     924     * Check for events.
     925     */
    898926    uint32_t fRetEvents = 0;
    899927    if (pThis->fBrokenPipe)
     
    901929    else if (pThis->fRead)
    902930    {
    903         if (!pThis->fIOPending)
    904         {
    905             DWORD cbAvailable;
    906             if (PeekNamedPipe(pThis->hPipe, NULL, 0, NULL, &cbAvailable, NULL))
    907             {
    908                 if (   (fEvents & RTPOLL_EVT_READ)
    909                     && cbAvailable > 0)
    910                     fRetEvents |= RTPOLL_EVT_READ;
    911             }
    912             else
    913             {
    914                 if (GetLastError() == ERROR_BROKEN_PIPE)
    915                     pThis->fBrokenPipe = true;
     931        ULONG       cbActual = 0;
     932        ULONG       ulState  = 0;
     933        AVAILDATA   Avail    = { 0, 0 };
     934        orc = DosPeekNPipe(pThis->hPipe, NULL, 0, &cbActual, &Avail, &ulState);
     935        if (orc != NO_ERROR)
     936        {
     937            fRetEvents |= RTPOLL_EVT_ERROR;
     938            if (orc == ERROR_BROKEN_PIPE || orc == ERROR_PIPE_NOT_CONNECTED)
     939                pThis->fBrokenPipe = true;
     940        }
     941        else if (Avail.cbpipe > 0)
     942            fRetEvents |= RTPOLL_EVT_READ;
     943        else if (ulState != NP_STATE_CONNECTED)
     944        {
     945            fRetEvents |= RTPOLL_EVT_ERROR;
     946            pThis->fBrokenPipe = true;
     947        }
     948    }
     949    else
     950    {
     951        PIPESEMSTATE aStates[4]; RT_ZERO(aStates);
     952        orc = DosQueryNPipeSemState((HSEM)pThis->hev, &aStates[0], sizeof(aStates));
     953        if (orc == NO_ERROR)
     954        {
     955            int i = 0;
     956            while (aStates[i].fStatus == NPSS_RDATA)
     957                i++;
     958            if (aStates[i].fStatus == NPSS_CLOSE)
     959            {
    916960                fRetEvents |= RTPOLL_EVT_ERROR;
    917             }
    918         }
    919     }
    920     else
    921     {
    922         if (pThis->fIOPending)
    923         {
    924             rtPipeWriteCheckCompletion(pThis);
    925             if (pThis->fBrokenPipe)
    926                 fRetEvents |= RTPOLL_EVT_ERROR;
    927         }
    928         if (   !pThis->fIOPending
    929             && !fRetEvents)
    930         {
    931             FILE_PIPE_LOCAL_INFORMATION Info;
    932             if (rtPipeQueryInfo(pThis, &Info))
    933             {
    934                 /* Check for broken pipe. */
    935                 if (Info.NamedPipeState == FILE_PIPE_CLOSING_STATE)
    936                 {
    937                     fRetEvents = RTPOLL_EVT_ERROR;
    938                     pThis->fBrokenPipe = true;
    939                 }
    940 
    941                 /* Check if there is available buffer space. */
    942                 if (   !fRetEvents
    943                     && (fEvents & RTPOLL_EVT_WRITE)
    944                     && (   Info.WriteQuotaAvailable > 0
    945                         || Info.OutboundQuota == 0)
    946                     )
    947                     fRetEvents |= RTPOLL_EVT_WRITE;
    948             }
    949             else if (fEvents & RTPOLL_EVT_WRITE)
     961                pThis->fBrokenPipe = true;
     962            }
     963            else if (   aStates[i].fStatus == NPSS_WSPACE
     964                     && aStates[i].usAvail > 0)
    950965                fRetEvents |= RTPOLL_EVT_WRITE;
    951966        }
    952     }
    953 
    954     return fRetEvents;
    955 }
    956 
    957 
    958 /**
    959  * Internal RTPoll helper that polls the pipe handle and, if @a fNoWait is
    960  * clear, starts whatever actions we've got running during the poll call.
    961  *
    962  * @returns 0 if no pending events, actions initiated if @a fNoWait is clear.
    963  *          Event mask (in @a fEvents) and no actions if the handle is ready
    964  *          already.
    965  *          UINT32_MAX (asserted) if the pipe handle is busy in I/O or a
    966  *          different poll set.
    967  *
    968  * @param   hPipe               The pipe handle.
    969  * @param   hPollSet            The poll set handle (for access checks).
    970  * @param   fEvents             The events we're polling for.
    971  * @param   fFinalEntry         Set if this is the final entry for this handle
    972  *                              in this poll set.  This can be used for dealing
    973  *                              with duplicate entries.
    974  * @param   fNoWait             Set if it's a zero-wait poll call.  Clear if
    975  *                              we'll wait for an event to occur.
    976  */
     967        else
     968        {
     969            fRetEvents |= RTPOLL_EVT_ERROR;
     970            if (orc == ERROR_BROKEN_PIPE || orc == ERROR_PIPE_NOT_CONNECTED)
     971                pThis->fBrokenPipe = true;
     972        }
     973    }
     974
     975    return fRetEvents & (fEvents | RTPOLL_EVT_ERROR);
     976}
     977
     978
    977979uint32_t rtPipePollStart(RTPIPE hPipe, RTPOLLSET hPollSet, uint32_t fEvents, bool fFinalEntry, bool fNoWait)
    978980{
    979     /** @todo All this polling code could be optimized to make fewer system
    980      *        calls; like for instance the ResetEvent calls. */
    981981    RTPIPEINTERNAL *pThis = hPipe;
    982982    AssertPtrReturn(pThis, UINT32_MAX);
     
    989989    uint32_t fRetEvents;
    990990    if (   pThis->cUsers   == 0
    991         || pThis->hPollSet == hPollSet)
    992     {
    993         /* Check what the current events are. */
    994         fRetEvents = rtPipePollCheck(pThis, fEvents);
    995         if (   !fRetEvents
    996             && !fNoWait)
    997         {
    998             /* Make sure the event semaphore has been reset. */
    999             if (!pThis->fIOPending)
    1000             {
    1001                 rc = ResetEvent(pThis->Overlapped.hEvent);
    1002                 Assert(rc == TRUE);
    1003             }
    1004 
    1005             /* Kick off the zero byte read thing if applicable. */
    1006             if (   !pThis->fIOPending
    1007                 && pThis->fRead
    1008                 && (fEvents & RTPOLL_EVT_READ)
    1009                )
    1010             {
    1011                 DWORD cbRead = 0;
    1012                 if (ReadFile(pThis->hPipe, pThis->abBuf, 0, &cbRead, &pThis->Overlapped))
    1013                     fRetEvents = rtPipePollCheck(pThis, fEvents);
    1014                 else if (GetLastError() == ERROR_IO_PENDING)
    1015                 {
    1016                     pThis->fIOPending    = true;
    1017                     pThis->fZeroByteRead = true;
    1018                 }
    1019                 else
    1020                     fRetEvents = RTPOLL_EVT_ERROR;
    1021             }
    1022 
    1023             /* If we're still set for the waiting, record the poll set and
    1024                mark the pipe used. */
    1025             if (!fRetEvents)
    1026             {
    1027                 pThis->cUsers++;
    1028                 pThis->hPollSet = hPollSet;
    1029             }
     991        || pThis->hPollSet == NIL_RTPOLLSET)
     992    {
     993        fRetEvents = rtPipePollCheck(pThis, fEvents, fNoWait);
     994        if (!fRetEvents && !fNoWait)
     995        {
     996            /* Mark the set busy while waiting. */
     997            pThis->cUsers++;
     998            pThis->hPollSet = hPollSet;
    1030999        }
    10311000    }
     
    10411010
    10421011
    1043 /**
    1044  * Called after a WaitForMultipleObjects returned in order to check for pending
    1045  * events and stop whatever actions that rtPipePollStart() initiated.
    1046  *
    1047  * @returns Event mask or 0.
    1048  *
    1049  * @param   hPipe               The pipe handle.
    1050  * @param   fEvents             The events we're polling for.
    1051  * @param   fFinalEntry         Set if this is the final entry for this handle
    1052  *                              in this poll set.  This can be used for dealing
    1053  *                              with duplicate entries.  Only keep in mind that
    1054  *                              this method is called in reverse order, so the
    1055  *                              first call will have this set (when the entire
    1056  *                              set was processed).
    1057  * @param   fHarvestEvents      Set if we should check for pending events.
    1058  */
    10591012uint32_t rtPipePollDone(RTPIPE hPipe, uint32_t fEvents, bool fFinalEntry, bool fHarvestEvents)
    10601013{
     
    10681021    Assert(pThis->cUsers > 0);
    10691022
    1070 
    1071     /* Cancel the zero byte read. */
    1072     uint32_t fRetEvents = 0;
    1073     if (pThis->fZeroByteRead)
    1074     {
    1075         CancelIo(pThis->hPipe);
    1076         DWORD cbRead = 0;
    1077         if (   !GetOverlappedResult(pThis->hPipe, &pThis->Overlapped, &cbRead, TRUE /*fWait*/)
    1078             && GetLastError() != ERROR_OPERATION_ABORTED)
    1079             fRetEvents = RTPOLL_EVT_ERROR;
    1080 
    1081         pThis->fIOPending    = false;
    1082         pThis->fZeroByteRead = false;
    1083     }
    1084 
    10851023    /* harvest events. */
    1086     fRetEvents |= rtPipePollCheck(pThis, fEvents);
     1024    uint32_t fRetEvents = rtPipePollCheck(pThis, fEvents, false);
    10871025
    10881026    /* update counters. */
    10891027    pThis->cUsers--;
    1090     if (!pThis->cUsers)
    1091         pThis->hPollSet = NIL_RTPOLLSET;
     1028    pThis->hPollSet = NIL_RTPOLLSET;
    10921029
    10931030    RTCritSectLeave(&pThis->CritSect);
    10941031    return fRetEvents;
    10951032}
    1096 #endif
  • trunk/src/VBox/Runtime/r3/poll.cpp

    r44472 r44487  
    3232#ifdef RT_OS_WINDOWS
    3333# include <Windows.h>
     34
     35#elif defined(RT_OS_OS2)
     36# define INCL_BASE
     37# include <os2.h>
     38# include <limits.h>
     39# include <sys/socket.h>
     40
    3441#else
    3542# include <limits.h>
     
    4148#include "internal/iprt.h"
    4249
     50#include <iprt/alloca.h>
    4351#include <iprt/asm.h>
    4452#include <iprt/assert.h>
     
    102110    bool volatile       fBusy;
    103111
     112    /** The number of allocated handles. */
     113    uint16_t            cHandlesAllocated;
    104114    /** The number of valid handles in the set. */
    105     uint32_t            cHandles;
    106     /** The number of allocated handles. */
    107     uint32_t            cHandlesAllocated;
     115    uint16_t            cHandles;
    108116
    109117#ifdef RT_OS_WINDOWS
    110118    /** Pointer to an array of native handles. */
    111119    HANDLE             *pahNative;
     120#elif defined(RT_OS_OS2)
     121    /** The semaphore records. */
     122    PSEMRECORD          paSemRecs;
     123    /** The multiple wait semaphore used for non-socket waits. */
     124    HMUX                hmux;
     125    /** os2_select template. */
     126    int                *pafdSelect;
     127    /** The number of sockets to monitor for read. */
     128    uint16_t            cReadSockets;
     129    /** The number of sockets to monitor for write. */
     130    uint16_t            cWriteSockets;
     131    /** The number of sockets to monitor for exceptions. */
     132    uint16_t            cXcptSockets;
     133    /** The number of pipes. */
     134    uint16_t            cPipes;
     135    /** Pointer to an array of native handles. */
     136    PRTHCINTPTR         pahNative;
    112137#else
    113138    /** Pointer to an array of pollfd structures. */
     
    115140#endif
    116141    /** Pointer to an array of handles and IDs. */
    117     RTPOLLSETHNDENT    *paHandles;
     142    PRTPOLLSETHNDENT    paHandles;
    118143} RTPOLLSETINTERNAL;
    119144
     
    123148 * Common worker for RTPoll and RTPollNoResume
    124149 */
    125 static int rtPollNoResumeWorker(RTPOLLSETINTERNAL *pThis, RTMSINTERVAL cMillies, uint32_t *pfEvents, uint32_t *pid)
     150static int rtPollNoResumeWorker(RTPOLLSETINTERNAL *pThis, uint64_t MsStart, RTMSINTERVAL cMillies,
     151                                uint32_t *pfEvents, uint32_t *pid)
    126152{
    127153    int rc;
     
    142168    }
    143169
    144 #ifdef RT_OS_WINDOWS
     170#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
    145171    /*
    146172     * Check + prepare the handles before waiting.
     
    210236    }
    211237
     238
    212239    /*
    213240     * Wait.
    214241     */
     242# ifdef RT_OS_WINDOWS
    215243    DWORD dwRc = WaitForMultipleObjectsEx(cHandles, pThis->pahNative,
    216244                                          FALSE /*fWaitAll */,
     
    231259        rc = VERR_INTERNAL_ERROR_5;
    232260    }
     261
     262# else  /* RT_OS_OS2 */
     263    APIRET      orc;
     264    ULONG       ulUser   = 0;
     265    uint16_t    cSockets = pThis->cReadSockets + pThis->cWriteSockets + pThis->cXcptSockets;
     266    if (cSockets == 0)
     267    {
     268        /* Only pipes. */
     269        AssertReturn(pThis->cPipes > 0, VERR_INTERNAL_ERROR_2);
     270        orc = DosWaitMuxWaitSem(pThis->hmux,
     271                                cMillies == RT_INDEFINITE_WAIT ? SEM_INDEFINITE_WAIT : RT_MIN(cMillies, SEM_INDEFINITE_WAIT - 1),
     272                                &ulUser);
     273        rc = RTErrConvertFromOS2(orc);
     274    }
     275    else
     276    {
     277        int *pafdSelect = (int *)alloca(cSockets + 1);
     278        if (pThis->cPipes == 0)
     279        {
     280            /* Only sockets. */
     281            memcpy(pafdSelect, pThis->pafdSelect, sizeof(pThis->pafdSelect[0]) * (cSockets + 1));
     282            rc = os2_select(pafdSelect, pThis->cReadSockets, pThis->cWriteSockets, pThis->cXcptSockets,
     283                            cMillies == RT_INDEFINITE_WAIT ? -1 : (long)RT_MIN(cMillies, LONG_MAX));
     284            if (rc > 0)
     285                rc = VINF_SUCCESS;
     286            else if (rc == 0)
     287                rc = VERR_TIMEOUT;
     288            else
     289                rc = RTErrConvertFromErrno(sock_errno());
     290        }
     291        else
     292        {
     293            /* Mix of both - taking the easy way out, not optimal, but whatever... */
     294            do
     295            {
     296                orc = DosWaitMuxWaitSem(pThis->hmux, 8, &ulUser);
     297                if (orc != ERROR_TIMEOUT && orc != ERROR_SEM_TIMEOUT)
     298                {
     299                    rc = RTErrConvertFromOS2(orc);
     300                    break;
     301                }
     302
     303                memcpy(pafdSelect, pThis->pafdSelect, sizeof(pThis->pafdSelect[0]) * (cSockets + 1));
     304                rc = os2_select(pafdSelect, pThis->cReadSockets, pThis->cWriteSockets, pThis->cXcptSockets, 8);
     305                if (rc != 0)
     306                {
     307                    if (rc > 0)
     308                        rc = VINF_SUCCESS;
     309                    else
     310                        rc = RTErrConvertFromErrno(sock_errno());
     311                    break;
     312                }
     313            } while (cMillies == RT_INDEFINITE_WAIT || RTTimeMilliTS() - MsStart < cMillies);
     314        }
     315    }
     316# endif /* RT_OS_OS2 */
    233317
    234318    /*
     
    362446    if (cMillies == RT_INDEFINITE_WAIT || cMillies == 0)
    363447    {
    364         do rc = rtPollNoResumeWorker(pThis, cMillies, pfEvents, pid);
     448        do rc = rtPollNoResumeWorker(pThis, 0, cMillies, pfEvents, pid);
    365449        while (rc == VERR_INTERRUPTED);
    366450    }
     
    368452    {
    369453        uint64_t MsStart = RTTimeMilliTS();
    370         rc = rtPollNoResumeWorker(pThis, cMillies, pfEvents, pid);
     454        rc = rtPollNoResumeWorker(pThis, MsStart, cMillies, pfEvents, pid);
    371455        while (RT_UNLIKELY(rc == VERR_INTERRUPTED))
    372456        {
     
    376460                break;
    377461            }
    378             rc = rtPollNoResumeWorker(pThis, cMillies, pfEvents, pid);
     462            rc = rtPollNoResumeWorker(pThis, MsStart, cMillies, pfEvents, pid);
    379463        }
    380464    }
     
    399483    AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true,  false), VERR_CONCURRENT_ACCESS);
    400484
    401     int rc = rtPollNoResumeWorker(pThis, cMillies, pfEvents, pid);
     485    int rc;
     486    if (cMillies == RT_INDEFINITE_WAIT || cMillies == 0)
     487        rc = rtPollNoResumeWorker(pThis, 0, cMillies, pfEvents, pid);
     488    else
     489        rc = rtPollNoResumeWorker(pThis, RTTimeMilliTS(), cMillies, pfEvents, pid);
    402490
    403491    ASMAtomicWriteBool(&pThis->fBusy, false);
     
    414502        return VERR_NO_MEMORY;
    415503
    416     pThis->u32Magic             = RTPOLLSET_MAGIC;
    417504    pThis->fBusy                = false;
    418505    pThis->cHandles             = 0;
     
    420507#ifdef RT_OS_WINDOWS
    421508    pThis->pahNative            = NULL;
     509#elif defined(RT_OS_OS2)
     510    pThis->hmux                 = NULLHANDLE;
     511    APIRET orc = DosCreateMuxWaitSem(NULL, &pThis->hmux, 0, NULL, DCMW_WAIT_ANY);
     512    if (orc != NO_ERROR)
     513    {
     514        RTMemFree(pThis);
     515        return RTErrConvertFromOS2(orc);
     516    }
     517    pThis->pafdSelect           = NULL;
     518    pThis->cReadSockets           = 0;
     519    pThis->cWriteSockets          = 0;
     520    pThis->cXcptSockets           = 0;
     521    pThis->cPipes               = 0;
     522    pThis->pahNative            = NULL;
    422523#else
    423524    pThis->paPollFds            = NULL;
    424525#endif
    425526    pThis->paHandles            = NULL;
     527    pThis->u32Magic             = RTPOLLSET_MAGIC;
    426528
    427529    *phPollSet = pThis;
     
    441543    ASMAtomicWriteU32(&pThis->u32Magic, ~RTPOLLSET_MAGIC);
    442544#ifdef RT_OS_WINDOWS
     545    RTMemFree(pThis->pahNative);
     546    pThis->pahNative = NULL;
     547#elif defined(RT_OS_OS2)
     548    DosCloseMuxWaitSem(pThis->hmux);
     549    pThis->hmux = NULLHANDLE;
     550    RTMemFree(pThis->pafdSelect);
     551    pThis->pafdSelect = NULL;
    443552    RTMemFree(pThis->pahNative);
    444553    pThis->pahNative = NULL;
     
    454563}
    455564
     565#ifdef RT_OS_OS2
     566
     567/**
     568 * Checks if @a fd is in the specific socket subset.
     569 *
     570 * @returns true / false.
     571 * @param   pThis       The poll set instance.
     572 * @param   iStart      The index to start at.
     573 * @param   cFds        The number of sockets to check.
     574 * @param   fd          The socket to look for.
     575 */
     576static bool rtPollSetOs2IsSocketInSet(RTPOLLSETINTERNAL *pThis, uint16_t iStart, uint16_t cFds, int fd)
     577{
     578    int const *pfd = pThis->pafdSelect + iStart;
     579    while (cFds-- > 0)
     580    {
     581        if (*pfd == fd)
     582            return true;
     583        pfd++;
     584    }
     585    return false;
     586}
     587
     588
     589/**
     590 * Removes a socket from a select template subset.
     591 *
     592 * @param   pThis       The poll set instance.
     593 * @param   iStart      The index to start at.
     594 * @param   pcSubSet    The subset counter to decrement.
     595 * @param   fd          The socket to remove.
     596 */
     597static void rtPollSetOs2RemoveSocket(RTPOLLSETINTERNAL *pThis, uint16_t iStart, uint16_t *pcFds, int fd)
     598{
     599    uint16_t cFds = *pcFds;
     600    while (cFds-- > 0)
     601    {
     602        if (pThis->pafdSelect[iStart] == fd)
     603            break;
     604        iStart++;
     605    }
     606    AssertReturnVoid(iStart != UINT16_MAX);
     607
     608    /* Note! We keep a -1 entry at the end of the set, thus the + 1. */
     609    memmove(&pThis->pafdSelect[iStart],
     610            &pThis->pafdSelect[iStart + 1],
     611            pThis->cReadSockets + pThis->cWriteSockets + pThis->cXcptSockets + 1 - 1 - iStart);
     612    *pcFds -= 1;
     613
     614    Assert(pThis->pafdSelect[pThis->cReadSockets + pThis->cWriteSockets + pThis->cXcptSockets] == -1);
     615}
     616
     617
     618/**
     619 * Adds a socket to a select template subset.
     620 *
     621 * @param   pThis       The poll set instance.
     622 * @param   iInsert     The insertion point.
     623 *                      ASSUMED to be at the end of the subset.
     624 * @param   pcSubSet    The subset counter to increment.
     625 * @param   fd          The socket to add.
     626 */
     627static void rtPollSetOs2AddSocket(RTPOLLSETINTERNAL *pThis, uint16_t iInsert, uint16_t *pcFds, int fd)
     628{
     629    Assert(!rtPollSetOs2IsSocketInSet(pThis, iInsert - *pcFds, *pcFds, fd));
     630
     631    /* Note! We keep a -1 entry at the end of the set, thus the + 1. */
     632    memmove(&pThis->pafdSelect[iInsert + 1],
     633            &pThis->pafdSelect[iInsert],
     634            pThis->cReadSockets + pThis->cWriteSockets + pThis->cXcptSockets + 1 - iInsert);
     635    pThis->pafdSelect[iInsert] = fd;
     636    *pcFds += 1;
     637
     638    Assert(pThis->pafdSelect[pThis->cReadSockets + pThis->cWriteSockets + pThis->cXcptSockets] == -1);
     639}
     640
     641
     642/**
     643 * OS/2 specific RTPollSetAdd worker.
     644 *
     645 * @returns IPRT status code.
     646 * @param   pThis       The poll set instance.
     647 * @param   i           The index of the new handle (not committed).
     648 * @param   fEvents     The events to poll for.
     649 */
     650static int rtPollSetOs2Add(RTPOLLSETINTERNAL *pThis, unsigned i, uint32_t fEvents)
     651{
     652    if (pThis->paHandles[i].enmType == RTHANDLETYPE_SOCKET)
     653    {
     654        int const fdSocket = pThis->pahNative[i];
     655        if (   (fEvents & RTPOLL_EVT_READ)
     656            && rtPollSetOs2IsSocketInSet(pThis, 0, pThis->cReadSockets, fdSocket))
     657            rtPollSetOs2AddSocket(pThis, pThis->cReadSockets, &pThis->cReadSockets, fdSocket);
     658
     659        if (   (fEvents & RTPOLL_EVT_WRITE)
     660            && rtPollSetOs2IsSocketInSet(pThis, pThis->cReadSockets, pThis->cWriteSockets, fdSocket))
     661            rtPollSetOs2AddSocket(pThis, pThis->cReadSockets + pThis->cWriteSockets, &pThis->cWriteSockets, fdSocket);
     662
     663        if (   (fEvents & RTPOLL_EVT_ERROR)
     664            && rtPollSetOs2IsSocketInSet(pThis, pThis->cReadSockets + pThis->cWriteSockets, pThis->cXcptSockets, fdSocket))
     665            rtPollSetOs2AddSocket(pThis, pThis->cReadSockets + pThis->cWriteSockets + pThis->cXcptSockets,
     666                                  &pThis->cXcptSockets, fdSocket);
     667    }
     668    else if (pThis->paHandles[i].enmType == RTHANDLETYPE_PIPE)
     669    {
     670        SEMRECORD Rec = { (HSEM)pThis->pahNative[i], pThis->paHandles[i].id };
     671        APIRET orc = DosAddMuxWaitSem(pThis->hmux, &Rec);
     672        if (orc != NO_ERROR && orc != ERROR_DUPLICATE_HANDLE)
     673            return RTErrConvertFromOS2(orc);
     674        pThis->cPipes++;
     675    }
     676    else
     677        AssertFailedReturn(VERR_INTERNAL_ERROR_2);
     678    return VINF_SUCCESS;
     679}
     680
     681#endif /* RT_OS_OS2 */
     682
     683/**
     684 * Grows the poll set.
     685 *
     686 * @returns VINF_SUCCESS or VERR_NO_MEMORY.
     687 * @param   pThis               The poll set instance.
     688 * @param   cHandlesNew         The new poll set size.
     689 */
     690static int rtPollSetGrow(RTPOLLSETINTERNAL *pThis, uint32_t cHandlesNew)
     691{
     692    Assert(cHandlesNew > pThis->cHandlesAllocated);
     693
     694    /* The common array. */
     695    void *pvNew = RTMemRealloc(pThis->paHandles, cHandlesNew * sizeof(pThis->paHandles[0]));
     696    if (!pvNew)
     697        return VERR_NO_MEMORY;
     698    pThis->paHandles = (PRTPOLLSETHNDENT)pvNew;
     699
     700
     701    /* OS specific handles */
     702#if defined(RT_OS_WINDOWS)
     703    pvNew = RTMemRealloc(pThis->pahNative, cHandlesNew * sizeof(pThis->pahNative[0]));
     704    if (!pvNew)
     705        return VERR_NO_MEMORY;
     706    pThis->pahNative  = (HANDLE *)pvNew;
     707
     708#elif defined(RT_OS_OS2)
     709    pvNew = RTMemRealloc(pThis->pahNative, cHandlesNew * sizeof(pThis->pahNative[0]));
     710    if (!pvNew)
     711        return VERR_NO_MEMORY;
     712    pThis->pahNative  = (PRTHCINTPTR)pvNew;
     713
     714    pvNew = RTMemRealloc(pThis->pafdSelect, (cHandlesNew * 3 + 1) * sizeof(pThis->pafdSelect[0]));
     715    if (!pvNew)
     716        return VERR_NO_MEMORY;
     717    pThis->pafdSelect  = (int *)pvNew;
     718    if (pThis->cHandlesAllocated == 0)
     719        pThis->pafdSelect[0] = -1;
     720
     721#else
     722    pvNew = RTMemRealloc(pThis->paPollFds, cHandlesNew * sizeof(pThis->paPollFds[0]));
     723    if (!pvNew)
     724        return VERR_NO_MEMORY;
     725    pThis->paPollFds  = (struct pollfd *)pvNew;
     726
     727#endif
     728
     729    pThis->cHandlesAllocated = (uint16_t)cHandlesNew;
     730    return VINF_SUCCESS;
     731}
     732
    456733
    457734RTDECL(int) RTPollSetAdd(RTPOLLSET hPollSet, PCRTHANDLE pHandle, uint32_t fEvents, uint32_t id)
     
    539816        /* Grow the tables if necessary. */
    540817        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 
     818            rc = rtPollSetGrow(pThis, pThis->cHandlesAllocated + 32);
    569819        if (RT_SUCCESS(rc))
    570820        {
    571             /* Add the handles to the two parallel arrays. */
     821            /*
     822             * Add the handles to the two parallel arrays.
     823             */
    572824#ifdef RT_OS_WINDOWS
    573             pThis->pahNative[i]            = (HANDLE)hNative;
     825            pThis->pahNative[i]             = (HANDLE)hNative;
     826#elif defined(RT_OS_OS2)
     827            pThis->pahNative[i]             = hNative;
    574828#else
    575             pThis->paPollFds[i].fd         = (int)hNative;
    576             pThis->paPollFds[i].revents = 0;
    577             pThis->paPollFds[i].events  = 0;
     829            pThis->paPollFds[i].fd          = (int)hNative;
     830            pThis->paPollFds[i].revents     = 0;
     831            pThis->paPollFds[i].events      = 0;
    578832            if (fEvents & RTPOLL_EVT_READ)
    579833                pThis->paPollFds[i].events |= POLLIN;
     
    595849            }
    596850
    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
     851            /*
     852             * Validations and OS specific updates.
     853             */
     854#ifdef RT_OS_WINDOWS
     855            /* none */
     856#elif defined(RT_OS_OS2)
     857            rc = rtPollSetOs2Add(pThis, i, fEvents);
     858#else  /* POSIX */
     859            if (poll(&pThis->paPollFds[i], 1, 0) < 0)
    607860            {
    608861                rc = RTErrConvertFromErrno(errno);
    609862                pThis->paPollFds[i].fd = -1;
    610863            }
    611 #endif
     864#endif /* POSIX */
    612865
    613866            if (RT_SUCCESS(rc))
    614867            {
    615                 /* Commit */
    616                 pThis->cHandles = i + 1;
     868                /*
     869                 * Commit it to the set.
     870                 */
     871                pThis->cHandles++; Assert(pThis->cHandles == i + 1);
    617872                rc = VINF_SUCCESS;
    618873            }
     
    646901        {
    647902            /* Save some details for the duplicate searching. */
    648             bool            fFinalEntry = pThis->paHandles[i].fFinalEntry;
    649             RTHANDLETYPE    enmType     = pThis->paHandles[i].enmType;
    650             RTHANDLEUNION   uh          = pThis->paHandles[i].u;
     903            bool const          fFinalEntry     = pThis->paHandles[i].fFinalEntry;
     904            RTHANDLETYPE const  enmType         = pThis->paHandles[i].enmType;
     905            RTHANDLEUNION const uh              = pThis->paHandles[i].u;
     906#ifdef RT_OS_OS2
     907            uint32_t            fRemovedEvents  = pThis->paHandles[i].fEvents;
     908            RTHCINTPTR const    hNative         = pThis->pahNative[i];
     909#endif
    651910
    652911            /* Remove the entry. */
     
    656915            {
    657916                memmove(&pThis->paHandles[i], &pThis->paHandles[i + 1], cToMove * sizeof(pThis->paHandles[i]));
    658 #ifdef RT_OS_WINDOWS
     917#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
    659918                memmove(&pThis->pahNative[i], &pThis->pahNative[i + 1], cToMove * sizeof(pThis->pahNative[i]));
    660919#else
     
    674933                    }
    675934
     935#ifdef RT_OS_OS2
     936            /*
     937             * Update OS/2 wait structures.
     938             */
     939            uint32_t fNewEvents = 0;
     940            i = pThis->cHandles;
     941            while (i-- > 0)
     942                if (   pThis->paHandles[i].u.uInt  == uh.uInt
     943                    && pThis->paHandles[i].enmType == enmType)
     944                    fNewEvents |= pThis->paHandles[i].fEvents;
     945            if (enmType == RTHANDLETYPE_PIPE)
     946            {
     947                pThis->cPipes--;
     948                if (fNewEvents == 0)
     949                {
     950                    APIRET orc = DosDeleteMuxWaitSem(pThis->hmux, (HSEM)hNative);
     951                    AssertMsg(orc == NO_ERROR, ("%d\n", orc));
     952                }
     953            }
     954            else if (   fNewEvents != (fNewEvents | fRemovedEvents)
     955                     && enmType == RTHANDLETYPE_SOCKET)
     956            {
     957                fRemovedEvents = fNewEvents ^ (fNewEvents | fRemovedEvents);
     958                if (fRemovedEvents & RTPOLL_EVT_ERROR)
     959                    rtPollSetOs2RemoveSocket(pThis, pThis->cReadSockets + pThis->cWriteSockets, &pThis->cXcptSockets, (int)hNative);
     960                if (fRemovedEvents & RTPOLL_EVT_WRITE)
     961                    rtPollSetOs2RemoveSocket(pThis, pThis->cReadSockets, &pThis->cWriteSockets, (int)hNative);
     962                if (fRemovedEvents & RTPOLL_EVT_READ)
     963                    rtPollSetOs2RemoveSocket(pThis, 0, &pThis->cReadSockets, (int)hNative);
     964            }
     965#endif /* RT_OS_OS2 */
    676966            rc = VINF_SUCCESS;
    677967            break;
     
    7591049        if (pThis->paHandles[i].id == id)
    7601050        {
    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;
     1051            if (pThis->paHandles[i].fEvents != fEvents)
     1052            {
     1053#if defined(RT_OS_WINDOWS)
     1054                /*nothing*/
     1055#elif defined(RT_OS_OS2)
     1056                if (pThis->paHandles[i].enmType == RTHANDLETYPE_SOCKET)
     1057                {
     1058                    uint32_t fOldEvents = 0;
     1059                    uint32_t j          = pThis->cHandles;
     1060                    while (j-- > 0)
     1061                        if (   pThis->paHandles[j].enmType == RTHANDLETYPE_SOCKET
     1062                            && pThis->paHandles[j].u.uInt  == pThis->paHandles[i].u.uInt
     1063                            && j != i)
     1064                            fOldEvents |= pThis->paHandles[j].fEvents;
     1065                    uint32_t fNewEvents = fOldEvents | fEvents;
     1066                    fOldEvents |= pThis->paHandles[i].fEvents;
     1067                    if (fOldEvents != fEvents)
     1068                    {
     1069                        int const       fdSocket = pThis->pahNative[i];
     1070                        uint32_t const  fChangedEvents = fOldEvents ^ fNewEvents;
     1071
     1072                        if ((fChangedEvents & RTPOLL_EVT_READ) && (fNewEvents & RTPOLL_EVT_READ))
     1073                            rtPollSetOs2AddSocket(pThis, pThis->cReadSockets, &pThis->cReadSockets, fdSocket);
     1074                        else if (fChangedEvents & RTPOLL_EVT_READ)
     1075                            rtPollSetOs2RemoveSocket(pThis, 0, &pThis->cReadSockets, fdSocket);
     1076
     1077                        if ((fChangedEvents & RTPOLL_EVT_WRITE) && (fNewEvents & RTPOLL_EVT_WRITE))
     1078                            rtPollSetOs2AddSocket(pThis, pThis->cReadSockets + pThis->cWriteSockets,
     1079                                                  &pThis->cWriteSockets, fdSocket);
     1080                        else if (fChangedEvents & RTPOLL_EVT_WRITE)
     1081                            rtPollSetOs2RemoveSocket(pThis, pThis->cReadSockets, &pThis->cWriteSockets, fdSocket);
     1082
     1083                        if ((fChangedEvents & RTPOLL_EVT_ERROR) && (fNewEvents & RTPOLL_EVT_ERROR))
     1084                            rtPollSetOs2AddSocket(pThis, pThis->cReadSockets + pThis->cWriteSockets + pThis->cXcptSockets,
     1085                                                  &pThis->cXcptSockets, fdSocket);
     1086                        else if (fChangedEvents & RTPOLL_EVT_ERROR)
     1087                            rtPollSetOs2RemoveSocket(pThis, pThis->cReadSockets + pThis->cWriteSockets, &pThis->cXcptSockets,
     1088                                                     fdSocket);
     1089                    }
     1090                }
     1091#else
     1092                pThis->paPollFds[i].events  = 0;
     1093                if (fEvents & RTPOLL_EVT_READ)
     1094                    pThis->paPollFds[i].events |= POLLIN;
     1095                if (fEvents & RTPOLL_EVT_WRITE)
     1096                    pThis->paPollFds[i].events |= POLLOUT;
     1097                if (fEvents & RTPOLL_EVT_ERROR)
     1098                    pThis->paPollFds[i].events |= POLLERR;
    7701099#endif
     1100                pThis->paHandles[i].fEvents = fEvents;
     1101            }
    7711102            rc = VINF_SUCCESS;
    7721103            break;
  • trunk/src/VBox/Runtime/r3/socket.cpp

    r44469 r44487  
    146146     * currently. */
    147147    bool                fBlocking;
     148#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
     149    /** The pollset currently polling this socket.  This is NIL if no one is
     150     * polling. */
     151    RTPOLLSET           hPollSet;
     152#endif
    148153#ifdef RT_OS_WINDOWS
    149154    /** The event semaphore we've associated with the socket handle.
    150155     * This is WSA_INVALID_EVENT if not done. */
    151156    WSAEVENT            hEvent;
    152     /** The pollset currently polling this socket.  This is NIL if no one is
    153      * polling. */
    154     RTPOLLSET           hPollSet;
    155157    /** The events we're polling for. */
    156158    uint32_t            fPollEvts;
     
    408410    pThis->fClosed          = false;
    409411    pThis->fBlocking        = true;
     412#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
     413    pThis->hPollSet         = NIL_RTPOLLSET;
     414#endif
    410415#ifdef RT_OS_WINDOWS
    411416    pThis->hEvent           = WSA_INVALID_EVENT;
    412     pThis->hPollSet         = NIL_RTPOLLSET;
    413417    pThis->fPollEvts        = 0;
    414418    pThis->fSubscribedEvts  = 0;
     
    18781882}
    18791883
     1884#endif  /* RT_OS_WINDOWS */
     1885
     1886
     1887#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
    18801888
    18811889/**
     
    18881896static uint32_t rtSocketPollCheck(RTSOCKETINT *pThis, uint32_t fEvents)
    18891897{
    1890     int         rc         = VINF_SUCCESS;
    1891     uint32_t    fRetEvents = 0;
     1898    uint32_t fRetEvents = 0;
    18921899
    18931900    LogFlowFunc(("pThis=%#p fEvents=%#x\n", pThis, fEvents));
    18941901
     1902# ifdef RT_OS_WINDOWS
    18951903    /* Make sure WSAEnumNetworkEvents returns what we want. */
     1904    int rc = VINF_SUCCESS;
    18961905    if ((pThis->fSubscribedEvts & fEvents) != fEvents)
    18971906        rc = rtSocketPollUpdateEvents(pThis, pThis->fSubscribedEvts | fEvents);
     
    19291938    if (RT_FAILURE(rc))
    19301939    {
    1931         /** @todo  */
    1932     }
     1940
     1941    }
     1942
     1943#else  /* RT_OS_OS2 */
     1944    int aFds[4] = { pThis->hNative, pThis->hNative, pThis->hNative, -1 };
     1945    int rc = os2_select(aFds, 1, 1, 1, 0);
     1946    if (rc > 0)
     1947    {
     1948        if (aFds[0] == pThis->hNative)
     1949            fRetEvents |= RTPOLL_EVT_READ;
     1950        if (aFds[1] == pThis->hNative)
     1951            fRetEvents |= RTPOLL_EVT_WRITE;
     1952        if (aFds[2] == pThis->hNative)
     1953            fRetEvents |= RTPOLL_EVT_ERROR;
     1954        fRetEvents &= fEvents;
     1955    }
     1956#endif /* RT_OS_OS2 */
    19331957
    19341958    LogFlowFunc(("fRetEvents=%#x\n", fRetEvents));
     
    19641988    AssertPtrReturn(pThis, UINT32_MAX);
    19651989    AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, UINT32_MAX);
     1990    /** @todo This isn't quite sane. Replace by critsect and open up concurrent
     1991     *        reads and writes! */
    19661992    if (rtSocketTryLock(pThis))
    19671993        pThis->hPollSet = hPollSet;
     
    19731999
    19742000    /* (rtSocketPollCheck will reset the event object). */
     2001# ifdef RT_OS_WINDOWS
    19752002    uint32_t fRetEvents = pThis->fEventsSaved;
    19762003    pThis->fEventsSaved = 0; /* Reset */
     
    19922019        }
    19932020    }
     2021# else
     2022    uint32_t fRetEvents = rtSocketPollCheck(pThis, fEvents);
     2023# endif
    19942024
    19952025    if (fRetEvents || fNoWait)
     
    19972027        if (pThis->cUsers == 1)
    19982028        {
     2029# ifdef RT_OS_WINDOWS
    19992030            rtSocketPollClearEventAndRestoreBlocking(pThis);
     2031# endif
    20002032            pThis->hPollSet = NIL_RTPOLLSET;
    20012033        }
     
    20332065    /* Harvest events and clear the event mask for the next round of polling. */
    20342066    uint32_t fRetEvents = rtSocketPollCheck(pThis, fEvents);
     2067# ifdef RT_OS_WINDOWS
    20352068    pThis->fPollEvts = 0;
    20362069
     
    20462079        fRetEvents = 0;
    20472080    }
     2081# endif
    20482082
    20492083    /* Make the socket blocking again and unlock the handle. */
    20502084    if (pThis->cUsers == 1)
    20512085    {
     2086# ifdef RT_OS_WINDOWS
    20522087        rtSocketPollClearEventAndRestoreBlocking(pThis);
     2088# endif
    20532089        pThis->hPollSet = NIL_RTPOLLSET;
    20542090    }
     
    20572093}
    20582094
    2059 #endif /* RT_OS_WINDOWS */
     2095#endif /* RT_OS_WINDOWS || RT_OS_OS2 */
     2096
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