Recent

Author Topic: [SOLVED] Components with console applications  (Read 5396 times)

Kurt

  • Jr. Member
  • **
  • Posts: 63
Re: [UNSOLVED] Components with console applications
« Reply #15 on: September 25, 2023, 01:04:45 am »
TFPTimer does the (same) job *period*
Oh, yes, I fully understand this.  My issue isn't that I can't figure out (or craft) a timer that works in my code within my project, my problem is that I've discovered that some component authors, even when making non-visual components, themselves used TTimer instead of TFPTimer.  In their defense, they probably weren't thinking about the widget set or that TTimer had no background support in nogui situations.

The problem when using these components in a nogui environment is that they are a mine field.  Your project will compile, and often it will at least partially run with no errors.  It's only when one of the non-visual components you use itself tries to make a TTimer class go active that you get an exception.  And sometimes the functionality that makes the component do that is a fringe functionality that may not be obvious or even tested for.

Anyway, rather than have to curate/port every non-visual component I ever use in nogui,  I updated the nogui interface with timer support in my installation.  It's interesting you brought up TFPTimer, since that's what I used (slightly modified) for the support.  Patches are attached in case anyone is interested.  It would have to be cleaned up to be used widely since I ruthlessly cheated with TFPTimer to make it work.

Kurt

  • Jr. Member
  • **
  • Posts: 63
Re: [SOLVED] Components with console applications
« Reply #16 on: September 26, 2023, 04:09:34 am »
I found a way to do my main "message loop" without actually having to do anything.

I had originally planned to periodically call WidgetSet.AppProcessMessages(), which for nogui just processes synchronize() on the main thread.  I discovered that if my main thread is waiting on another thread, then while its waiting any calls to synchronize() will interrupt the main thread and process immediately.  Automatically.  So I came up with a new sleep function I call LightSleep()

Code: Pascal  [Select][+][-]
  1. unit utilitiesunit;
  2. {$mode ObjFPC}{$H+}
  3.  
  4. interface
  5.  
  6. uses
  7.   Classes, SysUtils;
  8.  
  9. type
  10.  
  11. TWaitThread = class(TThread)
  12. protected
  13.   FDelay: integer;
  14. public
  15.   procedure Execute; override;
  16.   constructor Wait(delay: integer);
  17. end;
  18.  
  19. procedure LightSleep(delay: integer); inline;
  20.  
  21. implementation
  22.  
  23. procedure TWaitThread.Execute;
  24. begin
  25.   Self.Sleep(FDelay);
  26.   Terminate;
  27. end;
  28.  
  29. constructor TWaitThread.Wait(delay: integer);
  30. begin
  31.   inherited Create(true);
  32.   FDelay := delay;
  33.   Start();
  34.   WaitFor();
  35. end;
  36.  
  37. procedure LightSleep(delay: integer); inline;
  38. begin
  39.     TWaitThread.Wait(delay).Free;
  40. end;
  41.  
  42. end.
  43.  

When the main thread is in a LightSleep(), any timers that fire (or any other calls to synchronize) will process immediately, almost as if there were a dedicated message handling loop.

alpine

  • Hero Member
  • *****
  • Posts: 1303
Re: [SOLVED] Components with console applications
« Reply #17 on: September 26, 2023, 11:32:31 am »
That's  an utterly mindless way to call CheckSynchronize(100):
Code: Pascal  [Select][+][-]
  1. function TThread.WaitFor: Integer;
  2. begin
  3.   WRITE_DEBUG('waiting for thread ',ptruint(FHandle));
  4.   If (MainThreadID=GetCurrentThreadID) then
  5.     {
  6.      FFinished is set after DoTerminate, which does a synchronize of OnTerminate,
  7.      so make sure synchronize works (or indeed any other synchronize that may be
  8.      in progress)
  9.     }
  10.     While not FFinished do  
  11.       CheckSynchronize(100);
  12.   WaitFor := WaitForThreadTerminate(FHandle, 0);
  13.   { should actually check for errors in WaitForThreadTerminate, but no }
  14.   { error api is defined for that function                             }
  15.   FThreadReaped:=true;
  16.   WRITE_DEBUG('thread terminated');
  17. end;  

Just call it without creating stillborn threads.
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

Kurt

  • Jr. Member
  • **
  • Posts: 63
Re: [SOLVED] Components with console applications
« Reply #18 on: September 26, 2023, 10:39:37 pm »
That's  an utterly mindless way to call CheckSynchronize(100):

You're 100% right!  Lord, the Linux version of WaitFor() is the most asssuredly unfortunate way to implement that which one could think of.  I guess I should have checked it.  The Windows implementation is nicely done without any wheel spinning using WaitForMultipleObjects() and I just assumed the Linux version was properly implemented too.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5759
  • Compiler Developer
Re: [SOLVED] Components with console applications
« Reply #19 on: September 28, 2023, 10:56:29 pm »
That's  an utterly mindless way to call CheckSynchronize(100):

You're 100% right!  Lord, the Linux version of WaitFor() is the most asssuredly unfortunate way to implement that which one could think of.  I guess I should have checked it.  The Windows implementation is nicely done without any wheel spinning using WaitForMultipleObjects() and I just assumed the Linux version was properly implemented too.

The problem is that Linux does not provide a good way to wait for both a thread handle and a pthread_cond.

JuhaManninen

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4541
  • I like bugs.
Re: [UNSOLVED] Components with console applications
« Reply #20 on: October 04, 2023, 06:02:06 pm »
It would have to be cleaned up to be used widely since I ruthlessly cheated with TFPTimer to make it work.
If you figure out how to do it without changing FPC code, it could be applied to LCL NoGUI.
Mostly Lazarus trunk and FPC 3.2 on Manjaro Linux 64-bit.

Kurt

  • Jr. Member
  • **
  • Posts: 63
Re: [SOLVED] Components with console applications
« Reply #21 on: November 09, 2023, 05:44:51 pm »
The project I intended this all for is complete.  This issue turned out to be moot, since Indy ripped out its use of TTimer.

The project is AllCall, it's a cross-platform TCP/IP-over-http stream tunneler.  It's a client/server.  Client-side it acts as a local SOCKSv4/a server that your applications connect to.  It then talks to the AllCall server over your HTTP proxy and will work with virtually any HTTP proxy, no matter how basic (or restrictive).  It's beta quality now.

If you figure out how to do it without changing FPC code, it could be applied to LCL NoGUI.

It's easily doable.  I just need to basically duplicate TFPTimer within nogui.  If that's not an issue, I'll make another patch.

 

TinyPortal © 2005-2018