mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-29 03:31:32 +02:00
Fixed lazarus hanging when chmhelp pipe is leftover from an improperly closed lhelp
git-svn-id: trunk@37824 -
This commit is contained in:
parent
eea630f3bb
commit
ac177fc0e2
@ -23,6 +23,12 @@ unit lhelpcore;
|
|||||||
{$NOTE You can add http capability to lhelp by adding the lnetvisual package v0.6.3 or greater requirement to lhelp.}
|
{$NOTE You can add http capability to lhelp by adding the lnetvisual package v0.6.3 or greater requirement to lhelp.}
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
|
{$IFDEF UNIX}
|
||||||
|
{$if FPC_FULLVERSION <= 20700}
|
||||||
|
{$DEFINE STALE_PIPE_WORKAROUND}
|
||||||
|
{$ENDIF}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
{$mode objfpc}{$H+}
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
interface
|
interface
|
||||||
@ -219,6 +225,7 @@ procedure THelpForm.FormCreate(Sender: TObject);
|
|||||||
begin
|
begin
|
||||||
fContext := -1;
|
fContext := -1;
|
||||||
ReadCommandLineOptions;
|
ReadCommandLineOptions;
|
||||||
|
LoadPreferences(fServerName);
|
||||||
if fServerName <> '' then begin
|
if fServerName <> '' then begin
|
||||||
StartServer(fServerName);
|
StartServer(fServerName);
|
||||||
end;
|
end;
|
||||||
@ -237,7 +244,7 @@ begin
|
|||||||
if FHasShowed then
|
if FHasShowed then
|
||||||
Exit;
|
Exit;
|
||||||
FHasShowed := True;
|
FHasShowed := True;
|
||||||
LoadPreferences(fServerName);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure THelpForm.ForwardToolBtnClick(Sender: TObject);
|
procedure THelpForm.ForwardToolBtnClick(Sender: TObject);
|
||||||
@ -372,11 +379,15 @@ var
|
|||||||
begin
|
begin
|
||||||
fOutputIPC := TSimpleIPCClient.Create(nil);
|
fOutputIPC := TSimpleIPCClient.Create(nil);
|
||||||
fOutputIPC.ServerID := fServerName+'client';
|
fOutputIPC.ServerID := fServerName+'client';
|
||||||
fOutputIPC.Active := True;
|
if fOutputIPC.ServerRunning {$IFDEF STALE_PIPE_WORKAROUND} and not IPCPipeIsStale(fOutputIPC){$ENDIF}
|
||||||
|
then
|
||||||
|
fOutputIPC.Active := True;
|
||||||
|
|
||||||
Stream := TMemoryStream.Create;
|
Stream := TMemoryStream.Create;
|
||||||
Stream.WriteDWord(Response);
|
Stream.WriteDWord(Response);
|
||||||
fOutputIPC.SendMessage(mtUnknown, Stream);
|
|
||||||
|
if fOutputIPC.Active then
|
||||||
|
fOutputIPC.SendMessage(mtUnknown, Stream);
|
||||||
|
|
||||||
if fOutputIPC.Active then
|
if fOutputIPC.Active then
|
||||||
fOutputIPC.Active := False;
|
fOutputIPC.Active := False;
|
||||||
@ -474,6 +485,7 @@ end;
|
|||||||
|
|
||||||
procedure THelpForm.StartServer(ServerName: String);
|
procedure THelpForm.StartServer(ServerName: String);
|
||||||
begin
|
begin
|
||||||
|
|
||||||
fInputIPC := TSimpleIPCServer.Create(nil);
|
fInputIPC := TSimpleIPCServer.Create(nil);
|
||||||
fInputIPC.ServerID := ServerName;
|
fInputIPC.ServerID := ServerName;
|
||||||
fInputIPC.Global := True;
|
fInputIPC.Global := True;
|
||||||
|
@ -2,9 +2,18 @@ unit LHelpControl;
|
|||||||
|
|
||||||
{$mode objfpc}{$H+}
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
|
{$IFDEF UNIX}
|
||||||
|
{$if FPC_FULLVERSION <= 20700}
|
||||||
|
{$DEFINE STALE_PIPE_WORKAROUND}
|
||||||
|
{$ENDIF}
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
|
{$IFDEF STALE_PIPE_WORKAROUND}
|
||||||
|
BaseUnix,
|
||||||
|
{$ENDIF}
|
||||||
Classes, SysUtils, FileUtil, SimpleIPC, UTF8Process;
|
Classes, SysUtils, FileUtil, SimpleIPC, UTF8Process;
|
||||||
|
|
||||||
type
|
type
|
||||||
@ -48,7 +57,10 @@ type
|
|||||||
|
|
||||||
property ProcessWhileWaiting: TProcedureOfObject read FProcessWhileWaiting write FProcessWhileWaiting;
|
property ProcessWhileWaiting: TProcedureOfObject read FProcessWhileWaiting write FProcessWhileWaiting;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{$IFDEF STALE_PIPE_WORKAROUND}
|
||||||
|
function IPCPipeIsStale(AIPC: TSimpleIPC): Boolean;
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
@ -76,8 +88,12 @@ end;
|
|||||||
|
|
||||||
function TLHelpConnection.SendMessage(Stream: TStream): TLHelpResponse;
|
function TLHelpConnection.SendMessage(Stream: TStream): TLHelpResponse;
|
||||||
begin
|
begin
|
||||||
fServerOut.SendMessage(mtUnknown, Stream);
|
//try
|
||||||
Result := WaitForMsgResponse;
|
fServerOut.SendMessage(mtUnknown, Stream);
|
||||||
|
Result := WaitForMsgResponse;
|
||||||
|
//except
|
||||||
|
// on EIPCError do Result := srNoAnswer;
|
||||||
|
//end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TLHelpConnection.Create;
|
constructor TLHelpConnection.Create;
|
||||||
@ -97,9 +113,46 @@ begin
|
|||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{$IFDEF STALE_PIPE_WORKAROUND}
|
||||||
|
function IPCPipeIsStale(AIPC: TSimpleIPC): Boolean;
|
||||||
|
var
|
||||||
|
PipeName: String;
|
||||||
|
fd: cint;
|
||||||
|
begin
|
||||||
|
Result := False;
|
||||||
|
PipeName:='/tmp/'+AIPC.ServerID;
|
||||||
|
if (AIPC is TSimpleIPCServer) and (TSimpleIPCServer(AIPC).Global) and (TSimpleIPCServer(AIPC).InstanceID <> '') then
|
||||||
|
PipeName := PipeName +'-'+TSimpleIPCServer(AIPC).InstanceID;
|
||||||
|
|
||||||
|
// it's possible to have a stale file that is not open for reading which will
|
||||||
|
// cause fpOpen to hang/block later when .Active is set to true while it
|
||||||
|
// wait's for the pipe to be opened on the other end
|
||||||
|
|
||||||
|
// O_WRONLY | O_NONBLOCK causes fpOpen to return -1 if the file is not open for reading
|
||||||
|
// so in fact the 'server' is not running
|
||||||
|
fd := FpOpen(PipeName, O_WRONLY or O_NONBLOCK);
|
||||||
|
if fd = -1 then
|
||||||
|
begin
|
||||||
|
Result := True;
|
||||||
|
// delete the named pipe since it's orphaned
|
||||||
|
FpUnlink(PipeName);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
FpClose(fd);
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
{$ENDIF}
|
||||||
function TLHelpConnection.ServerRunning: Boolean;
|
function TLHelpConnection.ServerRunning: Boolean;
|
||||||
|
{$IFDEF STALE_PIPE_WORKAROUND}
|
||||||
|
{$ENDIF}
|
||||||
begin
|
begin
|
||||||
Result := (fServerOut<>nil) and (fServerOut.Active);
|
Result := (fServerOut<>nil) and (fServerOut.Active);
|
||||||
|
{$IFDEF STALE_PIPE_WORKAROUND}
|
||||||
|
if not Result then
|
||||||
|
Exit; // ==>
|
||||||
|
Result := not IPCPipeIsStale(fServerOut);
|
||||||
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TLHelpConnection.StartHelpServer(NameForServer: String;
|
function TLHelpConnection.StartHelpServer(NameForServer: String;
|
||||||
@ -109,13 +162,6 @@ var
|
|||||||
begin
|
begin
|
||||||
Result := False;
|
Result := False;
|
||||||
|
|
||||||
{$IFDEF Unix}
|
|
||||||
{$NOTE ToDo: fix simpleipc to allow changing the filenames, then fix this }
|
|
||||||
// clean up old files
|
|
||||||
DeleteFileUTF8('/tmp/lazhelp');
|
|
||||||
DeleteFileUTF8('/tmp/lazhelpclient');
|
|
||||||
{$ENDIF}
|
|
||||||
|
|
||||||
fServerIn.Active := False;
|
fServerIn.Active := False;
|
||||||
fServerIn.ServerID := NameForServer+'client';
|
fServerIn.ServerID := NameForServer+'client';
|
||||||
fServerIn.Global := True;
|
fServerIn.Global := True;
|
||||||
@ -123,7 +169,7 @@ begin
|
|||||||
|
|
||||||
fServerOut.Active := False;
|
fServerOut.Active := False;
|
||||||
fServerOut.ServerID := NameForServer;
|
fServerOut.ServerID := NameForServer;
|
||||||
if not fServerOut.ServerRunning then begin
|
if not ServerRunning then begin
|
||||||
with TProcessUTF8.Create(nil) do begin
|
with TProcessUTF8.Create(nil) do begin
|
||||||
CommandLine := ServerExe + ' --ipcname ' + NameForServer;
|
CommandLine := ServerExe + ' --ipcname ' + NameForServer;
|
||||||
Execute;
|
Execute;
|
||||||
@ -131,6 +177,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
// give the server some time to get started
|
// give the server some time to get started
|
||||||
for X := 0 to 40 do begin
|
for X := 0 to 40 do begin
|
||||||
|
// use fServerOut.ServerRunning here instead of Self.ServerRunning to avoid a race condition
|
||||||
if not fServerOut.ServerRunning then Sleep(200);
|
if not fServerOut.ServerRunning then Sleep(200);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user