diff options
| author | michael <michael@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2017-08-15 09:55:18 +0000 |
|---|---|---|
| committer | michael <michael@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2017-08-15 09:55:18 +0000 |
| commit | 8751748ae3fa8a0430e2eb2f2424f6ef8d881cf2 (patch) | |
| tree | 89115ed22333a7b6849d79a07727254d07783749 /packages/fcl-process/examples | |
| parent | 31d7460603922a4608f7a23cc44b0eec0a3965d6 (diff) | |
| download | fpc-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.lpi | 67 | ||||
| -rw-r--r-- | packages/fcl-process/examples/threadedipc.lpr | 111 |
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. + |
