Ejemplo n.º 1
0
static NTSTATUS NTAPI
Get_Byte(PCONTROLLER_INFO ControllerInfo, PUCHAR Byte)
/*
 * FUNCTION: Read a byte from the controller to the host
 * ARGUMENTS:
 *     ControllerInfo: Info structure for the controller we're reading from
 *     Offset: Offset over the controller's base address  that we're reading from
 *     Byte: Byte to read from the bus
 * RETURNS:
 *     STATUS_SUCCESS if the byte was read successfully
 *     STATUS_UNSUCCESSFUL if not
 * NOTES:
 *     - Function designed after flowchart in intel datasheet
 *     - 250us max delay.  Note that this is exactly 5 times longer
 *       than Microsoft recommends stalling the processor
 *     - Remember that we can be interrupted here, so this might
 *       take much more wall clock time than 250us
 *     - PAGED_CODE because we spin for longer than Microsoft recommends
 */
{
    int i;

    PAGED_CODE();

    for(i = 0; i < 5; i++)
    {
        if(ReadyForRead(ControllerInfo))
            break;

        KeStallExecutionProcessor(50);
    }

    if (i < 5)
    {
        *Byte = READ_PORT_UCHAR(ControllerInfo->BaseAddress + FIFO);
        return STATUS_SUCCESS;
    }
    else
    {
        INFO_(FLOPPY, "Get_Byte: timed out trying to write\n");
        HwDumpRegisters(ControllerInfo);
        return STATUS_UNSUCCESSFUL;
    }
}
Ejemplo n.º 2
0
void SocketManager::MainLoop()
{
    // remove evironment values passed by systemd
    sd_listen_fds(1);

    // Daemon is ready to work.
    sd_notify(0, "READY=1");

    m_working = true;
    while (m_working) {
        fd_set readSet = m_readSet;
        fd_set writeSet = m_writeSet;

        timeval localTempTimeout;
        timeval *ptrTimeout = &localTempTimeout;

        // I need to extract timeout from priority_queue.
        // Timeout in priority_queue may be deprecated.
        // I need to find some actual one.
        while (!m_timeoutQueue.empty()) {
            auto &top = m_timeoutQueue.top();
            auto &desc = m_socketDescriptionVector[top.sock];

            if (top.time == desc.timeout) {
                // This timeout matches timeout from socket.
                // It can be used.
                break;
            } else {
                // This socket was used after timeout in priority queue was set up.
                // We need to update timeout and find some useable one.
                Timeout tm = { desc.timeout , top.sock};
                m_timeoutQueue.pop();
                m_timeoutQueue.push(tm);
            }
        }

        if (m_timeoutQueue.empty()) {
            LogDebug("No usaable timeout found.");
            ptrTimeout = NULL; // select will wait without timeout
        } else {
            time_t currentTime = time(NULL);
            auto &pqTimeout = m_timeoutQueue.top();

            // 0 means that select won't block and socket will be closed ;-)
            ptrTimeout->tv_sec =
              currentTime < pqTimeout.time ? pqTimeout.time - currentTime : 0;
            ptrTimeout->tv_usec = 0;
        }

        int ret = select(m_maxDesc+1, &readSet, &writeSet, NULL, ptrTimeout);

        if (0 == ret) { // timeout
            Assert(!m_timeoutQueue.empty());

            Timeout pqTimeout = m_timeoutQueue.top();
            m_timeoutQueue.pop();

            auto &desc = m_socketDescriptionVector[pqTimeout.sock];

            if (!desc.isTimeout() || !desc.isOpen()) {
                // Connection was closed. Timeout is useless...
                desc.setTimeout(false);
                continue;
            }

            if (pqTimeout.time < desc.timeout) {
                // Is it possible?
                // This socket was used after timeout. We need to update timeout.
                pqTimeout.time = desc.timeout;
                m_timeoutQueue.push(pqTimeout);
                continue;
            }

            // timeout from m_timeoutQueue matches with socket.timeout
            // and connection is open. Time to close it!
            // Putting new timeout in queue here is pointless.
            desc.setTimeout(false);
            CloseSocket(pqTimeout.sock);

            // All done. Now we should process next select ;-)
            continue;
        }

        if (-1 == ret) {
            switch (errno) {
            case EINTR:
                LogDebug("EINTR in select");
                break;
            default:
                int err = errno;
                LogError("Error in select: " << GetErrnoString(err));
                return;
            }
            continue;
        }
        for (int i = 0; i < m_maxDesc+1 && ret; ++i) {
            if (FD_ISSET(i, &readSet)) {
                ReadyForRead(i);
                --ret;
            }
            if (FD_ISSET(i, &writeSet)) {
                ReadyForWrite(i);
                --ret;
            }
        }
        ProcessQueue();
    }
}