Changeset 73635 in vbox for trunk/src/VBox
- Timestamp:
- Aug 13, 2018 1:01:07 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/win/serialport-win.cpp
r73630 r73635 60 60 /** The device handle. */ 61 61 HANDLE hDev; 62 /** The overlapped I/O structure. */ 63 OVERLAPPED Overlapped; 64 /** The event handle to wait on for the overlapped I/O operations of the device. */ 62 /** The overlapped write structure. */ 63 OVERLAPPED OverlappedWrite; 64 /** The overlapped read structure. */ 65 OVERLAPPED OverlappedRead; 66 /** The overlapped I/O structure when waiting on events. */ 67 OVERLAPPED OverlappedEvt; 68 /** The event handle to wait on for the overlapped event operations of the device. */ 65 69 HANDLE hEvtDev; 70 /** The event handle to wait on for the overlapped write operations of the device. */ 71 HANDLE hEvtWrite; 72 /** The event handle to wait on for the overlapped read operations of the device. */ 73 HANDLE hEvtRead; 66 74 /** The event handle to wait on for waking up waiting threads externally. */ 67 75 HANDLE hEvtIntr; … … 111 119 static int rtSerialPortWinUpdateEvtMask(PRTSERIALPORTINTERNAL pThis, uint32_t fEvtMask) 112 120 { 113 DWORD dwEvtMask = 0;121 DWORD dwEvtMask = EV_ERR; 114 122 115 123 if (fEvtMask & RTSERIALPORT_EVT_F_DATA_RX) … … 173 181 { 174 182 int rc = VINF_SUCCESS; 175 DWORD dwRc = WaitForSingleObject(pThis->Overlapped .hEvent, 0);183 DWORD dwRc = WaitForSingleObject(pThis->OverlappedWrite.hEvent, 0); 176 184 if (dwRc == WAIT_OBJECT_0) 177 185 { 178 186 DWORD cbWritten = 0; 179 if (GetOverlappedResult(pThis->hDev, &pThis->Overlapped , &cbWritten, TRUE))187 if (GetOverlappedResult(pThis->hDev, &pThis->OverlappedWrite, &cbWritten, TRUE)) 180 188 { 181 189 for (;;) … … 190 198 /* resubmit the remainder of the buffer - can this actually happen? */ 191 199 memmove(&pThis->pbBounceBuf[0], &pThis->pbBounceBuf[cbWritten], pThis->cbBounceBufUsed - cbWritten); 192 rc = ResetEvent(pThis->Overlapped .hEvent); Assert(rc == TRUE);200 rc = ResetEvent(pThis->OverlappedWrite.hEvent); Assert(rc == TRUE); 193 201 if (!WriteFile(pThis->hDev, pThis->pbBounceBuf, (DWORD)pThis->cbBounceBufUsed, 194 &cbWritten, &pThis->Overlapped ))202 &cbWritten, &pThis->OverlappedWrite)) 195 203 { 196 204 if (GetLastError() == ERROR_IO_PENDING) … … 245 253 pThis->cbBounceBufUsed = 0; 246 254 pThis->cbBounceBufAlloc = 0; 247 pThis->hEvtDev = CreateEvent(NULL, FALSE, FALSE, NULL); 255 RT_ZERO(pThis->OverlappedEvt); 256 RT_ZERO(pThis->OverlappedWrite); 257 RT_ZERO(pThis->OverlappedRead); 258 pThis->hEvtDev = CreateEvent(NULL, TRUE, FALSE, NULL); 248 259 if (pThis->hEvtDev) 249 260 { 250 pThis->Overlapped .hEvent = pThis->hEvtDev,261 pThis->OverlappedEvt.hEvent = pThis->hEvtDev, 251 262 pThis->hEvtIntr = CreateEvent(NULL, FALSE, FALSE, NULL); 252 263 if (pThis->hEvtIntr) 253 264 { 254 DWORD fWinFlags = 0; 255 256 if (fFlags & RTSERIALPORT_OPEN_F_WRITE) 257 fWinFlags |= GENERIC_WRITE; 258 if (fFlags & RTSERIALPORT_OPEN_F_READ) 259 fWinFlags |= GENERIC_READ; 260 261 pThis->hDev = CreateFile(pszPortAddress, 262 fWinFlags, 263 0, /* Must be opened with exclusive access. */ 264 NULL, /* No SECURITY_ATTRIBUTES structure. */ 265 OPEN_EXISTING, /* Must use OPEN_EXISTING. */ 266 FILE_FLAG_OVERLAPPED, /* Overlapped I/O. */ 267 NULL); 268 if (pThis->hDev) 265 pThis->hEvtWrite = CreateEvent(NULL, TRUE, TRUE, NULL); 266 if (pThis->hEvtWrite) 269 267 { 270 rc = rtSerialPortSetDefaultCfg(pThis); 271 if (RT_SUCCESS(rc)) 268 pThis->OverlappedWrite.hEvent = pThis->hEvtWrite; 269 pThis->hEvtRead = CreateEvent(NULL, TRUE, TRUE, NULL); 270 if (pThis->hEvtRead) 272 271 { 273 *phSerialPort = pThis; 274 return rc; 272 pThis->OverlappedRead.hEvent = pThis->hEvtRead; 273 DWORD fWinFlags = 0; 274 275 if (fFlags & RTSERIALPORT_OPEN_F_WRITE) 276 fWinFlags |= GENERIC_WRITE; 277 if (fFlags & RTSERIALPORT_OPEN_F_READ) 278 fWinFlags |= GENERIC_READ; 279 280 pThis->hDev = CreateFile(pszPortAddress, 281 fWinFlags, 282 0, /* Must be opened with exclusive access. */ 283 NULL, /* No SECURITY_ATTRIBUTES structure. */ 284 OPEN_EXISTING, /* Must use OPEN_EXISTING. */ 285 FILE_FLAG_OVERLAPPED, /* Overlapped I/O. */ 286 NULL); 287 if (pThis->hDev) 288 { 289 rc = rtSerialPortSetDefaultCfg(pThis); 290 if (RT_SUCCESS(rc)) 291 { 292 *phSerialPort = pThis; 293 return rc; 294 } 295 } 296 else 297 rc = RTErrConvertFromWin32(GetLastError()); 298 299 CloseHandle(pThis->hEvtRead); 275 300 } 301 302 CloseHandle(pThis->hEvtWrite); 276 303 } 277 else278 rc = RTErrConvertFromWin32(GetLastError());279 304 280 305 CloseHandle(pThis->hEvtIntr); … … 315 340 CloseHandle(pThis->hDev); 316 341 CloseHandle(pThis->hEvtDev); 342 CloseHandle(pThis->hEvtWrite); 343 CloseHandle(pThis->hEvtRead); 317 344 CloseHandle(pThis->hEvtIntr); 318 pThis->hDev = NULL; 319 pThis->hEvtDev = NULL; 320 pThis->hEvtIntr = NULL; 345 pThis->hDev = NULL; 346 pThis->hEvtDev = NULL; 347 pThis->hEvtWrite = NULL; 348 pThis->hEvtRead = NULL; 349 pThis->hEvtIntr = NULL; 321 350 RTMemFree(pThis); 322 351 return VINF_SUCCESS; … … 351 380 && RT_SUCCESS(rc)) 352 381 { 353 BOOL fSucc = ResetEvent(pThis->Overlapped .hEvent); Assert(fSucc == TRUE); RT_NOREF(fSucc);382 BOOL fSucc = ResetEvent(pThis->OverlappedRead.hEvent); Assert(fSucc == TRUE); RT_NOREF(fSucc); 354 383 DWORD cbRead = 0; 355 384 if (ReadFile(pThis->hDev, pbBuf, 356 385 cbToRead <= ~(DWORD)0 ? (DWORD)cbToRead : ~(DWORD)0, 357 &cbRead, &pThis->Overlapped ))386 &cbRead, &pThis->OverlappedRead)) 358 387 { 359 388 if (pcbRead) … … 366 395 else if (GetLastError() == ERROR_IO_PENDING) 367 396 { 368 DWORD dwWait = WaitForSingleObject(pThis->Overlapped .hEvent, INFINITE);397 DWORD dwWait = WaitForSingleObject(pThis->OverlappedRead.hEvent, INFINITE); 369 398 if (dwWait == WAIT_OBJECT_0) 370 399 { 371 if (GetOverlappedResult(pThis->hDev, &pThis->Overlapped , &cbRead, TRUE /*fWait*/))400 if (GetOverlappedResult(pThis->hDev, &pThis->OverlappedRead, &cbRead, TRUE /*fWait*/)) 372 401 { 373 402 if (pcbRead) … … 418 447 */ 419 448 int rc = VINF_SUCCESS; 420 BOOL fSucc = ResetEvent(pThis->Overlapped .hEvent); Assert(fSucc == TRUE); RT_NOREF(fSucc);449 BOOL fSucc = ResetEvent(pThis->OverlappedRead.hEvent); Assert(fSucc == TRUE); RT_NOREF(fSucc); 421 450 DWORD cbRead = 0; 422 451 if ( cbToRead == 0 423 452 || ReadFile(pThis->hDev, pvBuf, 424 453 cbToRead <= ~(DWORD)0 ? (DWORD)cbToRead : ~(DWORD)0, 425 &cbRead, &pThis->Overlapped ))454 &cbRead, &pThis->OverlappedRead)) 426 455 { 427 456 *pcbRead = cbRead; … … 431 460 { 432 461 if (!CancelIo(pThis->hDev)) 433 WaitForSingleObject(pThis->Overlapped .hEvent, INFINITE);434 if (GetOverlappedResult(pThis->hDev, &pThis->Overlapped , &cbRead, TRUE /*fWait*/))462 WaitForSingleObject(pThis->OverlappedRead.hEvent, INFINITE); 463 if (GetOverlappedResult(pThis->hDev, &pThis->OverlappedRead, &cbRead, TRUE /*fWait*/)) 435 464 { 436 465 *pcbRead = cbRead; … … 471 500 && RT_SUCCESS(rc)) 472 501 { 473 BOOL fSucc = ResetEvent(pThis->Overlapped .hEvent); Assert(fSucc == TRUE); RT_NOREF(fSucc);502 BOOL fSucc = ResetEvent(pThis->OverlappedWrite.hEvent); Assert(fSucc == TRUE); RT_NOREF(fSucc); 474 503 DWORD cbWritten = 0; 475 504 if (WriteFile(pThis->hDev, pbBuf, 476 505 cbToWrite <= ~(DWORD)0 ? (DWORD)cbToWrite : ~(DWORD)0, 477 &cbWritten, &pThis->Overlapped ))506 &cbWritten, &pThis->OverlappedWrite)) 478 507 { 479 508 if (pcbWritten) … … 486 515 else if (GetLastError() == ERROR_IO_PENDING) 487 516 { 488 DWORD dwWait = WaitForSingleObject(pThis->Overlapped .hEvent, INFINITE);517 DWORD dwWait = WaitForSingleObject(pThis->OverlappedWrite.hEvent, INFINITE); 489 518 if (dwWait == WAIT_OBJECT_0) 490 519 { 491 if (GetOverlappedResult(pThis->hDev, &pThis->Overlapped , &cbWritten, TRUE /*fWait*/))520 if (GetOverlappedResult(pThis->hDev, &pThis->OverlappedWrite, &cbWritten, TRUE /*fWait*/)) 492 521 { 493 522 if (pcbWritten) … … 562 591 563 592 /* Submit the write. */ 564 rc = ResetEvent(pThis->Overlapped .hEvent); Assert(rc == TRUE);593 rc = ResetEvent(pThis->OverlappedWrite.hEvent); Assert(rc == TRUE); 565 594 DWORD cbWritten = 0; 566 595 if (WriteFile(pThis->hDev, pThis->pbBounceBuf, (DWORD)pThis->cbBounceBufUsed, 567 &cbWritten, &pThis->Overlapped ))596 &cbWritten, &pThis->OverlappedWrite)) 568 597 { 569 598 *pcbWritten = RT_MIN(cbWritten, cbToWrite); /* paranoia^3 */ … … 750 779 rc = rtSerialPortWinUpdateEvtMask(pThis, fEvtMask); 751 780 781 /* 782 * EV_RXCHAR is triggered only if a byte is received after the event mask is set, 783 * not if there is already something in the input buffer. Thatswhy we check the input 784 * buffer for any stored data and the output buffer whether it is empty and return 785 * the appropriate flags. 786 */ 787 if (RT_SUCCESS(rc)) 788 { 789 COMSTAT ComStat; RT_ZERO(ComStat); 790 if (!ClearCommError(pThis->hDev, NULL, &ComStat)) 791 return RTErrConvertFromWin32(GetLastError()); 792 793 /* Check whether data is already waiting in the input buffer. */ 794 if ( (fEvtMask & RTSERIALPORT_EVT_F_DATA_RX) 795 && ComStat.cbInQue > 0) 796 *pfEvtsRecv |= RTSERIALPORT_EVT_F_DATA_RX; 797 798 /* Check whether the output buffer is empty. */ 799 if ( (fEvtMask & RTSERIALPORT_EVT_F_DATA_TX) 800 && ComStat.cbOutQue == 0) 801 *pfEvtsRecv |= RTSERIALPORT_EVT_F_DATA_TX; 802 803 /* Return if there is at least one event. */ 804 if (*pfEvtsRecv != 0) 805 return VINF_SUCCESS; 806 } 807 752 808 if (RT_SUCCESS(rc)) 753 809 { … … 757 813 ahWait[1] = pThis->hEvtIntr; 758 814 759 RT_ZERO(pThis->Overlapped );760 pThis->Overlapped .hEvent = pThis->hEvtDev;761 762 if (!WaitCommEvent(pThis->hDev, &dwEventMask, &pThis->Overlapped ))815 RT_ZERO(pThis->OverlappedEvt); 816 pThis->OverlappedEvt.hEvent = pThis->hEvtDev; 817 818 if (!WaitCommEvent(pThis->hDev, &dwEventMask, &pThis->OverlappedEvt)) 763 819 { 764 820 DWORD dwRet = GetLastError();
Note:
See TracChangeset
for help on using the changeset viewer.