My point of view after looking at the code.


 This code is not thread safe.



Discussion

gtest.sflag := inttostr(gtest.nflag) ; -> will call fpc_AnsiStr_To_ShortStr



fpc_AnsiStr_To_ShortStr is programmed as :



procedure fpc_AnsiStr_To_ShortStr (out res: shortstring; const S2 : Ansistring);[Public, alias: 'FPC_ANSISTR_TO_SHORTSTR']; compilerproc;

{

 Converts a AnsiString to a ShortString;

}

Var

 Size : SizeInt;

begin

 if S2='' then

  res:=''

 else

  begin

    Size:=Length(S2);

    If Size>high(res) then

     Size:=high(res);

    Move (S2[1],res[1],Size); // 1° ~bk Copy the string

    byte(res[0]):=byte(Size);  // 2° ~bk patch the length

  end;

end;



1° and 2° (the processor instructions generated for the task) can not be guaranteed to be executed in order on most processors.

+

As far as I know, or at least that would be something that I would consider as true, pre-emptive multitasking may switch the threads during 1° or between and 1° and 2°.

+

Thread doing

if gtest.sflag = '123456' then begin // 3° ~bk unfinished AnsiStr_To_ShortStr ?

     // gtest.sflag is equal to '123456'



3° ~bk unfinished AnsiStr_To_ShortStr : res might contain '1234567' with length 6 because if contained a length of 6 before step 2°, but the length=6 would be, for example, the residue length of the previous res= '263456' .



And so on.



My experience is that for these things one must use a CriticalSection or similar thread protection.



Regards, Bruno

_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply via email to