mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-11-07 09:29:25 +01:00
FpDebugServer: Moved handling of the console to a separate thread.
git-svn-id: trunk@49032 -
This commit is contained in:
parent
b56346b8fe
commit
46c90d4df2
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -1344,6 +1344,7 @@ components/fpdebug/app/fpd/fpdtype.pas svneol=native#text/pascal
|
|||||||
components/fpdebug/app/fpdd/fpdumpdwarf.lpi svneol=native#text/plain
|
components/fpdebug/app/fpdd/fpdumpdwarf.lpi svneol=native#text/plain
|
||||||
components/fpdebug/app/fpdd/fpdumpdwarf.lpr svneol=native#text/pascal
|
components/fpdebug/app/fpdd/fpdumpdwarf.lpr svneol=native#text/pascal
|
||||||
components/fpdebug/app/fpdserver/Info.plist svneol=native#text/plain
|
components/fpdebug/app/fpdserver/Info.plist svneol=native#text/plain
|
||||||
|
components/fpdebug/app/fpdserver/debugconsoleserver.pas svneol=native#text/plain
|
||||||
components/fpdebug/app/fpdserver/debuginoutputprocessor.pas svneol=native#text/plain
|
components/fpdebug/app/fpdserver/debuginoutputprocessor.pas svneol=native#text/plain
|
||||||
components/fpdebug/app/fpdserver/debugtcpserver.pas svneol=native#text/plain
|
components/fpdebug/app/fpdserver/debugtcpserver.pas svneol=native#text/plain
|
||||||
components/fpdebug/app/fpdserver/debugthread.pas svneol=native#text/plain
|
components/fpdebug/app/fpdserver/debugthread.pas svneol=native#text/plain
|
||||||
|
|||||||
104
components/fpdebug/app/fpdserver/debugconsoleserver.pas
Normal file
104
components/fpdebug/app/fpdserver/debugconsoleserver.pas
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
unit DebugConsoleServer;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes,
|
||||||
|
SysUtils,
|
||||||
|
debugthread,
|
||||||
|
DebugInOutputProcessor,
|
||||||
|
lazCollections,
|
||||||
|
syncobjs,
|
||||||
|
pipes;
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
TFpDebugEventQueue = specialize TLazThreadedQueue<TFpDebugEvent>;
|
||||||
|
|
||||||
|
{ TFpDebugConsoleServer }
|
||||||
|
|
||||||
|
TFpDebugConsoleServer = class(TThread, IFpDebugListener)
|
||||||
|
private
|
||||||
|
FDebugThread: TFpDebugThread;
|
||||||
|
FConnectionIdentifier: integer;
|
||||||
|
FInOutputProcessor: TJSonInOutputProcessor;
|
||||||
|
FEventQueue: TFpDebugEventQueue;
|
||||||
|
protected
|
||||||
|
procedure Execute; override;
|
||||||
|
public
|
||||||
|
constructor create(ADebugThread: TFpDebugThread);
|
||||||
|
function GetOrigin: string;
|
||||||
|
procedure SendEvent(AnEvent: TFpDebugEvent);
|
||||||
|
destructor Destroy; override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
{ TFpDebugConsoleServer }
|
||||||
|
|
||||||
|
procedure TFpDebugConsoleServer.Execute;
|
||||||
|
var
|
||||||
|
InputStream: TInputPipeStream;
|
||||||
|
DebugEvent: TFpDebugEvent;
|
||||||
|
CommandStr: string;
|
||||||
|
ACommand: TFpDebugThreadCommand;
|
||||||
|
b: char;
|
||||||
|
begin
|
||||||
|
InputStream:=TInputPipeStream.Create(StdInputHandle);
|
||||||
|
FInOutputProcessor := TJSonInOutputProcessor.create(FConnectionIdentifier, @FDebugThread.SendLogMessage);
|
||||||
|
FConnectionIdentifier := FDebugThread.AddListener(self);
|
||||||
|
try
|
||||||
|
while not terminated do
|
||||||
|
begin
|
||||||
|
if FEventQueue.PopItem(DebugEvent) = wrSignaled then
|
||||||
|
begin
|
||||||
|
writeln(FInOutputProcessor.EventToText(DebugEvent));
|
||||||
|
end;
|
||||||
|
while InputStream.NumBytesAvailable>0 do
|
||||||
|
begin
|
||||||
|
InputStream.Read(b,sizeof(b));
|
||||||
|
if b <> #10 then
|
||||||
|
CommandStr:=CommandStr+b
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
ACommand := FInOutputProcessor.TextToCommand(CommandStr);
|
||||||
|
if assigned(ACommand) then
|
||||||
|
FDebugThread.QueueCommand(ACommand);
|
||||||
|
CommandStr:='';
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
FDebugThread.RemoveListener(self);
|
||||||
|
FInOutputProcessor.Free;
|
||||||
|
InputStream.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TFpDebugConsoleServer.create(ADebugThread: TFpDebugThread);
|
||||||
|
begin
|
||||||
|
FEventQueue:=TFpDebugEventQueue.Create(100, INFINITE, 100);
|
||||||
|
FDebugThread:=ADebugThread;
|
||||||
|
inherited Create(false);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TFpDebugConsoleServer.GetOrigin: string;
|
||||||
|
begin
|
||||||
|
result := 'console'
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TFpDebugConsoleServer.SendEvent(AnEvent: TFpDebugEvent);
|
||||||
|
begin
|
||||||
|
FEventQueue.PushItem(AnEvent);
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TFpDebugConsoleServer.Destroy;
|
||||||
|
begin
|
||||||
|
FEventQueue.Free;
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
||||||
@ -37,7 +37,7 @@
|
|||||||
<PackageName Value="fpdebug"/>
|
<PackageName Value="fpdebug"/>
|
||||||
</Item2>
|
</Item2>
|
||||||
</RequiredPackages>
|
</RequiredPackages>
|
||||||
<Units Count="5">
|
<Units Count="6">
|
||||||
<Unit0>
|
<Unit0>
|
||||||
<Filename Value="fpdserver.lpr"/>
|
<Filename Value="fpdserver.lpr"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
@ -62,6 +62,11 @@
|
|||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
<UnitName Value="DebugInOutputProcessor"/>
|
<UnitName Value="DebugInOutputProcessor"/>
|
||||||
</Unit4>
|
</Unit4>
|
||||||
|
<Unit5>
|
||||||
|
<Filename Value="debugconsoleserver.pas"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="DebugConsoleServer"/>
|
||||||
|
</Unit5>
|
||||||
</Units>
|
</Units>
|
||||||
</ProjectOptions>
|
</ProjectOptions>
|
||||||
<CompilerOptions>
|
<CompilerOptions>
|
||||||
|
|||||||
@ -26,35 +26,22 @@ uses
|
|||||||
Classes,
|
Classes,
|
||||||
SysUtils,
|
SysUtils,
|
||||||
CustApp,
|
CustApp,
|
||||||
syncobjs,
|
|
||||||
pipes,
|
|
||||||
lazfglhash,
|
|
||||||
debugthread,
|
debugthread,
|
||||||
DebugThreadCommand,
|
DebugThreadCommand,
|
||||||
lazCollections,
|
|
||||||
DebugInOutputProcessor,
|
DebugInOutputProcessor,
|
||||||
DebugTCPServer;
|
DebugTCPServer,
|
||||||
|
DebugConsoleServer;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
TFpDebugEventQueue = specialize TLazThreadedQueue<TFpDebugEvent>;
|
|
||||||
|
|
||||||
{ TFPDServerApplication }
|
{ TFPDServerApplication }
|
||||||
|
|
||||||
TFPDServerApplication = class(TCustomApplication, IFpDebugListener)
|
TFPDServerApplication = class(TCustomApplication)
|
||||||
private
|
|
||||||
FEventQueue: TFpDebugEventQueue;
|
|
||||||
FInOutputProcessor: TCustomInOutputProcessor;
|
|
||||||
FConnectionIdentifier: integer;
|
|
||||||
protected
|
protected
|
||||||
procedure DoRun; override;
|
procedure DoRun; override;
|
||||||
public
|
public
|
||||||
constructor Create(TheOwner: TComponent); override;
|
constructor Create(TheOwner: TComponent); override;
|
||||||
destructor Destroy; override;
|
|
||||||
procedure WriteHelp; virtual;
|
procedure WriteHelp; virtual;
|
||||||
// IFpDebugListener
|
|
||||||
procedure SendEvent(AnEvent: TFpDebugEvent);
|
|
||||||
function GetOrigin: string;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TFPDServerApplication }
|
{ TFPDServerApplication }
|
||||||
@ -64,11 +51,10 @@ var
|
|||||||
ErrorMsg: String;
|
ErrorMsg: String;
|
||||||
DebugThread: TFpDebugThread;
|
DebugThread: TFpDebugThread;
|
||||||
DebugEvent: TFpDebugEvent;
|
DebugEvent: TFpDebugEvent;
|
||||||
InputStream: TInputPipeStream;
|
|
||||||
CommandStr: string;
|
|
||||||
TCPServerThread: TFpDebugTcpServer;
|
TCPServerThread: TFpDebugTcpServer;
|
||||||
|
ConsoleServerThread: TFpDebugConsoleServer;
|
||||||
ACommand: TFpDebugThreadCommand;
|
ACommand: TFpDebugThreadCommand;
|
||||||
b: char;
|
CommandStr: string;
|
||||||
begin
|
begin
|
||||||
// quick check parameters
|
// quick check parameters
|
||||||
ErrorMsg:=CheckOptions('hf', ['help']);
|
ErrorMsg:=CheckOptions('hf', ['help']);
|
||||||
@ -88,7 +74,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
DebugThread := TFpDebugThread.Instance;
|
DebugThread := TFpDebugThread.Instance;
|
||||||
|
|
||||||
TCPServerThread := TFpDebugTcpServer.Create(DebugThread);
|
TCPServerThread := TFpDebugTcpServer.Create(DebugThread);
|
||||||
|
ConsoleServerThread := TFpDebugConsoleServer.Create(DebugThread);
|
||||||
|
|
||||||
if HasOption('f') then
|
if HasOption('f') then
|
||||||
begin
|
begin
|
||||||
@ -107,79 +95,35 @@ begin
|
|||||||
CommandStr:='';
|
CommandStr:='';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
InputStream:=TInputPipeStream.Create(StdInputHandle);
|
while not Terminated do
|
||||||
|
begin
|
||||||
FConnectionIdentifier := DebugThread.AddListener(self);
|
try
|
||||||
FInOutputProcessor := TJSonInOutputProcessor.create(FConnectionIdentifier, @DebugThread.SendLogMessage);
|
CheckSynchronize(100);
|
||||||
try
|
except
|
||||||
|
on e: exception do
|
||||||
while not terminated do
|
writeln(StdErr, 'Exception: '+e.Message);
|
||||||
begin
|
end;
|
||||||
if FEventQueue.PopItem(DebugEvent) = wrSignaled then
|
end;
|
||||||
begin
|
|
||||||
writeln(FInOutputProcessor.EventToText(DebugEvent));
|
|
||||||
end;
|
|
||||||
while InputStream.NumBytesAvailable>0 do
|
|
||||||
begin
|
|
||||||
InputStream.Read(b,sizeof(b));
|
|
||||||
if b <> #10 then
|
|
||||||
CommandStr:=CommandStr+b
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
if CommandStr='q' then
|
|
||||||
Terminate
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
ACommand := FInOutputProcessor.TextToCommand(CommandStr);
|
|
||||||
if assigned(ACommand) then
|
|
||||||
DebugThread.QueueCommand(ACommand);
|
|
||||||
end;
|
|
||||||
CommandStr:='';
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
CheckSynchronize;
|
|
||||||
end;
|
|
||||||
|
|
||||||
DebugThread.RemoveListener(self);
|
|
||||||
|
|
||||||
finally
|
|
||||||
FInOutputProcessor.Free;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
|
ConsoleServerThread.Terminate;
|
||||||
TCPServerThread.StopListening;
|
TCPServerThread.StopListening;
|
||||||
|
|
||||||
|
ConsoleServerThread.WaitFor;
|
||||||
TCPServerThread.WaitFor;
|
TCPServerThread.WaitFor;
|
||||||
|
|
||||||
TCPServerThread.Free;
|
TCPServerThread.Free;
|
||||||
|
ConsoleServerThread.Free;
|
||||||
|
|
||||||
DebugThread.Terminate;
|
DebugThread.Terminate;
|
||||||
DebugThread.WaitFor;
|
DebugThread.WaitFor;
|
||||||
InputStream.Free;
|
|
||||||
|
|
||||||
terminate;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TFPDServerApplication.Create(TheOwner: TComponent);
|
constructor TFPDServerApplication.Create(TheOwner: TComponent);
|
||||||
begin
|
begin
|
||||||
inherited Create(TheOwner);
|
inherited Create(TheOwner);
|
||||||
FEventQueue:=TFpDebugEventQueue.Create(100, INFINITE, 100);
|
|
||||||
StopOnException:=True;
|
StopOnException:=True;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TFPDServerApplication.Destroy;
|
|
||||||
begin
|
|
||||||
FEventQueue.Free;
|
|
||||||
inherited Destroy;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TFPDServerApplication.SendEvent(AnEvent: TFpDebugEvent);
|
|
||||||
begin
|
|
||||||
FEventQueue.PushItem(AnEvent);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TFPDServerApplication.GetOrigin: string;
|
|
||||||
begin
|
|
||||||
result := 'console';
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TFPDServerApplication.WriteHelp;
|
procedure TFPDServerApplication.WriteHelp;
|
||||||
begin
|
begin
|
||||||
{ add your help code here }
|
{ add your help code here }
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user