Newsgroups : Borland : borland.public.delphi.nativeapi.win32 : 2006 Oct : incomplete or erroneus file reads, under heavy stress

www.cryer.info
Managed Newsgroup Archive

incomplete or erroneus file reads, under heavy stress

Subject:incomplete or erroneus file reads, under heavy stress
Posted by:"Lucian" (thanks@no.spam)
Date:17 Oct 2006 13:29:26

Hi,

I hope someone has an idea for my problem, cuz I am actually out of any.

I have this multithreaded app. It runs for days/weeeks - actually
I have to stop it when I upgrade crappy Windows. Among other
things it does, is it reads from a file a line like this:
ActionCode=1000, which will result in spawning a thread to do some
stuff. Now, from time to time, in a log window, the application is
telling me there was no ActionCode in the file (as if actually it read
ActionCode=). I do log stuff a lot to external files and the log looks
like this:

2006/10/11 14:40:50 Warning [368C - Requests]: "Invalid [ActionCode=""]
in file "94943.REQ". File name will differ in time.

But, I do have to ofencing file(s) and the file actually is correct, it
does have a valid code in it.

The offending code is as simple as this:

  WaitForFile( FileName );
  Params.Clear;
  Params.LoadFromFile( FileName );
  strCode := Params.Values[ 'ActionCode' ];
  intCode := StrToIntDef(strCode, INVALID_ACTION);
  if intCode = INVALID_ACTION then
  begin
    Alerter.AddException( EInvalidRequest.Create(
      Format( 'Invalid [ActionCode="%s"] in file "%s".', [strCode,
FileName] ) ), Self );
    DeleteFile( ChangeFileExt( FileName, '.BAD' ) );
    RenameFile( FileName, ChangeFileExt( FileName, '.BAD' ) );

INVALID_ACTION is a constant (-1) and the method WaitForFile is doing
something like this (trying to make sure the file, which is written by
other app, is ready):

      repeat
        Handle := FileOpen(FileName, fmOpenRead);
        if Handle = INVALID_HANDLE_VALUE then
          Sleep(25);
      until Handle <> INVALID_HANDLE_VALUE;


Now ... someone suggested I should look for bugy VCL LoadFromFile. I
did, and I can't see anything wrong there, but, just in case I replaced
the LoadFromFile call with something else:

procedure ReadFile2Strings(const AFileName: String; S: TStringList);
var
  fileHandle: THandle;
  filemapHandle: THandle;
  mapView: Pointer;
begin
  fileHandle := CreateFile(PChar(AFileName),
    GENERIC_READ, FILE_SHARE_READ, nil,
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if fileHandle <> INVALID_HANDLE_VALUE then
  try
    filemapHandle := CreateFileMapping(fileHandle, nil, PAGE_READONLY,
0, 0, nil);
    if filemapHandle <> 0 then
    try
      mapView := MapViewOfFile(filemapHandle, FILE_MAP_READ, 0, 0, 0);
      if mapView <> nil then
      try
        S.Text := PChar(mapView);
      finally
        UnmapViewOfFile(mapView);
      end;
    finally
      CloseHandle(filemapHandle);
    end;
  finally
    CloseHandle(fileHandle);
  end;
end;


But the problem remains. From time to time, the application can't find
the ActionCode in the file, even though the ActionCode is there
(checking with Notepad).

The code above runs in a secondary thread. The application runs few
4-500 threads at all times. OS is W2k and XPpro, lots of RAM, lots of
disk space. Intel 2.8 and 3 ghz. This hapened for months now.


If anyone experienced something similar and found a solution, I'll be
gratefull to hear it.


tia,

Lucian

Replies:

www.cryer.info
Managed Newsgroup Archive