summaryrefslogtreecommitdiff
path: root/packages/fcl-process/examples
diff options
context:
space:
mode:
authormichael <michael@3ad0048d-3df7-0310-abae-a5850022a9f2>2017-08-15 09:55:18 +0000
committermichael <michael@3ad0048d-3df7-0310-abae-a5850022a9f2>2017-08-15 09:55:18 +0000
commit8751748ae3fa8a0430e2eb2f2424f6ef8d881cf2 (patch)
tree89115ed22333a7b6849d79a07727254d07783749 /packages/fcl-process/examples
parent31d7460603922a4608f7a23cc44b0eec0a3965d6 (diff)
downloadfpc-8751748ae3fa8a0430e2eb2f2424f6ef8d881cf2.tar.gz
* Patch from Denis Kozlov to fix threaded server
git-svn-id: https://svn.freepascal.org/svn/fpc/trunk@36916 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'packages/fcl-process/examples')
-rw-r--r--packages/fcl-process/examples/threadedipc.lpi67
-rw-r--r--packages/fcl-process/examples/threadedipc.lpr111
2 files changed, 178 insertions, 0 deletions
diff --git a/packages/fcl-process/examples/threadedipc.lpi b/packages/fcl-process/examples/threadedipc.lpi
new file mode 100644
index 0000000000..42dd6a5de2
--- /dev/null
+++ b/packages/fcl-process/examples/threadedipc.lpi
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CONFIG>
+ <ProjectOptions>
+ <Version Value="10"/>
+ <PathDelim Value="\"/>
+ <General>
+ <Flags>
+ <MainUnitHasCreateFormStatements Value="False"/>
+ <MainUnitHasTitleStatement Value="False"/>
+ </Flags>
+ <SessionStorage Value="InProjectDir"/>
+ <MainUnit Value="0"/>
+ <Title Value="threadedipc"/>
+ <UseAppBundle Value="False"/>
+ <ResourceType Value="res"/>
+ </General>
+ <VersionInfo>
+ <StringTable ProductVersion=""/>
+ </VersionInfo>
+ <BuildModes Count="1">
+ <Item1 Name="Default" Default="True"/>
+ </BuildModes>
+ <PublishOptions>
+ <Version Value="2"/>
+ </PublishOptions>
+ <RunParams>
+ <local>
+ <FormatVersion Value="1"/>
+ </local>
+ </RunParams>
+ <Units Count="1">
+ <Unit0>
+ <Filename Value="threadedipc.lpr"/>
+ <IsPartOfProject Value="True"/>
+ </Unit0>
+ </Units>
+ </ProjectOptions>
+ <CompilerOptions>
+ <Version Value="11"/>
+ <PathDelim Value="\"/>
+ <Target>
+ <Filename Value="threadedipc"/>
+ </Target>
+ <SearchPaths>
+ <IncludeFiles Value="$(ProjOutDir)"/>
+ <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
+ </SearchPaths>
+ <Linking>
+ <Debugging>
+ <UseExternalDbgSyms Value="True"/>
+ </Debugging>
+ </Linking>
+ </CompilerOptions>
+ <Debugging>
+ <Exceptions Count="3">
+ <Item1>
+ <Name Value="EAbort"/>
+ </Item1>
+ <Item2>
+ <Name Value="ECodetoolError"/>
+ </Item2>
+ <Item3>
+ <Name Value="EFOpenError"/>
+ </Item3>
+ </Exceptions>
+ </Debugging>
+</CONFIG>
diff --git a/packages/fcl-process/examples/threadedipc.lpr b/packages/fcl-process/examples/threadedipc.lpr
new file mode 100644
index 0000000000..67f1b7411e
--- /dev/null
+++ b/packages/fcl-process/examples/threadedipc.lpr
@@ -0,0 +1,111 @@
+program ThreadedIPC;
+
+{$mode objfpc}{$H+}
+
+uses
+ {$IFDEF UNIX}cthreads,{$ENDIF}
+ SysUtils, Classes, Math, FGL, SimpleIPC;
+
+const
+ ServerUniqueID = '39693DC0-BD8B-4AAD-9D9B-387D37CD59FD';
+ ServerTimeout = 5000;
+ ClientDelayMin = 500;
+ ClientDelayMax = 3000;
+ ClientCount = 10;
+
+var
+ ServerThreaded: Boolean = True;
+
+type
+ TServerMessageHandler = class
+ public
+ procedure HandleMessage(Sender: TObject);
+ procedure HandleMessageQueued(Sender: TObject);
+ end;
+
+procedure TServerMessageHandler.HandleMessage(Sender: TObject);
+begin
+ WriteLn(TSimpleIPCServer(Sender).StringMessage);
+end;
+
+procedure TServerMessageHandler.HandleMessageQueued(Sender: TObject);
+begin
+ TSimpleIPCServer(Sender).ReadMessage;
+end;
+
+procedure ServerWorker;
+var
+ Server: TSimpleIPCServer;
+ MessageHandler: TServerMessageHandler;
+begin
+ WriteLn(Format('Starting server #%x', [GetThreadID]));
+ MessageHandler := TServerMessageHandler.Create;
+ Server := TSimpleIPCServer.Create(nil);
+ try
+ Server.ServerID := ServerUniqueID;
+ Server.Global := True;
+ Server.OnMessage := @MessageHandler.HandleMessage;
+ Server.OnMessageQueued := @MessageHandler.HandleMessageQueued;
+ Server.StartServer(ServerThreaded);
+ if ServerThreaded then
+ Sleep(ServerTimeout)
+ else
+ while Server.PeekMessage(ServerTimeout, True) do ;
+ except on E: Exception do
+ WriteLn('Server error: ' + E.Message);
+ end;
+ Server.Free;
+ MessageHandler.Free;
+ WriteLn(Format('Finished server #%x', [GetThreadID]));
+end;
+
+procedure ClientWorker;
+var
+ Client: TSimpleIPCClient;
+ Message: String;
+begin
+ WriteLn(Format('Starting client #%x', [GetThreadID]));
+ Client := TSimpleIPCClient.Create(nil);
+ try
+ Client.ServerID := ServerUniqueID;
+ while not Client.ServerRunning do
+ Sleep(100);
+ Client.Active := True;
+ Sleep(RandomRange(ClientDelayMin, ClientDelayMax));
+ Message := Format('Hello from client #%x', [GetThreadID]);
+ Client.SendStringMessage(Message);
+ except on E: Exception do
+ WriteLn('Client error: ' + E.Message);
+ end;
+ Client.Free;
+ WriteLn(Format('Finished client #%x', [GetThreadID]));
+end;
+
+type
+ TThreadList = specialize TFPGObjectList<TThread>;
+
+var
+ I: Integer;
+ Thread: TThread;
+ Threads: TThreadList;
+
+begin
+ Randomize;
+ WriteLn('Threaded server: ' + BoolToStr(ServerThreaded, 'YES', 'NO'));
+ Threads := TThreadList.Create(True);
+ try
+ Threads.Add(TThread.CreateAnonymousThread(@ServerWorker));
+ for I := 1 to ClientCount do
+ Threads.Add(TThread.CreateAnonymousThread(@ClientWorker));
+ for Thread in Threads do
+ begin
+ Thread.FreeOnTerminate := False;
+ Thread.Start;
+ end;
+ for Thread in Threads do
+ Thread.WaitFor;
+ finally
+ Threads.Free;
+ end;
+end.
+