VirtualBox

Changeset 12347 in vbox for trunk/src


Ignore:
Timestamp:
Sep 10, 2008 12:15:20 PM (16 years ago)
Author:
vboxsync
Message:

DrvHostSerial: poll is busted on darwin/x86, so use select for the receive waiting. Thread function SHALL return an failure status if they return out of order - fixed the receive thread function. TODO: check the rest. TODO: Check hHaltEventSem reset

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Serial/DrvHostSerial.cpp

    r12334 r12347  
    4646# include <string.h>
    4747# include <unistd.h>
    48 # include <sys/poll.h>
     48# ifdef RT_OS_DARWIN
     49#  include <sys/select.h>
     50# else
     51#  include <sys/poll.h>
     52# endif
    4953# include <sys/ioctl.h>
    5054# include <pthread.h>
     
    536540    size_t cbRemaining = 0; /* start by reading host data */
    537541    int rc = VINF_SUCCESS;
     542    int rcThread = VINF_SUCCESS;
    538543
    539544    if (pThread->enmState == PDMTHREADSTATE_INITIALIZING)
     
    541546
    542547#ifdef RT_OS_WINDOWS
    543     HANDLE haWait[2];
    544     haWait[0] = pThis->hEventRecv;
    545     haWait[1] = pThis->hHaltEventSem;
     548    HANDLE ahWait[2];
     549    ahWait[0] = pThis->hEventRecv;
     550    ahWait[1] = pThis->hHaltEventSem;
    546551#endif
    547552
     
    552557            /* Get a block of data from the host serial device. */
    553558
    554 #if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN)
     559#if defined(RT_OS_DARWIN) /* poll is broken on x86 darwin, returns POLLNVAL. */
     560            fdset RdSet;
     561            FDSET_ZERO(&RdSet);
     562            FDSET_SET(pThis->DeviceFile, &RdSet);
     563            FDSET_SET(pThis->WakeupPipeR, &RdSet);
     564            fdset XcptSet;
     565            FDSET_ZERO(&XcptSet);
     566            FDSET_SET(pThis->DeviceFile, &XcptSet);
     567            FDSET_SET(pThis->WakeupPipeR, &XcptSet);
     568            rc = select(RT_MAX(pThis->WakeupPipeR, pThis->DeviceFile) + 1, &RdSet, NULL, &XcptSet, NULL);
     569            if (rc == -1)
     570            {
     571                int err = errno;
     572                rcThread = RTErrConvertFromErrno(err);
     573                LogRel(("HostSerial#%d: select failed with errno=%d / %Rrc, terminating the worker thread.\n", pDrvIns->iInstance, err, rcThread));
     574                break;
     575            }
     576
     577            /* this might have changed in the meantime */
     578            if (pThread->enmState != PDMTHREADSTATE_RUNNING)
     579                break;
     580            if (rc == 0)
     581                continue;
     582
     583            /* drain the wakeup pipe */
     584            if (   FDSET_ISSET(pThis->WakeupPipeR, &RdSet)
     585                || FDSET_ISSET(pThis->WakeupPipeR, &XcptSet))
     586            {
     587                rc = RTFileRead(pThis->WakeupPipeR, abBuffer, 1, &cbRead);
     588                if (RT_FAILURE(rc))
     589                {
     590                    LogRel(("HostSerial#%d: draining the wakekup pipe failed with %Rrc, terminating the worker thread.\n", pDrvIns->iInstance, rc));
     591                    rcThread = rc;
     592                    break;
     593                }
     594                continue;
     595            }
     596
     597            /* read data from the serial port. */
     598            rc = RTFileRead(pThis->DeviceFile, abBuffer, sizeof(abBuffer), &cbRead);
     599            if (RT_FAILURE(rc))
     600            {
     601                LogRel(("HostSerial#%d: Read failed with %Rrc, terminating the worker thread.\n", pDrvIns->iInstance, rc));
     602                rcThread = rc;
     603                break;
     604            }
     605            cbRemaining = cbRead;
     606
     607#elif defined(RT_OS_LINUX)
    555608
    556609            size_t cbRead;
     
    565618            if (rc < 0)
    566619            {
    567                 /* poll failed for whatever reason */
     620                int err = errno;
     621                rcThread = RTErrConvertFromErrno(err);
     622                LogRel(("HostSerial#%d: poll failed with errno=%d / %Rrc, terminating the worker thread.\n", pDrvIns->iInstance, err, rcThread));
    568623                break;
    569624            }
     
    576631                    break;
    577632                /* notification to terminate -- drain the pipe */
    578                 char ch;
    579                 size_t cbRead;
    580                 RTFileRead(pThis->WakeupPipeR, &ch, 1, &cbRead);
     633                RTFileRead(pThis->WakeupPipeR, &abBuffer, 1, &cbRead);
    581634                continue;
    582635            }
     
    585638            {
    586639                LogRel(("HostSerial#%d: Read failed with %Rrc, terminating the worker thread.\n", pDrvIns->iInstance, rc));
     640                rcThread = rc;
    587641                break;
    588642            }
     
    602656                if (dwRet == ERROR_IO_PENDING)
    603657                {
    604                     dwRet = WaitForMultipleObjects(2, haWait, FALSE, INFINITE);
     658                    dwRet = WaitForMultipleObjects(2, ahWait, FALSE, INFINITE);
    605659                    if (dwRet != WAIT_OBJECT_0)
    606660                    {
     
    611665                else
    612666                {
    613                     LogRel(("HostSerial#%d: Wait failed with error %Rrc; terminating the worker thread.\n", pDrvIns->iInstance, RTErrConvertFromWin32(dwRet)));
     667                    rcThread = RTErrConvertFromWin32(dwRet);
     668                    LogRel(("HostSerial#%d: Wait failed with error %Rrc; terminating the worker thread.\n", pDrvIns->iInstance, rcThread));
    614669                    break;
    615670                }
     
    624679                if (!ReadFile(pThis->hDeviceFile, abBuffer, sizeof(abBuffer), &dwNumberOfBytesTransferred, &pThis->overlappedRecv))
    625680                {
    626                     LogRel(("HostSerial#%d: Read failed with error %Rrc; terminating the worker thread.\n", pDrvIns->iInstance, RTErrConvertFromWin32(GetLastError())));
     681                    rcThread = RTErrConvertFromWin32(GetLastError());
     682                    LogRel(("HostSerial#%d: Read failed with error %Rrc; terminating the worker thread.\n", pDrvIns->iInstance, rcThread));
    627683                    break;
    628684                }
     
    685741            {
    686742                LogRel(("HostSerial#%d: NotifyRead failed with %Rrc, terminating the worker thread.\n", pDrvIns->iInstance, rc));
     743                rcThread = rc;
    687744                break;
    688745            }
     
    690747    }
    691748
    692     return VINF_SUCCESS;
     749    return rcThread;
    693750}
    694751
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