Changeset 44487 in vbox
- Timestamp:
- Jan 31, 2013 12:37:42 PM (12 years ago)
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 1 deleted
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/Makefile.kmk
r44472 r44487 477 477 r3/isofs.cpp \ 478 478 r3/path.cpp \ 479 r3/poll.cpp \ 479 480 r3/process.cpp \ 480 481 r3/socket.cpp \ … … 572 573 r3/win/path-win.cpp \ 573 574 r3/win/pipe-win.cpp \ 574 r3/poll.cpp \575 575 r3/win/process-win.cpp \ 576 576 r3/win/RTLogWriteDebugger-win.cpp \ … … 646 646 r3/posix/RTPathUserDocuments-posix.cpp \ 647 647 r3/posix/pipe-posix.cpp \ 648 r3/poll.cpp \649 648 r3/posix/process-posix.cpp \ 650 649 r3/posix/process-creation-posix.cpp \ … … 712 711 r3/os2/mp-os2.cpp \ 713 712 r3/os2/pipe-os2.cpp \ 714 r3/os2/poll-os2.cpp \715 713 r3/os2/rtProcInitExePath-os2.cpp \ 716 714 r3/os2/sched-os2.cpp \ … … 801 799 r3/posix/path2-posix.cpp \ 802 800 r3/posix/pipe-posix.cpp \ 803 r3/poll.cpp \804 801 r3/posix/process-posix.cpp \ 805 802 r3/posix/process-creation-posix.cpp \ … … 866 863 r3/posix/RTPathUserDocuments-posix.cpp \ 867 864 r3/posix/pipe-posix.cpp \ 868 r3/poll.cpp \869 865 r3/posix/process-posix.cpp \ 870 866 r3/posix/process-creation-posix.cpp \ … … 925 921 r3/posix/RTPathUserDocuments-posix.cpp \ 926 922 r3/posix/pipe-posix.cpp \ 927 r3/poll.cpp \928 923 r3/posix/process-posix.cpp \ 929 924 r3/posix/process-creation-posix.cpp \ … … 999 994 r3/posix/pathhost-posix.cpp \ 1000 995 r3/posix/pipe-posix.cpp \ 1001 r3/poll.cpp \1002 996 r3/posix/process-posix.cpp \ 1003 997 r3/posix/process-creation-posix.cpp \ -
trunk/src/VBox/Runtime/include/internal/pipe.h
r44469 r44487 5 5 6 6 /* 7 * Copyright (C) 2010 Oracle Corporation7 * Copyright (C) 2010-2013 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 29 29 30 30 #include <iprt/pipe.h> 31 /* Requires Windows.h on windows. */32 31 33 32 RT_C_DECLS_BEGIN … … 42 41 * @param phNative Where to put the primary handle. 43 42 */ 44 int rtPipePollGetHandle(RTPIPE hPipe, uint32_t fEvents, PRTHCINTPTR phNative);43 int rtPipePollGetHandle(RTPIPE hPipe, uint32_t fEvents, PRTHCINTPTR phNative); 45 44 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 */ 47 64 uint32_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 */ 48 82 uint32_t rtPipePollDone(RTPIPE hPipe, uint32_t fEvents, bool fFinalEntry, bool fHarvestEvents); 49 #endif /* RT_OS_WINDOWS */50 83 51 84 RT_C_DECLS_END -
trunk/src/VBox/Runtime/include/internal/socket.h
r44469 r44487 63 63 64 64 int rtSocketPollGetHandle(RTSOCKET hSocket, uint32_t fEvents, PRTHCINTPTR phNative); 65 #ifdef RT_OS_WINDOWS66 65 uint32_t rtSocketPollStart(RTSOCKET hSocket, RTPOLLSET hPollSet, uint32_t fEvents, bool fFinalEntry, bool fNoWait); 67 66 uint32_t rtSocketPollDone(RTSOCKET hSocket, uint32_t fEvents, bool fFinalEntry, bool fHarvestEvents); 68 #endif /* RT_OS_WINDOWS */69 67 70 68 RT_C_DECLS_END -
trunk/src/VBox/Runtime/r3/os2/pipe-os2.cpp
r44462 r44487 763 763 if (RT_FAILURE(rc)) 764 764 return rc; 765 765 766 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 } 766 775 if (RT_SUCCESS(rc)) 767 776 { … … 771 780 * Check the handle state. 772 781 */ 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 773 790 PIPESEMSTATE aStates[4]; RT_ZERO(aStates); 774 APIRETorc = DosQueryNPipeSemState((HSEM)pThis->hev, &aStates[0], sizeof(aStates));791 orc = DosQueryNPipeSemState((HSEM)pThis->hev, &aStates[0], sizeof(aStates)); 775 792 if (orc != NO_ERROR) 776 793 { … … 789 806 Assert(aStates[i].fStatus == NPSS_WSPACE || aStates[i].fStatus == NPSS_RDATA || aStates[i].fStatus == NPSS_EOI); 790 807 if ( aStates[i].fStatus != NPSS_EOI 791 && aStates[ 0].usAvail > 0)808 && aStates[i].usAvail > 0) 792 809 break; 793 810 … … 822 839 if (rc == VERR_BROKEN_PIPE) 823 840 pThis->fBrokenPipe = true; 841 if (cMillies > 0) 842 pThis->hPollSet = NIL_RTPOLLSET; 824 843 } 825 844 … … 860 879 861 880 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) 881 int rtPipePollGetHandle(RTPIPE hPipe, uint32_t fEvents, PRTHCINTPTR phNative) 873 882 { 874 883 RTPIPEINTERNAL *pThis = hPipe; … … 876 885 AssertReturn(pThis->u32Magic == RTPIPE_MAGIC, VERR_INVALID_HANDLE); 877 886 878 AssertReturn(!(fEvents & RTPOLL_EVT_READ) || pThis->fRead,VERR_INVALID_PARAMETER);887 AssertReturn(!(fEvents & RTPOLL_EVT_READ) || pThis->fRead, VERR_INVALID_PARAMETER); 879 888 AssertReturn(!(fEvents & RTPOLL_EVT_WRITE) || !pThis->fRead, VERR_INVALID_PARAMETER); 880 889 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; 886 899 } 887 900 … … 893 906 * @param pThis The pipe handle. 894 907 * @param fEvents The desired events. 908 * @param fResetEvtSem Whether to reset the event semaphore. 895 909 */ 896 static uint32_t rtPipePollCheck(RTPIPEINTERNAL *pThis, uint32_t fEvents) 897 { 910 static 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 */ 898 926 uint32_t fRetEvents = 0; 899 927 if (pThis->fBrokenPipe) … … 901 929 else if (pThis->fRead) 902 930 { 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 { 916 960 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) 950 965 fRetEvents |= RTPOLL_EVT_WRITE; 951 966 } 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 977 979 uint32_t rtPipePollStart(RTPIPE hPipe, RTPOLLSET hPollSet, uint32_t fEvents, bool fFinalEntry, bool fNoWait) 978 980 { 979 /** @todo All this polling code could be optimized to make fewer system980 * calls; like for instance the ResetEvent calls. */981 981 RTPIPEINTERNAL *pThis = hPipe; 982 982 AssertPtrReturn(pThis, UINT32_MAX); … … 989 989 uint32_t fRetEvents; 990 990 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; 1030 999 } 1031 1000 } … … 1041 1010 1042 1011 1043 /**1044 * Called after a WaitForMultipleObjects returned in order to check for pending1045 * 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 handle1052 * in this poll set. This can be used for dealing1053 * with duplicate entries. Only keep in mind that1054 * this method is called in reverse order, so the1055 * first call will have this set (when the entire1056 * set was processed).1057 * @param fHarvestEvents Set if we should check for pending events.1058 */1059 1012 uint32_t rtPipePollDone(RTPIPE hPipe, uint32_t fEvents, bool fFinalEntry, bool fHarvestEvents) 1060 1013 { … … 1068 1021 Assert(pThis->cUsers > 0); 1069 1022 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 1085 1023 /* harvest events. */ 1086 fRetEvents |= rtPipePollCheck(pThis, fEvents);1024 uint32_t fRetEvents = rtPipePollCheck(pThis, fEvents, false); 1087 1025 1088 1026 /* update counters. */ 1089 1027 pThis->cUsers--; 1090 if (!pThis->cUsers) 1091 pThis->hPollSet = NIL_RTPOLLSET; 1028 pThis->hPollSet = NIL_RTPOLLSET; 1092 1029 1093 1030 RTCritSectLeave(&pThis->CritSect); 1094 1031 return fRetEvents; 1095 1032 } 1096 #endif -
trunk/src/VBox/Runtime/r3/poll.cpp
r44472 r44487 32 32 #ifdef RT_OS_WINDOWS 33 33 # 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 34 41 #else 35 42 # include <limits.h> … … 41 48 #include "internal/iprt.h" 42 49 50 #include <iprt/alloca.h> 43 51 #include <iprt/asm.h> 44 52 #include <iprt/assert.h> … … 102 110 bool volatile fBusy; 103 111 112 /** The number of allocated handles. */ 113 uint16_t cHandlesAllocated; 104 114 /** 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; 108 116 109 117 #ifdef RT_OS_WINDOWS 110 118 /** Pointer to an array of native handles. */ 111 119 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; 112 137 #else 113 138 /** Pointer to an array of pollfd structures. */ … … 115 140 #endif 116 141 /** Pointer to an array of handles and IDs. */ 117 RTPOLLSETHNDENT *paHandles;142 PRTPOLLSETHNDENT paHandles; 118 143 } RTPOLLSETINTERNAL; 119 144 … … 123 148 * Common worker for RTPoll and RTPollNoResume 124 149 */ 125 static int rtPollNoResumeWorker(RTPOLLSETINTERNAL *pThis, RTMSINTERVAL cMillies, uint32_t *pfEvents, uint32_t *pid) 150 static int rtPollNoResumeWorker(RTPOLLSETINTERNAL *pThis, uint64_t MsStart, RTMSINTERVAL cMillies, 151 uint32_t *pfEvents, uint32_t *pid) 126 152 { 127 153 int rc; … … 142 168 } 143 169 144 #if def RT_OS_WINDOWS170 #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) 145 171 /* 146 172 * Check + prepare the handles before waiting. … … 210 236 } 211 237 238 212 239 /* 213 240 * Wait. 214 241 */ 242 # ifdef RT_OS_WINDOWS 215 243 DWORD dwRc = WaitForMultipleObjectsEx(cHandles, pThis->pahNative, 216 244 FALSE /*fWaitAll */, … … 231 259 rc = VERR_INTERNAL_ERROR_5; 232 260 } 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 */ 233 317 234 318 /* … … 362 446 if (cMillies == RT_INDEFINITE_WAIT || cMillies == 0) 363 447 { 364 do rc = rtPollNoResumeWorker(pThis, cMillies, pfEvents, pid);448 do rc = rtPollNoResumeWorker(pThis, 0, cMillies, pfEvents, pid); 365 449 while (rc == VERR_INTERRUPTED); 366 450 } … … 368 452 { 369 453 uint64_t MsStart = RTTimeMilliTS(); 370 rc = rtPollNoResumeWorker(pThis, cMillies, pfEvents, pid);454 rc = rtPollNoResumeWorker(pThis, MsStart, cMillies, pfEvents, pid); 371 455 while (RT_UNLIKELY(rc == VERR_INTERRUPTED)) 372 456 { … … 376 460 break; 377 461 } 378 rc = rtPollNoResumeWorker(pThis, cMillies, pfEvents, pid);462 rc = rtPollNoResumeWorker(pThis, MsStart, cMillies, pfEvents, pid); 379 463 } 380 464 } … … 399 483 AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true, false), VERR_CONCURRENT_ACCESS); 400 484 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); 402 490 403 491 ASMAtomicWriteBool(&pThis->fBusy, false); … … 414 502 return VERR_NO_MEMORY; 415 503 416 pThis->u32Magic = RTPOLLSET_MAGIC;417 504 pThis->fBusy = false; 418 505 pThis->cHandles = 0; … … 420 507 #ifdef RT_OS_WINDOWS 421 508 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; 422 523 #else 423 524 pThis->paPollFds = NULL; 424 525 #endif 425 526 pThis->paHandles = NULL; 527 pThis->u32Magic = RTPOLLSET_MAGIC; 426 528 427 529 *phPollSet = pThis; … … 441 543 ASMAtomicWriteU32(&pThis->u32Magic, ~RTPOLLSET_MAGIC); 442 544 #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; 443 552 RTMemFree(pThis->pahNative); 444 553 pThis->pahNative = NULL; … … 454 563 } 455 564 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 */ 576 static 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 */ 597 static 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 */ 627 static 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 */ 650 static 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 */ 690 static 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 456 733 457 734 RTDECL(int) RTPollSetAdd(RTPOLLSET hPollSet, PCRTHANDLE pHandle, uint32_t fEvents, uint32_t id) … … 539 816 /* Grow the tables if necessary. */ 540 817 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); 569 819 if (RT_SUCCESS(rc)) 570 820 { 571 /* Add the handles to the two parallel arrays. */ 821 /* 822 * Add the handles to the two parallel arrays. 823 */ 572 824 #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; 574 828 #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; 578 832 if (fEvents & RTPOLL_EVT_READ) 579 833 pThis->paPollFds[i].events |= POLLIN; … … 595 849 } 596 850 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) 607 860 { 608 861 rc = RTErrConvertFromErrno(errno); 609 862 pThis->paPollFds[i].fd = -1; 610 863 } 611 #endif 864 #endif /* POSIX */ 612 865 613 866 if (RT_SUCCESS(rc)) 614 867 { 615 /* Commit */ 616 pThis->cHandles = i + 1; 868 /* 869 * Commit it to the set. 870 */ 871 pThis->cHandles++; Assert(pThis->cHandles == i + 1); 617 872 rc = VINF_SUCCESS; 618 873 } … … 646 901 { 647 902 /* 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 651 910 652 911 /* Remove the entry. */ … … 656 915 { 657 916 memmove(&pThis->paHandles[i], &pThis->paHandles[i + 1], cToMove * sizeof(pThis->paHandles[i])); 658 #if def RT_OS_WINDOWS917 #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) 659 918 memmove(&pThis->pahNative[i], &pThis->pahNative[i + 1], cToMove * sizeof(pThis->pahNative[i])); 660 919 #else … … 674 933 } 675 934 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 */ 676 966 rc = VINF_SUCCESS; 677 967 break; … … 759 1049 if (pThis->paHandles[i].id == id) 760 1050 { 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; 770 1099 #endif 1100 pThis->paHandles[i].fEvents = fEvents; 1101 } 771 1102 rc = VINF_SUCCESS; 772 1103 break; -
trunk/src/VBox/Runtime/r3/socket.cpp
r44469 r44487 146 146 * currently. */ 147 147 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 148 153 #ifdef RT_OS_WINDOWS 149 154 /** The event semaphore we've associated with the socket handle. 150 155 * This is WSA_INVALID_EVENT if not done. */ 151 156 WSAEVENT hEvent; 152 /** The pollset currently polling this socket. This is NIL if no one is153 * polling. */154 RTPOLLSET hPollSet;155 157 /** The events we're polling for. */ 156 158 uint32_t fPollEvts; … … 408 410 pThis->fClosed = false; 409 411 pThis->fBlocking = true; 412 #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) 413 pThis->hPollSet = NIL_RTPOLLSET; 414 #endif 410 415 #ifdef RT_OS_WINDOWS 411 416 pThis->hEvent = WSA_INVALID_EVENT; 412 pThis->hPollSet = NIL_RTPOLLSET;413 417 pThis->fPollEvts = 0; 414 418 pThis->fSubscribedEvts = 0; … … 1878 1882 } 1879 1883 1884 #endif /* RT_OS_WINDOWS */ 1885 1886 1887 #if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2) 1880 1888 1881 1889 /** … … 1888 1896 static uint32_t rtSocketPollCheck(RTSOCKETINT *pThis, uint32_t fEvents) 1889 1897 { 1890 int rc = VINF_SUCCESS; 1891 uint32_t fRetEvents = 0; 1898 uint32_t fRetEvents = 0; 1892 1899 1893 1900 LogFlowFunc(("pThis=%#p fEvents=%#x\n", pThis, fEvents)); 1894 1901 1902 # ifdef RT_OS_WINDOWS 1895 1903 /* Make sure WSAEnumNetworkEvents returns what we want. */ 1904 int rc = VINF_SUCCESS; 1896 1905 if ((pThis->fSubscribedEvts & fEvents) != fEvents) 1897 1906 rc = rtSocketPollUpdateEvents(pThis, pThis->fSubscribedEvts | fEvents); … … 1929 1938 if (RT_FAILURE(rc)) 1930 1939 { 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 */ 1933 1957 1934 1958 LogFlowFunc(("fRetEvents=%#x\n", fRetEvents)); … … 1964 1988 AssertPtrReturn(pThis, UINT32_MAX); 1965 1989 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! */ 1966 1992 if (rtSocketTryLock(pThis)) 1967 1993 pThis->hPollSet = hPollSet; … … 1973 1999 1974 2000 /* (rtSocketPollCheck will reset the event object). */ 2001 # ifdef RT_OS_WINDOWS 1975 2002 uint32_t fRetEvents = pThis->fEventsSaved; 1976 2003 pThis->fEventsSaved = 0; /* Reset */ … … 1992 2019 } 1993 2020 } 2021 # else 2022 uint32_t fRetEvents = rtSocketPollCheck(pThis, fEvents); 2023 # endif 1994 2024 1995 2025 if (fRetEvents || fNoWait) … … 1997 2027 if (pThis->cUsers == 1) 1998 2028 { 2029 # ifdef RT_OS_WINDOWS 1999 2030 rtSocketPollClearEventAndRestoreBlocking(pThis); 2031 # endif 2000 2032 pThis->hPollSet = NIL_RTPOLLSET; 2001 2033 } … … 2033 2065 /* Harvest events and clear the event mask for the next round of polling. */ 2034 2066 uint32_t fRetEvents = rtSocketPollCheck(pThis, fEvents); 2067 # ifdef RT_OS_WINDOWS 2035 2068 pThis->fPollEvts = 0; 2036 2069 … … 2046 2079 fRetEvents = 0; 2047 2080 } 2081 # endif 2048 2082 2049 2083 /* Make the socket blocking again and unlock the handle. */ 2050 2084 if (pThis->cUsers == 1) 2051 2085 { 2086 # ifdef RT_OS_WINDOWS 2052 2087 rtSocketPollClearEventAndRestoreBlocking(pThis); 2088 # endif 2053 2089 pThis->hPollSet = NIL_RTPOLLSET; 2054 2090 } … … 2057 2093 } 2058 2094 2059 #endif /* RT_OS_WINDOWS */ 2095 #endif /* RT_OS_WINDOWS || RT_OS_OS2 */ 2096
Note:
See TracChangeset
for help on using the changeset viewer.