Jump to content

Primož Gabrijelčič

Members
  • Content Count

    167
  • Joined

  • Last visited

  • Days Won

    8

Posts posted by Primož Gabrijelčič


  1. 16 minutes ago, PatV said:

    Is it possible I have a race condition

    Yes. The answer does not depend on the rest of the statement 😞

     

    Thread pool does not get destroyed unless you destroy it in the code. 

     

    A thread from a thread pool does not get destroyed while it is running your code.

     

    You can process thread pool events to be informed when a thread will be destroyed: http://www.omnithreadlibrary.com/book/chap07.html#lowlevel-threadpool-monitoring


  2. OK, now for reals 🙂 

     

    (Sorry for the wrong answer before. You did not provide a test project so I did not open my Delphi at all and just guessed at the answer.)

     

    As the SetThreadDataFactory doesn't yet support anonymous method factory, your best bet is to use a singleton to store parameters and provide a factory.

     

    Just a sketch of a solution:

     

    type
      TThreadFactory = class
      public
        class var Handle: THandle;
        class function Make: IInterface;
      end;
    
      FConnectionPool := CreateThreadPool('Connection pool');
      TThreadFactory.Handle := aHandle;
      FConnectionPool.SetThreadDataFactory(TThreadFactory.Make);

     


  3. Ah, SetThreadDataFactory actually doesn't support taking an anonymous function as an argument. An oversight that I should fix in a future.

     

    So - pass a normal function or method name to SetThreadDataFactory, not an anonymous method.

     

    (And I will amend my answer to your previous question on that topic.)


  4. You can just use aConfig inside the anonymous function. Compiler will capture it for you.

     

    function TFConfig.CreateThreadPool(aHandle : THandle ; aConfig : rConnectionConfig ;  aValue: string) : iOmniThreadPool;
    begin
      result := otlThreadPool.CreateThreadPool(aValue);
      result.MaxExecuting := result.NumCores;
    
      result.SetThreadDataFactory
      (
        function: IInterface
         begin
           result:= MakeInterface(aHandle, aConfig); // implement MakeInterface 
         end
      );
    end;

     


  5. This works:

     

    program Project191;
    
    {$APPTYPE CONSOLE}
    
    {$R *.res}
    
    uses
      System.SysUtils,
      OtlCommon;
    
    type
      TpDataType  = (dtNone, dtInteger, dtDateTime, dtString, dtBlob);
    
      rParameter= record
        Field   : string;
        Value   : Variant;
        AsValue : TpDataType;
      end;
    
      TParameters = TArray<rParameter>;
    
    var
      params, params2: TParameters;
      ov: TOmniValue;
    
    begin
      SetLength(params, 2);
    
      params[0].Field := 'a'; params[0].Value := 1; params[0].AsValue := dtInteger;
      params[1].Field := 'b'; params[1].Value := Now; params[1].AsValue := dtDateTime;
    
      ov := TOmniValue.FromArray<rParameter>(params);
    
      params2 := ov.ToArray<rParameter>;
    end.

    You will have to convert 'array of rParameter' to 'TArray<rParameter>'. TOmniValue has special support (FromArray, ToArray) for the latter but not for the former.


  6. IDE Fix Pack 6.4.3 breaks compilation in Rio 10.3.2 for our flagship application. After compile or rebuild, I get

     

    [dcc32 Fatal Error] FAB .gRPC  . pas ( 265): F2084 Internal Error: AV0D0F16E4(0D080000)-R0000000C-0

     

    Wihout IDE Fix Pack, compilation works fine.

     

    Any suggestions?

     

    • Like 1

  7. Hi all,

     

    Somehow I think that the following code should compile, but it does not. It looks like the compiler uses the wrong `TCallback` definition when resolving the property. Am I correct or did I miss something and I'm just stupid?

     

    program Project184;
    
    {$APPTYPE CONSOLE}
    
    {$R *.res}
    
    uses
      System.SysUtils;
    
    type
      TCallback = reference to procedure (value: int64);
    
      TRunner = class
      public type
        TCallback = reference to procedure;
      strict private
        FOnCallback: TCallback;
      public
        procedure Run;
        property OnCallback: TCallback read FOnCallback write FOnCallback;
      end;
    
    procedure TRunner.Run;
    begin
      OnCallback(); // <-- E2035 Not enough actual parameters
    end;
    
    begin
    end.


    Delphi 10.3.1, in case this is a regression bug.


  8. Tricky, got me completely dazzled for a moment 🙂

     

    You are now generating new capture proc for each `I`. That `Proc`, however, is just a pointer. Now your code `Task.Invoke(procedure begin Proc(); end);` captures this `Proc` by value and executes the last stored value three times. 

     

    You should do it like this:

     

    function CaptureValue(Value: Integer): TOmniTaskInvokeFunction;
    begin
      Result := procedure begin Memo.Lines.add(Value.ToString); end;
    end;
    
    for I := 0 to 2 do
      begin
        Task.Invoke(CaptureValue(i));
      end;

     

×