static NTSTATUS NTAPI Send_Byte(PCONTROLLER_INFO ControllerInfo, UCHAR Byte) /* * FUNCTION: Send a byte from the host to the controller's FIFO * ARGUMENTS: * ControllerInfo: Info structure for the controller we're writing to * Offset: Offset over the controller's base address that we're writing to * Byte: Byte to write to the bus * RETURNS: * STATUS_SUCCESS if the byte was written 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 * - PAGED_CODE, because we spin for more than the Microsoft-recommended * maximum. * - This function is necessary because sometimes the FIFO reacts slowly * and isn't yet ready to read or write the next byte */ { int i; PAGED_CODE(); for(i = 0; i < 5; i++) { if(ReadyForWrite(ControllerInfo)) break; KeStallExecutionProcessor(50); } if (i < 5) { WRITE_PORT_UCHAR(ControllerInfo->BaseAddress + FIFO, Byte); return STATUS_SUCCESS; } else { INFO_(FLOPPY, "Send_Byte: timed out trying to write\n"); HwDumpRegisters(ControllerInfo); return STATUS_UNSUCCESSFUL; } }
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(); } }