unit PrimeRangeThread;

interface

uses
  Classes, BlockToAsyncBuf;

type
  TPrimeRangeThread = class(TThread)
  private
    { Private declarations }
    FBuf: TBlockToAsyncBuf;
  protected
    function IsPrime(TestNum: integer): boolean;
    procedure Execute; override;
  public
  published
    property Buf: TBlockToAsyncBuf read FBuf write FBuf;
  end;

  TRangeRequestType = record
    Low, High: integer;
  end;

  PRangeRequestType = ^TRangeRequestType;

  { Results returned in a string list }

implementation

uses SysUtils;

{ TPrimeRangeThread }

function TPrimeRangeThread.IsPrime(TestNum: integer): boolean;

var
  iter: integer;

begin
  result := true;
  if TestNum < 0 then
    result := false;
  if TestNum <= 2 then
    exit;
  iter := 2;
  while (iter < TestNum) and (not terminated) do {Line A}
  begin
    if (TestNum mod iter) = 0 then
    begin
      result := false;
      exit;
    end;
    Inc(iter);
  end;
end;

procedure TPrimeRangeThread.Execute;

var
  PRange: PRangeRequestType;
  TestNum: integer;
  Results: TStringList;

begin
  while not Terminated do
  begin
    PRange := PRangeRequestType(FBuf.BlockingRead);
    if Assigned(PRange) then
    begin
      Assert(PRange.Low <= PRange.High);
      Results := TStringList.Create;
      Results.Add('Primes from: ' + IntToStr(PRange.Low) +
        ' to: ' + IntToStr(PRange.High));
      for TestNum := PRange.Low to PRange.High do
      begin
        if IsPrime(TestNum) then
          Results.Add(IntToStr(TestNum) + ' is prime.');
      end;
      if not FBuf.BlockingWrite(Results) then
      begin
        Results.Free;
        Terminate;
      end;
    end
    else Terminate;
  end;
end;

end.