Changeset 27509 in vbox for trunk/src/VBox/Runtime/r3
- Timestamp:
- Mar 18, 2010 11:47:16 PM (15 years ago)
- Location:
- trunk/src/VBox/Runtime/r3
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/os2/poll-os2.cpp
r26844 r27509 83 83 84 84 85 RTDECL(uint32_t) RTPollSet Count(RTPOLLSET hPollSet)85 RTDECL(uint32_t) RTPollSetGetCount(RTPOLLSET hPollSet) 86 86 { 87 87 return UINT32_MAX; -
trunk/src/VBox/Runtime/r3/posix/poll-posix.cpp
r27503 r27509 184 184 * Set the busy flag and do the job. 185 185 */ 186 AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true, false), VERR_ WRONG_ORDER);186 AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true, false), VERR_CONCURRENT_ACCESS); 187 187 188 188 int rc; … … 224 224 * Set the busy flag and do the job. 225 225 */ 226 AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true, false), VERR_ WRONG_ORDER);226 AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true, false), VERR_CONCURRENT_ACCESS); 227 227 228 228 int rc = rtPollNoResumeWorker(pThis, cMillies, pfEvents, pid); … … 260 260 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 261 261 AssertReturn(pThis->u32Magic == RTPOLLSET_MAGIC, VERR_INVALID_HANDLE); 262 AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true, false), VERR_ WRONG_ORDER);262 AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true, false), VERR_CONCURRENT_ACCESS); 263 263 264 264 ASMAtomicWriteU32(&pThis->u32Magic, ~RTPOLLSET_MAGIC); … … 293 293 * Set the busy flag and do the job. 294 294 */ 295 AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true, false), VERR_ WRONG_ORDER);295 AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true, false), VERR_CONCURRENT_ACCESS); 296 296 297 297 int rc = VINF_SUCCESS; … … 407 407 * Set the busy flag and do the job. 408 408 */ 409 AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true, false), VERR_ WRONG_ORDER);409 AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true, false), VERR_CONCURRENT_ACCESS); 410 410 411 411 int rc = VERR_POLL_HANDLE_ID_NOT_FOUND; … … 444 444 * Set the busy flag and do the job. 445 445 */ 446 AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true, false), VERR_ WRONG_ORDER);446 AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true, false), VERR_CONCURRENT_ACCESS); 447 447 448 448 int rc = VERR_POLL_HANDLE_ID_NOT_FOUND; … … 465 465 466 466 467 RTDECL(uint32_t) RTPollSet Count(RTPOLLSET hPollSet)467 RTDECL(uint32_t) RTPollSetGetCount(RTPOLLSET hPollSet) 468 468 { 469 469 /* -
trunk/src/VBox/Runtime/r3/socket.cpp
r27504 r27509 60 60 #include <iprt/err.h> 61 61 #include <iprt/mem.h> 62 #include <iprt/poll.h> 62 63 #include <iprt/string.h> 63 64 #include <iprt/thread.h> … … 134 135 /** The events we're polling for. */ 135 136 uint32_t fPollEvts; 137 /** The events we're currently subscribing to with WSAEventSelect. 138 * This is ZERO if we're currently not subscribing to anything. */ 139 uint32_t fSubscribedEvts; 136 140 #else 137 141 /** The native socket handle. */ … … 258 262 if (!pThis) 259 263 return VERR_NO_MEMORY; 260 pThis->u32Magic = RTSOCKET_MAGIC; 261 pThis->cUsers = 0; 262 pThis->hNative = hNative; 263 #ifdef RT_OS_WINDOWS 264 pThis->hEvent = WSA_INVALID_EVENT; 265 pThis->hPollSet = NIL_RTPOLLSET; 266 pThis->fPollEvts = 0; 264 pThis->u32Magic = RTSOCKET_MAGIC; 265 pThis->cUsers = 0; 266 pThis->hNative = hNative; 267 #ifdef RT_OS_WINDOWS 268 pThis->hEvent = WSA_INVALID_EVENT; 269 pThis->hPollSet = NIL_RTPOLLSET; 270 pThis->fPollEvts = 0; 271 pThis->fSubscribedEvts = 0; 267 272 #endif 268 273 *ppSocket = pThis; … … 870 875 } 871 876 877 #ifdef RT_OS_WINDOWS 878 879 /** 880 * Internal RTPollSetAdd helper that returns the handle that should be added to 881 * the pollset. 882 * 883 * @returns Valid handle on success, INVALID_HANDLE_VALUE on failure. 884 * @param hSocket The socket handle. 885 * @param fEvents The events we're polling for. 886 * @param ph wher to put the primary handle. 887 */ 888 int rtSocketPollGetHandle(RTSOCKET hSocket, uint32_t fEvents, PHANDLE ph) 889 { 890 RTSOCKETINT *pThis = hSocket; 891 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 892 AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, VERR_INVALID_HANDLE); 893 AssertReturn(rtSocketTryLock(pThis), VERR_CONCURRENT_ACCESS); 894 895 int rc = VINF_SUCCESS; 896 if (pThis->hEvent != WSA_INVALID_EVENT) 897 *ph = pThis->hEvent; 898 else 899 { 900 *ph = pThis->hEvent = WSACreateEvent(); 901 if (pThis->hEvent == WSA_INVALID_EVENT) 902 rc = rtSocketError(); 903 } 904 905 rtSocketUnlock(pThis); 906 return rc; 907 } 908 909 910 /** 911 * Updates the mask of events we're subscribing to. 912 * 913 * @returns IPRT status code. 914 * @param pThis The socket handle. 915 * @param fEvents The events we want to subscribe to. 916 */ 917 static int rtSocketPollUpdateEvents(RTSOCKETINT *pThis, uint32_t fEvents) 918 { 919 LONG fNetworkEvents = 0; 920 if (fEvents & RTPOLL_EVT_READ) 921 fNetworkEvents |= FD_READ; 922 if (fEvents & RTPOLL_EVT_WRITE) 923 fNetworkEvents |= FD_WRITE; 924 if (fEvents & RTPOLL_EVT_ERROR) 925 fNetworkEvents |= FD_CLOSE; 926 if (WSAEventSelect(pThis->hNative, pThis->hEvent, fNetworkEvents) == 0) 927 { 928 pThis->fSubscribedEvts = fEvents; 929 930 u_long fNonBlocking = 0; 931 if (ioctlsocket(pThis->hNative, FIONBIO, &fNonBlocking)) 932 AssertMsgFailed(("%Rrc\n", rtSocketError())); 933 934 return VINF_SUCCESS; 935 } 936 937 int rc = rtSocketError(); 938 AssertMsgFailed(("fNetworkEvents=%#x rc=%Rrc\n", fNetworkEvents, rtSocketError())); 939 return rc; 940 } 941 942 943 /** 944 * Checks for pending events. 945 * 946 * @returns Event mask or 0. 947 * @param pThis The socket handle. 948 * @param fEvents The desired events. 949 */ 950 static uint32_t rtSocketPollCheck(RTSOCKETINT *pThis, uint32_t fEvents) 951 { 952 int rc = VINF_SUCCESS; 953 uint32_t fRetEvents = 0; 954 955 /* Make sure WSAEnumNetworkEvents returns what we want. */ 956 if ((pThis->fSubscribedEvts & fEvents) != fEvents) 957 rc = rtSocketPollUpdateEvents(pThis, pThis->fSubscribedEvts | fEvents); 958 959 /* Get the event mask, ASSUMES that WSAEnumNetworkEvents doesn't clear stuff. */ 960 WSANETWORKEVENTS NetEvts; 961 RT_ZERO(NetEvts); 962 if (WSAEnumNetworkEvents(pThis->hNative, pThis->hEvent, &NetEvts) == 0) 963 { 964 if ( (NetEvts.lNetworkEvents & FD_READ) 965 && (fEvents & RTPOLL_EVT_READ) 966 && NetEvts.iErrorCode[FD_READ_BIT] == 0) 967 fRetEvents |= RTPOLL_EVT_READ; 968 969 if ( (NetEvts.lNetworkEvents & FD_WRITE) 970 && (fEvents & RTPOLL_EVT_WRITE) 971 && NetEvts.iErrorCode[FD_WRITE_BIT] == 0) 972 fRetEvents |= RTPOLL_EVT_WRITE; 973 974 if (fEvents & RTPOLL_EVT_ERROR) 975 { 976 if (NetEvts.lNetworkEvents & FD_CLOSE) 977 fRetEvents |= RTPOLL_EVT_ERROR; 978 else 979 for (uint32_t i = 0; i < FD_MAX_EVENTS; i++) 980 if ( (NetEvts.lNetworkEvents & (1L << i)) 981 && NetEvts.iErrorCode[i] != 0) 982 fRetEvents |= RTPOLL_EVT_ERROR; 983 } 984 } 985 else 986 rc = rtSocketError(); 987 988 /* Fall back on select if we hit an error above. */ 989 if (RT_FAILURE(rc)) 990 { 991 /** @todo */ 992 } 993 994 return fRetEvents; 995 } 996 997 998 /** 999 * Internal RTPoll helper that polls the socket handle and, if @a fNoWait is 1000 * clear, starts whatever actions we've got running during the poll call. 1001 * 1002 * @returns 0 if no pending events, actions initiated if @a fNoWait is clear. 1003 * Event mask (in @a fEvents) and no actions if the handle is ready 1004 * already. 1005 * UINT32_MAX (asserted) if the socket handle is busy in I/O or a 1006 * different poll set. 1007 * 1008 * @param hSocket The socket handle. 1009 * @param hPollSet The poll set handle (for access checks). 1010 * @param fEvents The events we're polling for. 1011 * @param fFinalEntry Set if this is the final entry for this handle 1012 * in this poll set. This can be used for dealing 1013 * with duplicate entries. 1014 * @param fNoWait Set if it's a zero-wait poll call. Clear if 1015 * we'll wait for an event to occur. 1016 * 1017 * @remarks There is a potential race wrt duplicate handles when @a fNoWait is 1018 * @c true, we don't currently care about that oddity... 1019 */ 1020 uint32_t rtSocketPollStart(RTSOCKET hSocket, RTPOLLSET hPollSet, uint32_t fEvents, bool fFinalEntry, bool fNoWait) 1021 { 1022 RTSOCKETINT *pThis = hSocket; 1023 AssertPtrReturn(pThis, UINT32_MAX); 1024 AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, UINT32_MAX); 1025 if (rtSocketTryLock(pThis)) 1026 pThis->hPollSet = hPollSet; 1027 else 1028 { 1029 AssertReturn(pThis->hPollSet == hPollSet, UINT32_MAX); 1030 ASMAtomicIncU32(&pThis->cUsers); 1031 } 1032 1033 /* (rtSocketPollCheck will reset the event object). */ 1034 uint32_t fRetEvents = rtSocketPollCheck(pThis, fEvents); 1035 if ( !fRetEvents 1036 && !fNoWait) 1037 { 1038 pThis->fPollEvts |= fEvents; 1039 if ( fFinalEntry 1040 && pThis->fSubscribedEvts != pThis->fPollEvts) 1041 { 1042 int rc = rtSocketPollUpdateEvents(pThis, pThis->fPollEvts); 1043 if (RT_FAILURE(rc)) 1044 { 1045 pThis->fPollEvts = 0; 1046 fRetEvents = UINT32_MAX; 1047 } 1048 } 1049 } 1050 1051 if (fRetEvents || fNoWait) 1052 { 1053 if (pThis->cUsers == 1) 1054 pThis->hPollSet = NIL_RTPOLLSET; 1055 ASMAtomicDecU32(&pThis->cUsers); 1056 } 1057 1058 return fRetEvents; 1059 } 1060 1061 1062 /** 1063 * Called after a WaitForMultipleObjects returned in order to check for pending 1064 * events and stop whatever actions that rtSocketPollStart() initiated. 1065 * 1066 * @returns Event mask or 0. 1067 * 1068 * @param hSocket The socket handle. 1069 * @param fEvents The events we're polling for. 1070 * @param fFinalEntry Set if this is the final entry for this handle 1071 * in this poll set. This can be used for dealing 1072 * with duplicate entries. Only keep in mind that 1073 * this method is called in reverse order, so the 1074 * first call will have this set (when the entire 1075 * set was processed). 1076 */ 1077 uint32_t rtSocketPollDone(RTSOCKET hSocket, uint32_t fEvents, bool fFinalEntry) 1078 { 1079 RTSOCKETINT *pThis = hSocket; 1080 AssertPtrReturn(pThis, 0); 1081 AssertReturn(pThis->u32Magic == RTSOCKET_MAGIC, 0); 1082 Assert(pThis->cUsers > 0); 1083 Assert(pThis->hPollSet != NIL_RTPOLLSET); 1084 1085 /* Harvest events and clear the event mask for the next round of polling. */ 1086 uint32_t fRetEvents = rtSocketPollCheck(pThis, fEvents); 1087 pThis->fPollEvts = 0; 1088 1089 /* unlock the socket. */ 1090 if (pThis->cUsers == 1) 1091 pThis->hPollSet = NIL_RTPOLLSET; 1092 ASMAtomicDecU32(&pThis->cUsers); 1093 return fRetEvents; 1094 } 1095 1096 #endif /* RT_OS_WINDOWS */ -
trunk/src/VBox/Runtime/r3/win/pipe-win.cpp
r27431 r27509 1018 1018 1019 1019 /** 1020 * Internal RTPollSetAdd helper that returns one or two handles that should be1021 * added tothe pollset.1020 * Internal RTPollSetAdd helper that returns the handle that should be added to 1021 * the pollset. 1022 1022 * 1023 1023 * @returns Valid handle on success, INVALID_HANDLE_VALUE on failure. 1024 1024 * @param hPipe The pipe handle. 1025 1025 * @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. 1028 1027 */ 1029 int rtPipePollGetHandle s(RTPIPE hPipe, uint32_t fEvents, PHANDLE ph1, PHANDLE ph2)1028 int rtPipePollGetHandle(RTPIPE hPipe, uint32_t fEvents, PHANDLE ph) 1030 1029 { 1031 1030 RTPIPEINTERNAL *pThis = hPipe; … … 1036 1035 AssertReturn(!(fEvents & RTPOLL_EVT_WRITE) || !pThis->fRead, VERR_INVALID_PARAMETER); 1037 1036 1038 *ph1 = pThis->Overlapped.hEvent;1039 1037 /* Later: Try register an event handle with the pipe like on OS/2, there is 1040 1038 a file control for doing this obviously intended for the OS/2 subsys. 1041 1039 The question is whether this still exists on Vista and W7. */ 1042 *ph 2 = INVALID_HANDLE_VALUE;1040 *ph = pThis->Overlapped.hEvent; 1043 1041 return VINF_SUCCESS; 1044 1042 } … … 1127 1125 * @param hPollSet The poll set handle (for access checks). 1128 1126 * @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. 1129 1130 * @param fNoWait Set if it's a zero-wait poll call. Clear if 1130 1131 * we'll wait for an event to occur. 1131 1132 */ 1132 uint32_t rtPipePollStart(RTPIPE hPipe, RTPOLLSET hPollSet, uint32_t fEvents, bool f NoWait)1133 uint32_t rtPipePollStart(RTPIPE hPipe, RTPOLLSET hPollSet, uint32_t fEvents, bool fFinalEntry, bool fNoWait) 1133 1134 { 1134 1135 /** @todo All this polling code could be optimized to make fewer system … … 1207 1208 * @param hPipe The pipe handle. 1208 1209 * @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). 1209 1216 */ 1210 uint32_t rtPipePollDone(RTPIPE hPipe, uint32_t fEvents )1217 uint32_t rtPipePollDone(RTPIPE hPipe, uint32_t fEvents, bool fFinalEntry) 1211 1218 { 1212 1219 RTPIPEINTERNAL *pThis = hPipe; -
trunk/src/VBox/Runtime/r3/win/poll-win.cpp
r27431 r27509 2 2 /** @file 3 3 * IPRT - Polling I/O Handles, Windows Implementation. 4 * 5 * @todo merge poll-win.cpp and poll-posix.cpp, there is lots of common code. 4 6 */ 5 7 … … 46 48 #include <iprt/thread.h> 47 49 #include <iprt/time.h> 50 48 51 #include "internal/pipe.h" 52 #define IPRT_INTERNAL_SOCKET_POLLING_ONLY 53 #include "internal/socket.h" 49 54 #include "internal/magics.h" 50 55 … … 64 69 /** The events we're waiting for here. */ 65 70 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; 66 75 /** The handle union. */ 67 76 RTHANDLEUNION u; … … 123 132 { 124 133 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); 126 141 break; 127 142 … … 155 170 { 156 171 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); 158 174 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 159 181 default: 160 182 AssertFailed(); … … 198 220 { 199 221 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 202 231 default: 203 232 AssertFailed(); … … 230 259 * Set the busy flag and do the job. 231 260 */ 232 AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true, false), VERR_ WRONG_ORDER);261 AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true, false), VERR_CONCURRENT_ACCESS); 233 262 234 263 int rc; … … 270 299 * Set the busy flag and do the job. 271 300 */ 272 AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true, false), VERR_ WRONG_ORDER);301 AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true, false), VERR_CONCURRENT_ACCESS); 273 302 274 303 int rc = rtPollNoResumeWorker(pThis, cMillies, pfEvents, pid); … … 305 334 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 306 335 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); 308 337 309 338 ASMAtomicWriteU32(&pThis->u32Magic, ~RTPOLLSET_MAGIC); … … 334 363 * Set the busy flag and do the job. 335 364 */ 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; 341 371 switch (pHandle->enmType) 342 372 { 343 373 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); 346 377 break; 347 378 348 379 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); 351 383 break; 352 384 … … 372 404 373 405 /* 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; 375 408 while (j-- > 0) 409 { 376 410 if (pThis->aHandles[j].id == id) 377 411 { … … 379 413 break; 380 414 } 415 if ( pThis->aHandles[j].enmType == pHandle->enmType 416 && pThis->aHandles[j].u.uInt == uh.uInt) 417 iPrev = j; 418 } 381 419 382 420 /* Check that we won't overflow the poll set now. */ 383 421 if ( RT_SUCCESS(rc) 384 && i + 1 + (hNative2 != INVALID_HANDLE_VALUE)> RT_ELEMENTS(pThis->ahNative))422 && i + 1 > RT_ELEMENTS(pThis->ahNative)) 385 423 rc = VERR_POLL_SET_IS_FULL; 386 424 if (RT_SUCCESS(rc)) 387 425 { 388 426 /* 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) 397 436 { 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; 401 439 } 402 440 … … 423 461 * Set the busy flag and do the job. 424 462 */ 425 AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true, false), VERR_ WRONG_ORDER);463 AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true, false), VERR_CONCURRENT_ACCESS); 426 464 427 465 int rc = VERR_POLL_HANDLE_ID_NOT_FOUND; … … 430 468 if (pThis->aHandles[i].id == id) 431 469 { 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. */ 432 476 pThis->cHandles--; 433 477 size_t const cToMove = pThis->cHandles - i; … … 437 481 memmove(&pThis->ahNative[i], &pThis->ahNative[i + 1], cToMove * sizeof(pThis->ahNative[i])); 438 482 } 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 439 495 rc = VINF_SUCCESS; 496 break; 440 497 } 441 498 … … 459 516 * Set the busy flag and do the job. 460 517 */ 461 AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true, false), VERR_ WRONG_ORDER);518 AssertReturn(ASMAtomicCmpXchgBool(&pThis->fBusy, true, false), VERR_CONCURRENT_ACCESS); 462 519 463 520 int rc = VERR_POLL_HANDLE_ID_NOT_FOUND; … … 480 537 481 538 482 RTDECL(uint32_t) RTPollSet Count(RTPOLLSET hPollSet)539 RTDECL(uint32_t) RTPollSetGetCount(RTPOLLSET hPollSet) 483 540 { 484 541 /* … … 499 556 } 500 557 501
Note:
See TracChangeset
for help on using the changeset viewer.