Changeset 69897 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Dec 1, 2017 11:17:15 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/posix/serialport-posix.cpp
r69896 r69897 97 97 /** Flag whether the monitoring thread should shutdown. */ 98 98 volatile bool fMonThrdShutdown; 99 /** Reading end of wakeup pipe. */ 100 int iFdPipeR; 101 /** Writing end of wakeup pipe. */ 102 int iFdPipeW; 99 103 /** The current active config (we assume no one changes this behind our back). */ 100 104 struct termios PortCfg; … … 119 123 typedef const RTSERIALPORTBRATECONVDESC *PCRTSERIALPORTBRATECONVDESC; 120 124 125 121 126 /********************************************************************************************************************************* 122 127 * Defined Constants And Macros * 123 128 *********************************************************************************************************************************/ 124 129 130 /** The event poller was woken up due to an external interrupt. */ 131 #define RTSERIALPORT_WAKEUP_PIPE_REASON_INTERRUPT 0x0 132 /** The event poller was woken up due to a change in the monitored status lines. */ 133 #define RTSERIALPORT_WAKEUP_PIPE_REASON_STS_LINE_CHANGED 0x1 134 /** The monitor thread encoutnered repeating errors querying the status lines and terminated. */ 135 #define RTSERIALPORT_WAKEUP_PIPE_REASON_STS_LINE_MONITOR_FAILED 0x2 125 136 126 137 … … 424 435 425 436 /** 437 * Wakes up any thread polling for a serial port event with the given reason. 438 * 439 * @returns IPRT status code. 440 * @param pThis The internal serial port instance data. 441 * @param bWakeupReason The wakeup reason to pass to the event poller. 442 */ 443 DECLINLINE(int) rtSerialPortWakeupEvtPoller(PRTSERIALPORTINTERNAL pThis, uint8_t bWakeupReason) 444 { 445 int rcPsx = write(pThis->iFdPipeW, &bWakeupReason, 1); 446 if (rcPsx != 1) 447 return RTErrConvertFromErrno(errno); 448 449 return VINF_SUCCESS; 450 } 451 452 453 /** 426 454 * The status line monitor thread worker. 427 455 * … … 471 499 rcPsx = ioctl(pThis->iFd, TIOCMIWAIT, fStsLinesChk); 472 500 if (!rcPsx) 473 { /** @todo Notify any event waiter. */ } 501 { 502 rc = rtSerialPortWakeupEvtPoller(pThis, RTSERIALPORT_WAKEUP_PIPE_REASON_STS_LINE_CHANGED); 503 if (RT_FAILURE(rc)) 504 break; 505 } 474 506 else if (rcPsx == -1 && errno != EINTR) 475 507 fPoll = true; … … 486 518 if (((fStsLines ^ fStsLinesOld) & fStsLinesChk)) 487 519 { 488 /** @todo Notify any event waiter. */ 520 rc = rtSerialPortWakeupEvtPoller(pThis, RTSERIALPORT_WAKEUP_PIPE_REASON_STS_LINE_CHANGED); 521 if (RT_FAILURE(rc)) 522 break; 523 489 524 fStsLinesOld = fStsLines; 490 525 } … … 499 534 */ 500 535 if (cStsLineGetErrors++ >= 10) 501 { /** @todo Send error notification */ } 536 { 537 rc = RTErrConvertFromErrno(errno); 538 rtSerialPortWakeupEvtPoller(pThis, RTSERIALPORT_WAKEUP_PIPE_REASON_STS_LINE_MONITOR_FAILED); 539 break; 540 } 502 541 503 542 RTThreadSleep(100 /*ms*/); … … 591 630 if (pThis->iFd != -1) 592 631 { 593 rc = rtSerialPortSetDefaultCfg(pThis); 594 if ( RT_SUCCESS(rc) 595 && (fFlags & RT_SERIALPORT_OPEN_F_SUPPORT_STATUS_LINE_MONITORING)) 596 rc = rtSerialPortMonitorThreadCreate(pThis); 597 598 if (RT_SUCCESS(rc)) 632 /* Create wakeup pipe for the event API. */ 633 int aPipeFds[2]; 634 int rcPsx = pipe(&aPipeFds[0]); 635 if (!rcPsx) 599 636 { 600 *phSerialPort = pThis; 601 return VINF_SUCCESS; 637 /* Make the pipes close on exec. */ 638 pThis->iFdPipeR = aPipeFds[0]; 639 pThis->iFdPipeW = aPipeFds[1]; 640 641 if (fcntl(pThis->iFdPipeR, F_SETFD, FD_CLOEXEC)) 642 rc = RTErrConvertFromErrno(errno); 643 644 if ( RT_SUCCESS(rc) 645 && fcntl(pThis->iFdPipeW, F_SETFD, FD_CLOEXEC)) 646 rc = RTErrConvertFromErrno(errno); 647 648 if (RT_SUCCESS(rc)) 649 { 650 rc = rtSerialPortSetDefaultCfg(pThis); 651 if ( RT_SUCCESS(rc) 652 && (fFlags & RT_SERIALPORT_OPEN_F_SUPPORT_STATUS_LINE_MONITORING)) 653 rc = rtSerialPortMonitorThreadCreate(pThis); 654 655 if (RT_SUCCESS(rc)) 656 { 657 *phSerialPort = pThis; 658 return VINF_SUCCESS; 659 } 660 } 661 662 close(pThis->iFdPipeR); 663 close(pThis->iFdPipeW); 602 664 } 665 else 666 rc = RTErrConvertFromErrno(errno); 603 667 604 668 close(pThis->iFd); … … 633 697 634 698 close(pThis->iFd); 699 close(pThis->iFdPipeR); 700 close(pThis->iFdPipeW); 635 701 RTMemFree(pThis); 636 702 return VINF_SUCCESS; … … 770 836 RTDECL(int) RTSerialPortEvtPollInterrupt(RTSERIALPORT hSerialPort) 771 837 { 772 RT_NOREF(hSerialPort); 773 return VERR_NOT_IMPLEMENTED; 838 PRTSERIALPORTINTERNAL pThis = hSerialPort; 839 AssertPtrReturn(pThis, VERR_INVALID_PARAMETER); 840 AssertReturn(pThis->u32Magic == RTSERIALPORT_MAGIC, VERR_INVALID_HANDLE); 841 842 return rtSerialPortWakeupEvtPoller(pThis, RTSERIALPORT_WAKEUP_PIPE_REASON_INTERRUPT); 774 843 } 775 844
Note:
See TracChangeset
for help on using the changeset viewer.