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

Reply via email to