mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
UPD: Use poll() thread for ipc (less cpu usage)
This commit is contained in:
parent
c3dbc04f08
commit
0153669ca7
5 changed files with 187 additions and 30 deletions
25
doc/COPYING.FPC.txt
Normal file
25
doc/COPYING.FPC.txt
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
This is the file COPYING.FPC, it applies to the Free Pascal Run-Time Library
|
||||
(RTL) and packages (packages) distributed by members of the Free Pascal
|
||||
Development Team.
|
||||
|
||||
The source code of the Free Pascal Runtime Libraries and packages are
|
||||
distributed under the Library GNU General Public License
|
||||
(see the file COPYING) with the following modification:
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent modules,
|
||||
and to copy and distribute the resulting executable under terms of your choice,
|
||||
provided that you also meet, for each linked independent module, the terms
|
||||
and conditions of the license of that module. An independent module is a module
|
||||
which is not derived from or based on this library. If you modify this
|
||||
library, you may extend this exception to your version of the library, but you are
|
||||
not obligated to do so. If you do not wish to do so, delete this exception
|
||||
statement from your version.
|
||||
|
||||
If you didn't receive a copy of the file COPYING, contact:
|
||||
Free Software Foundation
|
||||
675 Mass Ave
|
||||
Cambridge, MA 02139
|
||||
USA
|
||||
|
||||
145
src/platform/unix/upipeserver.pas
Normal file
145
src/platform/unix/upipeserver.pas
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
{
|
||||
Double Commander
|
||||
-------------------------------------------------------------------------
|
||||
Unix implementation of one-way IPC between 2 processes
|
||||
|
||||
Copyright (C) 2015 Alexander Koblov (alexx2000@mail.ru)
|
||||
|
||||
Based on simpleipc.inc from Free Component Library.
|
||||
Copyright (c) 2005 by Michael Van Canneyt, member of
|
||||
the Free Pascal development team
|
||||
|
||||
See the file COPYING.FPC.txt, included in this distribution,
|
||||
for details about the copyright.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
}
|
||||
|
||||
unit uPipeServer;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, SimpleIPC, BaseUnix;
|
||||
|
||||
Type
|
||||
|
||||
{ TPipeServerComm }
|
||||
|
||||
TPipeServerComm = Class(TIPCServerComm)
|
||||
Private
|
||||
FFileName: String;
|
||||
FStream: TFileStream;
|
||||
private
|
||||
procedure Handler(Sender: TObject);
|
||||
Public
|
||||
Constructor Create(AOWner : TSimpleIPCServer); override;
|
||||
Procedure StartServer; override;
|
||||
Procedure StopServer; override;
|
||||
Function PeekMessage(TimeOut : Integer) : Boolean; override;
|
||||
Procedure ReadMessage ; override;
|
||||
Function GetInstanceID : String;override;
|
||||
Property FileName : String Read FFileName;
|
||||
Property Stream : TFileStream Read FStream;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
uPollThread;
|
||||
|
||||
ResourceString
|
||||
SErrFailedToCreatePipe = 'Failed to create named pipe: %s';
|
||||
SErrFailedToRemovePipe = 'Failed to remove named pipe: %s';
|
||||
|
||||
type
|
||||
TUnixIPCServer = class(TSimpleIPCServer);
|
||||
|
||||
procedure TPipeServerComm.Handler(Sender: TObject);
|
||||
begin
|
||||
TThread.Synchronize(nil, @TUnixIPCServer(Owner).ReadMessage);
|
||||
end;
|
||||
|
||||
constructor TPipeServerComm.Create(AOWner: TSimpleIPCServer);
|
||||
|
||||
Var
|
||||
D : String;
|
||||
|
||||
begin
|
||||
inherited Create(AOWner);
|
||||
FFileName:=Owner.ServerID;
|
||||
If Not Owner.Global then
|
||||
FFileName:=FFileName+'-'+IntToStr(fpGetPID);
|
||||
D:='/tmp/'; // Change to something better later
|
||||
FFileName:=D+FFileName;
|
||||
end;
|
||||
|
||||
|
||||
procedure TPipeServerComm.StartServer;
|
||||
|
||||
const
|
||||
PrivateRights = S_IRUSR or S_IWUSR;
|
||||
GlobalRights = PrivateRights or S_IRGRP or S_IWGRP or S_IROTH or S_IWOTH;
|
||||
Rights : Array [Boolean] of Integer = (PrivateRights,GlobalRights);
|
||||
|
||||
begin
|
||||
If not FileExists(FFileName) then
|
||||
If (fpmkFifo(FFileName,438)<>0) then
|
||||
DoError(SErrFailedToCreatePipe,[FFileName]);
|
||||
FStream:=TFileStream.Create(FFileName,fmOpenReadWrite+fmShareDenyNone,Rights[Owner.Global]);
|
||||
AddPoll(FStream.Handle, POLLIN, @Handler, False);
|
||||
end;
|
||||
|
||||
procedure TPipeServerComm.StopServer;
|
||||
begin
|
||||
RemovePoll(FStream.Handle);
|
||||
FreeAndNil(FStream);
|
||||
if Not DeleteFile(FFileName) then
|
||||
DoError(SErrFailedtoRemovePipe,[FFileName]);
|
||||
end;
|
||||
|
||||
function TPipeServerComm.PeekMessage(TimeOut: Integer): Boolean;
|
||||
|
||||
Var
|
||||
FDS : TFDSet;
|
||||
|
||||
begin
|
||||
fpfd_zero(FDS);
|
||||
fpfd_set(FStream.Handle,FDS);
|
||||
Result:=fpSelect(FStream.Handle+1,@FDS,Nil,Nil,TimeOut)>0;
|
||||
end;
|
||||
|
||||
procedure TPipeServerComm.ReadMessage;
|
||||
|
||||
Var
|
||||
Count : Integer;
|
||||
Hdr : TMsgHeader;
|
||||
M : TStream;
|
||||
begin
|
||||
FStream.ReadBuffer(Hdr,SizeOf(Hdr));
|
||||
SetMsgType(Hdr.MsgType);
|
||||
Count:=Hdr.MsgLen;
|
||||
M:=MsgData;
|
||||
if count > 0 then
|
||||
begin
|
||||
M.Seek(0,soFrombeginning);
|
||||
M.CopyFrom(FStream,Count);
|
||||
end
|
||||
else
|
||||
M.Size := 0;
|
||||
end;
|
||||
|
||||
function TPipeServerComm.GetInstanceID: String;
|
||||
begin
|
||||
Result:=IntToStr(fpGetPID);
|
||||
end;
|
||||
|
||||
initialization
|
||||
DefaultIPCServerClass:= TPipeServerComm;
|
||||
|
||||
end.
|
||||
|
||||
|
|
@ -8,6 +8,7 @@ uses
|
|||
Classes, SysUtils, Unix, BaseUnix;
|
||||
|
||||
procedure AddPoll(fd: cint; events: cshort; handler: TNotifyEvent; CloseOnDestroy: Boolean = True);
|
||||
procedure RemovePoll(fd: cint);
|
||||
|
||||
implementation
|
||||
|
||||
|
|
@ -56,6 +57,20 @@ begin
|
|||
PollThread.AddPoll(fd, events, handler, CloseOnDestroy);
|
||||
end;
|
||||
|
||||
procedure RemovePoll(fd: cint);
|
||||
var
|
||||
Index: Integer;
|
||||
begin
|
||||
for Index:= 0 to PollThread.FCount - 1 do
|
||||
begin
|
||||
if PollThread.FDesc[Index].fd = fd then
|
||||
begin
|
||||
PollThread.FDesc[Index].events:= 0;
|
||||
Break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TPollThread }
|
||||
|
||||
procedure TPollThread.Clear(Sender: TObject);
|
||||
|
|
|
|||
|
|
@ -598,7 +598,7 @@ begin
|
|||
// This fd will get passed to poll()
|
||||
fd := udev_monitor_get_fd(udev_monitor);
|
||||
|
||||
AddPoll(fd, POLLIN, Handler, True);
|
||||
AddPoll(fd, POLLIN, Handler, False);
|
||||
|
||||
Print('Begin monitoring');
|
||||
end;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ type
|
|||
FServernameByUser: String;
|
||||
{$IF DEFINED(UNIX)}
|
||||
FMyProgramCreateSemaphore:Boolean;
|
||||
FPeekThread: TThreadID;
|
||||
{$ENDIF}
|
||||
|
||||
procedure OnNative(Sender: TObject);
|
||||
|
|
@ -70,28 +69,10 @@ uses
|
|||
{$IF DEFINED(MSWINDOWS)}
|
||||
Windows,
|
||||
{$ELSEIF DEFINED(UNIX)}
|
||||
ipc, baseunix,
|
||||
ipc, baseunix, uPipeServer,
|
||||
{$ENDIF}
|
||||
Forms, StrUtils, FileUtil, uGlobs, uDebug;
|
||||
|
||||
{$IF DEFINED(UNIX)}
|
||||
type
|
||||
TUnixIPCServer = class(TSimpleIPCServer) end;
|
||||
|
||||
function PeekMessage(Parameter: Pointer): PtrInt;
|
||||
var
|
||||
UnixIPC: TUnixIPCServer absolute Parameter;
|
||||
begin
|
||||
Result:= 0;
|
||||
while UnixIPC.Active do
|
||||
begin
|
||||
if UnixIPC.PeekMessage(100, False) then
|
||||
TThread.Synchronize(nil, @UnixIPC.ReadMessage);
|
||||
Sleep(1); // Fix crash under OS X
|
||||
end;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
{ TUniqueInstance }
|
||||
|
||||
procedure TUniqueInstance.OnNative(Sender: TObject);
|
||||
|
|
@ -268,9 +249,6 @@ begin
|
|||
FServerIPC.ServerID:= FInstanceName;
|
||||
FServerIPC.Global:= True;
|
||||
FServerIPC.StartServer;
|
||||
{$IF DEFINED(UNIX)}
|
||||
FPeekThread:= BeginThread(@PeekMessage, FServerIPC);
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
procedure TUniqueInstance.StopListen;
|
||||
|
|
@ -278,12 +256,6 @@ begin
|
|||
DisposeMutex;
|
||||
if FServerIPC = nil then Exit;
|
||||
FServerIPC.StopServer;
|
||||
{$IF DEFINED(UNIX)}
|
||||
DCDebug('Waiting for UniqueInstance thread');
|
||||
WaitForThreadTerminate(FPeekThread, 0);
|
||||
DCDebug('Close UniqueInstance thread');
|
||||
CloseThread(FPeekThread);
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
function TUniqueInstance.isAnotherDCRunningWhileIamRunning:boolean;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue