VirtualBox

Changeset 11451 in vbox for trunk/src/VBox/Devices/Serial


Ignore:
Timestamp:
Aug 17, 2008 9:24:30 PM (17 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
34855
Message:

Host Serial: Hardware independent way of wking up the status line monitor thread

File:
1 edited

Legend:

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

    r11286 r11451  
    4848# include <sys/poll.h>
    4949# include <sys/ioctl.h>
     50# include <pthread.h>
     51# include <sys/signal.h>
    5052
    5153/*
     
    767769}
    768770
     771static void drvHostSerialSignalHandler(int iSignal)
     772{
     773    /* Do nothing. */
     774    return;
     775}
     776
    769777/**
    770778 * Unblock the monitor thread so it can respond to a state change.
     
    779787{
    780788    PDRVHOSTSERIAL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTSERIAL);
    781     int rc;
    782     unsigned int uSerialLineFlags;
    783     unsigned int uSerialLineStatus;
    784     unsigned int uIoctl;
     789    int rc = VINF_SUCCESS;
     790#if 0
     791     unsigned int uSerialLineFlags;
     792     unsigned int uSerialLineStatus;
     793     unsigned int uIoctl;
     794#endif
    785795
    786796    /*
    787797     * Linux is a bit difficult as the thread is sleeping in an ioctl call.
    788798     * So there is no way to have a wakeup pipe.
    789      * Thatswhy we set the serial device into loopback mode and change one of the
    790      * modem control bits.
    791      * This should make the ioctl call return.
     799     *
     800     * 1. Thatswhy we set the serial device into loopback mode and change one of the
     801     *    modem control bits.
     802     *    This should make the ioctl call return.
     803     *
     804     * 2. We still got reports about long shutdown times. It may bepossible
     805     *    that the loopback mode is not implemented on all devices.
     806     *    The next possible solution is to close the device file to make the ioctl
     807     *    return with EBADF and be able to suspend the thread.
     808     *
     809     * 3. The second approach doesn't work too, the ioctl doesn't return.
     810     *    But it seems that the ioctl is interruptible (return code in errno is EINTR).
     811     *    We get the native thread id of the PDM thread and send a signal with pthread_kill().
    792812     */
    793813
     814#if 0 /* Disabled because it does not work for all. */
    794815    /* Get current status of control lines. */
    795816    rc = ioctl(pThis->DeviceFile, TIOCMGET, &uSerialLineStatus);
     
    832853                                N_("Ioctl failed for serial host device '%s' (%Rrc). The device will not work properly"),
    833854                                pThis->pszDevicePath, RTErrConvertFromErrno(errno));
     855#endif
     856
     857#if 0
     858    /* Close file to make ioctl return. */
     859    RTFileClose(pData->DeviceFile);
     860    /* Open again to make use after suspend possible again. */
     861    rc = RTFileOpen(&pData->DeviceFile, pData->pszDevicePath, RTFILE_O_OPEN | RTFILE_O_READWRITE);
     862    AssertMsg(RT_SUCCESS(rc), ("Opening device file again failed rc=%Vrc\n", rc));
     863
     864    if (RT_FAILURE(rc))
     865        PDMDrvHlpVMSetRuntimeError(pDrvIns, false, "DrvHostSerialFail",
     866                                    N_("Opening failed for serial host device '%s' (%Vrc). The device will not work"),
     867                                    pData->pszDevicePath, rc);
     868#endif
     869
     870    pthread_t        ThreadId = (pthread_t)RTThreadGetNative(pThread->Thread);
     871    struct sigaction SigactionThread;
     872    struct sigaction SigactionThreadOld;
     873
     874    memset(&SigactionThread, 0, sizeof(struct sigaction));
     875    sigemptyset(&SigactionThread.sa_mask);
     876    SigactionThread.sa_flags = 0;
     877    SigactionThread.sa_handler = drvHostSerialSignalHandler;
     878    rc = sigaction(SIGUSR2, &SigactionThread, &SigactionThreadOld);
     879    if (rc < 0)
     880        PDMDrvHlpVMSetRuntimeError(pDrvIns, false, "DrvHostSerialFail",
     881                                    N_("Suspending serial monitor thread failed for serial device '%s' (%Vrc). The shutdown may take extremly long."),
     882                                    pThis->pszDevicePath, RTErrConvertFromErrno(errno));
     883
     884    rc = pthread_kill(ThreadId, SIGUSR2);
     885    if (rc < 0)
     886        PDMDrvHlpVMSetRuntimeError(pDrvIns, false, "DrvHostSerialFail",
     887                                    N_("Suspending serial monitor thread failed for serial device '%s' (%Vrc). The shutdown may take extremly long."),
     888                                    pThis->pszDevicePath, RTErrConvertFromErrno(rc));
     889
     890    /* Restore old action handler. */
     891    sigaction(SIGUSR2, &SigactionThreadOld, NULL);
     892
    834893    return VINF_SUCCESS;
    835894}
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