VirtualBox

Changeset 58299 in vbox


Ignore:
Timestamp:
Oct 18, 2015 7:35:41 PM (9 years ago)
Author:
vboxsync
Message:

localipc-win.cpp: Implemented RTLocalIpcSessionReadNB.

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

Legend:

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

    r58298 r58299  
    2929*   Header Files                                                                                                                 *
    3030*********************************************************************************************************************************/
    31 #define RTMEM_WRAP_TO_EF_APIS
    3231#define LOG_GROUP RTLOGGROUP_LOCALIPC
    3332/*
     
    10821081        {
    10831082            pThis->Read.hActiveThread = RTThreadSelf();
    1084             Assert(!pThis->fZeroByteRead);
    10851083
    10861084            size_t cbTotalRead = 0;
     
    11281126
    11291127                        RTCritSectEnter(&pThis->CritSect);
    1130                         if (GetOverlappedResult(pThis->hNmPipe, &pThis->Read.OverlappedIO, &cbRead,
    1131                                                 rcWait == WAIT_OBJECT_0 && !pThis->fCancelled /*fWait*/))
     1128                        if (GetOverlappedResult(pThis->hNmPipe, &pThis->Read.OverlappedIO, &cbRead, TRUE /*fWait*/))
    11321129                            rc = VINF_SUCCESS;
    11331130                        else
     
    11651162                    && rc != VERR_INVALID_POINTER)
    11661163                    rc = VINF_SUCCESS;
     1164            }
     1165
     1166            pThis->Read.hActiveThread = NIL_RTTHREAD;
     1167        }
     1168        else
     1169            rc = VERR_WRONG_ORDER;
     1170        rtLocalIpcSessionReleaseAndUnlock(pThis);
     1171    }
     1172
     1173    return rc;
     1174}
     1175
     1176
     1177RTDECL(int) RTLocalIpcSessionReadNB(RTLOCALIPCSESSION hSession, void *pvBuf, size_t cbToRead, size_t *pcbRead)
     1178{
     1179    PRTLOCALIPCSESSIONINT pThis = (PRTLOCALIPCSESSIONINT)hSession;
     1180    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     1181    AssertReturn(pThis->u32Magic == RTLOCALIPCSESSION_MAGIC, VERR_INVALID_HANDLE);
     1182    AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
     1183    AssertPtrReturn(pcbRead, VERR_INVALID_POINTER);
     1184    *pcbRead = 0;
     1185
     1186    int rc = RTCritSectEnter(&pThis->CritSect);
     1187    if (RT_SUCCESS(rc))
     1188    {
     1189        rtLocalIpcSessionRetain(pThis);
     1190        if (pThis->Read.hActiveThread == NIL_RTTHREAD)
     1191        {
     1192            pThis->Read.hActiveThread = RTThreadSelf();
     1193
     1194            for (;;)
     1195            {
     1196                DWORD cbRead = 0;
     1197                if (!pThis->fCancelled)
     1198                {
     1199                    /*
     1200                     * Wait for pending zero byte read, if necessary.
     1201                     * Note! It cannot easily be cancelled due to concurrent current writes.
     1202                     */
     1203                    if (!pThis->fZeroByteRead)
     1204                    { /* likely */ }
     1205                    else
     1206                    {
     1207                        RTCritSectLeave(&pThis->CritSect);
     1208                        DWORD rcWait = WaitForSingleObject(pThis->Read.OverlappedIO.hEvent, 0);
     1209                        RTCritSectEnter(&pThis->CritSect);
     1210
     1211                        rc = rtLocalIpcWinGetZeroReadResult(pThis, rcWait);
     1212                        if (RT_SUCCESS(rc))
     1213                            continue;
     1214
     1215                        if (rc == VERR_TIMEOUT)
     1216                            rc = VINF_TRY_AGAIN;
     1217                        break;
     1218                    }
     1219
     1220                    /*
     1221                     * Figure out how much we can read (cannot try and cancel here
     1222                     * like in the anonymous pipe code).
     1223                     */
     1224                    DWORD cbAvailable;
     1225                    if (PeekNamedPipe(pThis->hNmPipe, NULL, 0, NULL, &cbAvailable, NULL))
     1226                    {
     1227                        if (cbAvailable == 0 || cbToRead == 0)
     1228                        {
     1229                            *pcbRead = 0;
     1230                            rc = VINF_TRY_AGAIN;
     1231                            break;
     1232                        }
     1233                    }
     1234                    else
     1235                    {
     1236                        rc = RTErrConvertFromWin32(GetLastError());
     1237                        break;
     1238                    }
     1239                    if (cbAvailable > cbToRead)
     1240                        cbAvailable = (DWORD)cbToRead;
     1241
     1242                    /*
     1243                     * Kick of a an overlapped read.  It should return immediately, so we
     1244                     * don't really need to leave the critsect here.
     1245                     */
     1246                    rc = ResetEvent(pThis->Read.OverlappedIO.hEvent); Assert(rc == TRUE);
     1247                    if (ReadFile(pThis->hNmPipe, pvBuf, cbAvailable, &cbRead, &pThis->Read.OverlappedIO))
     1248                    {
     1249                        *pcbRead = cbRead;
     1250                        rc = VINF_SUCCESS;
     1251                    }
     1252                    else if (GetLastError() == ERROR_IO_PENDING)
     1253                    {
     1254                        DWORD rcWait = WaitForSingleObject(pThis->Read.OverlappedIO.hEvent, 0);
     1255                        if (rcWait == WAIT_TIMEOUT)
     1256                        {
     1257                            RTCritSectLeave(&pThis->CritSect);
     1258                            rcWait = WaitForSingleObject(pThis->Read.OverlappedIO.hEvent, INFINITE);
     1259                            RTCritSectEnter(&pThis->CritSect);
     1260                        }
     1261                        if (GetOverlappedResult(pThis->hNmPipe, &pThis->Read.OverlappedIO, &cbRead, TRUE /*fWait*/))
     1262                        {
     1263                            *pcbRead = cbRead;
     1264                            rc = VINF_SUCCESS;
     1265                        }
     1266                        else
     1267                        {
     1268                            if (pThis->fCancelled)
     1269                                rc = VERR_CANCELLED;
     1270                            else
     1271                                rc = RTErrConvertFromWin32(GetLastError());
     1272                        }
     1273                    }
     1274                    else
     1275                    {
     1276                        rc = RTErrConvertFromWin32(GetLastError());
     1277                        AssertMsgFailedBreak(("%Rrc\n", rc));
     1278                    }
     1279                }
     1280                else
     1281                    rc = VERR_CANCELLED;
     1282                break;
    11671283            }
    11681284
  • trunk/src/VBox/Runtime/testcase/tstRTLocalIpc.cpp

    r58296 r58299  
    242242            RTTESTI_CHECK_RC(RTLocalIpcSessionWaitForData(hIpcSession, RT_MS_1MIN), VINF_SUCCESS);
    243243
    244 #ifndef RT_OS_WINDOWS
    245244            size_t cbRead;
    246245            char szCmd[64];
     
    250249                RTTestIFailed("cbRead=%zu, expected %zu; szCmd='%s', expected 'disconnect'\n",
    251250                              cbRead, sizeof("disconnect") - 1, szCmd);
    252 #endif
    253251
    254252            RTTESTI_CHECK_RC(RTLocalIpcSessionClose(hIpcSession), VINF_OBJECT_DESTROYED);
     
    285283    uint8_t abBuf[4];
    286284    size_t cbRead = _4M-1;
    287 #ifndef RT_OS_WINDOWS
    288285    RTTESTI_CHECK_RC(RTLocalIpcSessionReadNB(hClientSession, abBuf, sizeof(abBuf), &cbRead), VINF_TRY_AGAIN);
    289286    RTTESTI_CHECK(cbRead == 0);
    290 #endif
    291287
    292288    /* Trigger server disconnect. */
     
    310306        cbRead = _4M-1;
    311307        RTTESTI_CHECK_RC(RTLocalIpcSessionRead(hClientSession, abBuf, sizeof(abBuf), &cbRead), VERR_BROKEN_PIPE);
    312 #ifndef RT_OS_WINDOWS
    313308        cbRead = _1G/2;
    314309        RTTESTI_CHECK_RC(RTLocalIpcSessionReadNB(hClientSession, abBuf, sizeof(abBuf), &cbRead), VERR_BROKEN_PIPE);
    315 #endif
    316310
    317311        RTAssertSetMayPanic(fMayPanic);
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