void SocketOutputStream::write(const char* s, size_t offset, size_t length) { //wprintf(stderr,TEXT("write(char*='%s',offset=%d,length=%d)\n"),s,offset,length); m_socket->write(s + offset, length); }
unsigned sendData(const UdpPermitToSendMsg &permit, bool isLocal, TokenBucket *bucket, bool &moreRequested, unsigned &maxPackets) { moreRequested = false; maxPackets = permit.max_data; PointerArray toSend; unsigned totalSent = cleanRetryData(permit, toSend); while (toSend.length() < maxPackets && dataQueued()) { DataBuffer *buffer = popQueuedData(); if (buffer) // Aborted slave queries leave NULL records on queue { UdpPacketHeader *header = (UdpPacketHeader*) buffer->data; toSend.append(buffer); totalSent += header->length; #ifdef __linux__ if (isLocal && (totalSent> 100000)) break; #endif } } maxPackets = toSend.length(); for (unsigned idx = 0; idx < maxPackets; idx++) { DataBuffer *buffer = (DataBuffer *) toSend.item(idx); UdpPacketHeader *header = (UdpPacketHeader*) buffer->data; bool isRetry = (header->udpSequence != 0); if (isRetry) { if (checkTraceLevel(TRACE_RETRY_DATA, 1)) DBGLOG("UdpSender: Resending packet to destination node %u sequence %u", permit.destNodeIndex, header->udpSequence); atomic_inc(&packetsRetried); } else header->udpSequence = nextUdpSequence(); unsigned length = header->length; if (bucket) { MTIME_SECTION(timer, "bucket_wait"); bucket->wait((length / 1024)+1); } try { if (udpSendCompletedInData) { if (idx == maxPackets-1) { // MORE - is this safe ? Any other thread looking at the data right now? Don't _think_ so... if (false && dataQueued()) // Causes some problems because no flow control info gets through at all { moreRequested = true; header->udpSequence |= (UDP_SEQUENCE_COMPLETE|UDP_SEQUENCE_MORE); } else header->udpSequence |= UDP_SEQUENCE_COMPLETE; } } #ifdef _SIMULATE_LOST_PACKETS if (isRetry || (header->udpSequence % 100) != 0) #endif data_socket->write(buffer->data, length); header->udpSequence &= ~UDP_SEQUENCE_BITS; } catch(IException *e) { StringBuffer s; DBGLOG("UdpSender: write exception - write(%p, %u) - %s", buffer->data, length, e->errorMessage(s).str()); e->Release(); } catch(...) { DBGLOG("UdpSender: write exception - unknown exception"); } if (!isRetry && maxRetryData) { unsigned slot = (retryDataIdx + retryDataCount) % maxRetryData; if (retryDataCount < maxRetryData) retryDataCount++; else { if (udpTraceLevel > 0) DBGLOG("Overflow in resend packet buffer for destination node %u - discarding packet sequence %u", permit.destNodeIndex, header->udpSequence); ::Release(retryData[slot]); } retryData[slot] = buffer; } else { ::Release(buffer); } } return totalSent; }