| 531 | |
| 532 | |
| 533 | void cSocketThreads::cSocketThread::WriteToSockets(fd_set * a_Write) |
| 534 | { |
| 535 | // Write to available client sockets: |
| 536 | cCSLock Lock(m_Parent->m_CS); |
| 537 | for (int i = m_NumSlots - 1; i >= 0; --i) |
| 538 | { |
| 539 | cSocket::xSocket Socket = m_Slots[i].m_Socket.GetSocket(); |
| 540 | if (!cSocket::IsValidSocket(Socket) || !FD_ISSET(Socket, a_Write)) |
| 541 | { |
| 542 | continue; |
| 543 | } |
| 544 | if (m_Slots[i].m_Outgoing.empty()) |
| 545 | { |
| 546 | // Request another chunk of outgoing data: |
| 547 | if (m_Slots[i].m_Client != NULL) |
| 548 | { |
| 549 | AString Data; |
| 550 | m_Slots[i].m_Client->GetOutgoingData(Data); |
| 551 | m_Slots[i].m_Outgoing.append(Data); |
| 552 | } |
| 553 | if (m_Slots[i].m_Outgoing.empty()) |
| 554 | { |
| 555 | // No outgoing data is ready |
| 556 | if (m_Slots[i].m_State == sSlot::ssWritingRestOut) |
| 557 | { |
| 558 | m_Slots[i].m_State = sSlot::ssShuttingDown; |
| 559 | m_Slots[i].m_Socket.ShutdownReadWrite(); |
| 560 | } |
| 561 | continue; |
| 562 | } |
| 563 | } // if (outgoing data is empty) |
| 564 | |
| 565 | if (m_Slots[i].m_State == sSlot::ssRemoteClosed) |
| 566 | { |
| 567 | continue; |
| 568 | } |
| 569 | |
| 570 | if (!SendDataThroughSocket(m_Slots[i].m_Socket, m_Slots[i].m_Outgoing)) |
| 571 | { |
| 572 | int Err = cSocket::GetLastError(); |
| 573 | LOGWARNING("Error %d while writing to client \"%s\", disconnecting. \"%s\"", Err, m_Slots[i].m_Socket.GetIPString().c_str(), GetOSErrorString(Err).c_str()); |
| 574 | m_Slots[i].m_Socket.CloseSocket(); |
| 575 | if (m_Slots[i].m_Client != NULL) |
| 576 | { |
| 577 | m_Slots[i].m_Client->SocketClosed(); |
| 578 | } |
| 579 | continue; |
| 580 | } |
| 581 | |
| 582 | if (m_Slots[i].m_Outgoing.empty() && (m_Slots[i].m_State == sSlot::ssWritingRestOut)) |
| 583 | { |
| 584 | m_Slots[i].m_State = sSlot::ssShuttingDown; |
| 585 | m_Slots[i].m_Socket.ShutdownReadWrite(); |
| 586 | } |
| 587 | |
| 588 | // _X: If there's data left, it means the client is not reading fast enough, the server would unnecessarily spin in the main loop with zero actions taken; so signalling is disabled |
| 589 | // This means that if there's data left, it will be sent only when there's incoming data or someone queues another packet (for any socket handled by this thread) |
| 590 | /* |
nothing calls this directly
no test coverage detected