Hello, I implemented -almost- the same mechanism as THttpCli as Francois said. The timer runs per every 100ms and the code is below:
void __fastcall httpServerThread::TimerResume(TObject *Sender) { if(resumeTimerTick % (10 * 8) == 0) { serverPermissions->resetConsumedSpeedLimit(); httpServerClientClass *bufferClient; for(int i = 0; i < HTTPServer->ClientCount; ++i) { bufferClient = (httpServerClientClass*)HTTPServer->Client[i]; if(!bufferClient->bandwidthPermissions) continue; if(bufferClient->paused) { bufferClient->paused = false; PostThreadMessage(bufferClient->affinityThread->ThreadID, WM_RESUME_CLIENT, (WPARAM)bufferClient, 0); } } } else { httpServerClientClass *bufferClient; for(int i = 0; i < HTTPServer->ClientCount; ++i) { bufferClient = (httpServerClientClass*)HTTPServer->Client[i]; if(!bufferClient->bandwidthPermissions) continue; if(!bufferClient->paused) { if(bufferClient->bandwidthPermissions->isSpeedLimitReached()) { bufferClient->paused = true; //bufferClient->Pause(); PostThreadMessage(bufferClient->affinityThread->ThreadID, WM_PAUSE_CLIENT, (WPARAM)bufferClient, 0); } } PostThreadMessage(bufferClient->affinityThread->ThreadID, WM_CLIENT_TIMER, (WPARAM)bufferClient, 0); } } ++resumeTimerTick; } //--------------------------------------------------------------------------- When the throttling is enabled, the CPU usage goes to 100%. Aqtime code profiler tells me that the below function is the reason of it: procedure TCustomWSocket.TryToSend; var oBuffer : TBuffer; Len : Integer; Count : Integer; Data : Pointer; LastError : Integer; { p : PChar;23/12/01} bMore : Boolean; // Hit Count : 29731 // Time : 19,86 // Time with Children : 22,74 begin if (FHSocket = INVALID_SOCKET) or { No more socket } (FBufList.Count = 0) { Nothing to send } {or (bMoreFlag and (nMoreCnt >= nMoreMax))23/12/01} { Waiting more signal } then begin bAllSent := True; exit; end; bMore := TRUE; while bMore do begin oBuffer := FBufList.First; Data := oBuffer.Peek(Len); if Len <= 0 then begin { Buffer is empty } if FBufList.Count <= 1 then begin { Every thing has been sent } bAllSent := TRUE; bMore := FALSE; end else begin oBuffer.Free; FBufList.Delete(0); FBufList.Pack; end; end else begin Count := RealSend(Data, Len); if Count > 0 then begin Dec(FBufferedByteCount, Count); { V5.20 } if FBufferedByteCount < 0 then FBufferedByteCount := 0; end; if Count = 0 then bMore := FALSE { Closed by remote } else if count = SOCKET_ERROR then begin LastError := WSocket_Synchronized_WSAGetLastError; if (LastError = WSAECONNRESET) or (LastError = WSAENOTSOCK) or (LastError = WSAENOTCONN) or (LastError = WSAEINVAL) or (LastError = WSAECONNABORTED) { 07/05/99 } then begin {$IFDEF DEBUG_OUTPUT} OutputDebugString(Name + ' Winsock.Send failed ' + IntToStr(LastError)); {$ENDIF} FCloseInvoked := TRUE; { 23/07/98 } Close; TriggerSessionClosed(LastError); { 23/07/98 } end else if LastError <> WSAEWOULDBLOCK then begin SocketError('TryToSend failed'); Exit; end; bMore := FALSE; end else begin oBuffer.Remove(Count); if Count < Len then begin { Could not write as much as we wanted. Stop sending } {$IFDEF DELPHI1} { A bug in some Trumpet Winsock implementation break he } { background sending. Jan Tomasek <[EMAIL PROTECTED]> } if not TrumpetCompability then begin {bWrite := FALSE;23/12/01} bMore := FALSE; end; {$ELSE} {bWrite := FALSE;23/12/01} bMore := FALSE; {$ENDIF} end; end; end; end; end; Any idea why the bottle neck is? One interesting problem, the throttling cannot slow it any slower than 2.5 MBps! (local test) When the throttling is shut down, the timer still runs but it is not paused/resumed and the CPU usage is less than 5%. Regards, SZ -- To unsubscribe or change your settings for TWSocket mailing list please goto http://www.elists.org/mailman/listinfo/twsocket Visit our website at http://www.overbyte.be