VirtualBox

Changeset 69897 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Dec 1, 2017 11:17:15 AM (7 years ago)
Author:
vboxsync
Message:

Runtime/serialport-posix: Updates

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/posix/serialport-posix.cpp

    r69896 r69897  
    9797    /** Flag whether the monitoring thread should shutdown. */
    9898    volatile bool       fMonThrdShutdown;
     99    /** Reading end of wakeup pipe. */
     100    int                 iFdPipeR;
     101    /** Writing end of wakeup pipe. */
     102    int                 iFdPipeW;
    99103    /** The current active config (we assume no one changes this behind our back). */
    100104    struct termios      PortCfg;
     
    119123typedef const RTSERIALPORTBRATECONVDESC *PCRTSERIALPORTBRATECONVDESC;
    120124
     125
    121126/*********************************************************************************************************************************
    122127*   Defined Constants And Macros                                                                                                 *
    123128*********************************************************************************************************************************/
    124129
     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
    125136
    126137
     
    424435
    425436/**
     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 */
     443DECLINLINE(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/**
    426454 * The status line monitor thread worker.
    427455 *
     
    471499            rcPsx = ioctl(pThis->iFd, TIOCMIWAIT, fStsLinesChk);
    472500            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            }
    474506            else if (rcPsx == -1 && errno != EINTR)
    475507                fPoll = true;
     
    486518                if (((fStsLines ^ fStsLinesOld) & fStsLinesChk))
    487519                {
    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
    489524                    fStsLinesOld = fStsLines;
    490525                }
     
    499534                 */
    500535                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                }
    502541
    503542                RTThreadSleep(100 /*ms*/);
     
    591630        if (pThis->iFd != -1)
    592631        {
    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)
    599636            {
    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);
    602664            }
     665            else
     666                rc = RTErrConvertFromErrno(errno);
    603667
    604668            close(pThis->iFd);
     
    633697
    634698    close(pThis->iFd);
     699    close(pThis->iFdPipeR);
     700    close(pThis->iFdPipeW);
    635701    RTMemFree(pThis);
    636702    return VINF_SUCCESS;
     
    770836RTDECL(int) RTSerialPortEvtPollInterrupt(RTSERIALPORT hSerialPort)
    771837{
    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);
    774843}
    775844
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