You are not logged in.
Pages: 1
SynCommons.pas
descript:
strspnsse42('gggggg', '0123456789abcdefghi') return 0, should be 6
reson:
function strspnsse42(s,accept: pointer): integer;
asm // eax=s, edx=accept
push edi
push esi
push ebx
mov edi, eax
mov esi, edx
mov ebx, esi
xor ecx, ecx
@1: {$ifdef HASAESNI}
movdqu xmm2, dqword [edi]
movdqu xmm1, dqword [esi]
pcmpistrm xmm1, xmm2, $00 // find in set, return bit mask in xmm0
movd eax, xmm0
{$else}
db $F3,$0F,$6F,$17
db $F3,$0F,$6F,$0E
db $66,$0F,$3A,$62,$CA,$00
db $66,$0F,$7E,$C0
{$endif}
jns @5
@2: cmp ax, -1
jne @3
add edi, 16 // first 16 chars matched, continue with next 16 chars
add ecx, 16
jmp @1
@3: not eax
bsf eax, eax
add eax, ecx
pop ebx
pop esi
pop edi
ret
//*****************************************************************************************************************
@4: and eax, edx // accumulate matches <-------------------------------------- should be or eax, edx
//*****************************************************************************************************************
@5: add esi, 16 // the set is more than 16 bytes
{$ifdef HASAESNI}
movdqu xmm1, [esi]
pcmpistrm xmm1, xmm2, $00
movd edx, xmm0
{$else}
db $F3,$0F,$6F,$0E
db $66,$0F,$3A,$62,$CA,$00
db $66,$0F,$7E,$C2
{$endif}
jns @4
mov esi, ebx // restore set pointer
//*****************************************************************************************************************
and eax, edx // accumulate matches <------------------------------------- should be or eax, edx
//*****************************************************************************************************************
jmp @2
end;
function strspnsse42(s,accept: pointer): integer;
{$ifdef FPC}nostackframe; assembler; asm {$else}
asm // rcx=s, rdx=accept (Linux: rdi,rsi)
.noframe
{$endif FPC}
{$ifdef win64}
push rdi
push rsi
mov rdi, rcx
mov rsi, rdx
{$endif}mov r8, rsi
xor ecx, ecx
@1: movdqu xmm2, [rdi]
movdqu xmm1, [rsi]
{$ifdef HASAESNI}
pcmpistrm xmm1, xmm2, $00 // find in set, return bit mask in xmm0
{$else}
db $66,$0F,$3A,$62,$CA,$00
{$endif}
movd eax, xmm0
jns @5
@2: cmp ax, -1
jne @3
add rdi, 16 // first 16 chars matched, continue with next 16 chars
add rcx, 16
jmp @1
@3: not eax
bsf eax, eax
add rax, rcx
{$ifdef win64}
pop rsi
pop rdi
{$endif}ret
//*****************************************************************************************************************
@4: and eax, edx // accumulate matches <-------------------------------------- should be or eax, edx
//*****************************************************************************************************************
@5: add rsi, 16 // the set is more than 16 bytes
movdqu xmm1, [rsi]
{$ifdef HASAESNI}
pcmpistrm xmm1, xmm2, $00
{$else}
db $66,$0F,$3A,$62,$CA,$00
{$endif}
movd edx, xmm0
jns @4
mov rsi, r8 // restore set pointer
//*****************************************************************************************************************
and eax, edx // accumulate matches <-------------------------------------- should be or eax, edx
//*****************************************************************************************************************
jmp @2
end;
thanks
PRecInitData = TypInfo.PRecInitData;
D:\svncheck\dmustache.git\trunk\SynFPCTypInfo.pas(92,26) Error: (5000) Identifier not found "PRecInitData"
D:\svncheck\dmustache.git\trunk\SynFPCTypInfo.pas(92,38) Error: (5007) Error in type definition
D:\svncheck\dmustache.git\trunk\SynFPCTypInfo.pas(94,1) Fatal: (10026) There were 2 errors compiling module, stopping
Fatal: (1018) Compilation aborted
Error: D:\lazarus\fpc\3.0.4\bin\x86_64-win64\ppcx64.exe returned an error exitcode
I'm sorry.
The advantage of this is that the thread is not blocked
It also improves performance by more than 100%
I added a worker thread pool to httpapiserver
My code looks something like this
type
PSynWorkItem = ^TSynWorkItem;
TSynWorkItem = record
FContext: TObject;
FProc: TNotifyEvent;
end;
function SynWorkItemFunction(lpThreadParameter: Pointer): Integer; stdcall;
var
W: PSynWorkItem;
begin
Result := 0;
W := PSynWorkItem(lpThreadParameter);
try
W^.FProc(W.FContext);
finally
W^.FContext.Free;
end;
end;
function THttpApiServer.GetContext: THttpServerRequest;
var
HttpResult: HRESULT;
ReqID: HTTP_REQUEST_ID;
//RequestBuffer: TBytes;
ReqBuf, RemoteIP: SockString;
Req: PHTTP_REQUEST;
BytesRead: Cardinal;
Done: boolean;
begin
// MS recomendation: 4K for normal buffers, plus 12K for authentication headers if used
//SetLength(RequestBuffer, 4096);
SetLength(ReqBuf,16384+sizeof(HTTP_REQUEST)); // space for Req^ + 16 KB of headers
Req := pointer(ReqBuf);
ReqID := 0;
Done := false;
repeat
BytesRead := 0;
HttpResult := Http.ReceiveHttpRequest(fReqQueue,ReqID,0,Req^,length(ReqBuf),BytesRead, nil);
if HttpResult = ERROR_MORE_DATA then
begin
ReqID := Req^.RequestId;
SetLength(ReqBuf, BytesRead);
Req := pointer(ReqBuf);
end
else
if (HttpResult = ERROR_INVALID_PARAMETER) and (ReqID <> 0) then
begin
ReqID := 0;
end
else
if (HttpResult = ERROR_CONNECTION_INVALID) and (ReqID <> 0) then
begin
ReqID := 0;
end
else
Done := true;
until Done;
// Check for operation aborted - this might mean the server was interrupted
// so we should not raise an exception, but rather return nil
if HttpResult = ERROR_OPERATION_ABORTED then
Exit(nil);
//HttpCheck(HttpResult);
if HttpResult<>0 then
Exit(nil);
Result := THttpServerRequest.Create(Self, 0, Self);
Result.fReqBuf := ReqBuf;
Result.fReqBufLen := BytesRead;
end;
procedure THttpApiServer.Execute;
var
WorkItem: TSynWorkItem;
LContext: THttpServerRequest;
begin
//ExecuteEx;
// THttpServerGeneric thread preparation: launch any OnHttpThreadStart event
NotifyThreadStart(self);
try
repeat
LContext := GetContext;
if (LContext <> nil) and not Terminated then
begin
WorkItem.FContext := LContext;
WorkItem.FProc := DoProcessContext;
Winapi.Windows.QueueUserWorkItem(SynWorkItemFunction, @WorkItem, 0);
end;
if Terminated then
break;
until Terminated;
finally
//Context.Free;
//fExecuteFinished := true;
end;
end;
procedure THttpApiServer.DoProcessContext(LContext: THttpServerRequest;);
begin
...
Recvbody and sendresponse
end;
step1 send head
POST / HTTP/1.1
Host: 127.0.0.1:8080
Connection: Keep-Alive
Keep-Alive: 900
Content-Length: 90000000
CONTENT-Type: application/x-www-form-urlencoded
Accept: */*
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
next
for i=0 to 90000000
begin
send('A');
sleep(300);
end;
The server thread is blocked
Is this a bug or a trap?
Thank you. If you create an engine in advance, you might want to create an object pool.
error code is
frt := PJSRuntime(nil).New(FManager.MaxPerEngineMemory, $01000000, nil);
if frt = nil then
raise ESMException.Create('Create runtime: out of memory');
frt is nil
Why use SyNode in the ISAPI to Create the Create runtime: out of memory?
But SM24 doesn't.
MyCode
procedure TWebModule1.WebModule1DefaultHandlerAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
fEngineManager := TSMEngineManager.Create('');
try
fEngine := fEngineManager.ThreadSafeEngine(nil);
Response.Content :=
'<html>' +
'<head><title>Web Server Application</title></head>' +
'<body>Web Server Application</body>' +
'</html>';
fEngineManager.ReleaseCurrentThreadEngine;
finally
fEngineManager.Free;
end;
end;
Pages: 1