Thomas Schatzl wrote:
This code is not thread safe at all. A thread switch after the while
loop and before the increment will not prevent progress on other
threads, so multiple threads can enter the "critical section".
Well, yes, even if under Windows it's rare that a thread is preempted right in the middle of its execution. At least that's what my own experience has told me and why I'm calling Sleep in the while loop, so that the thread yields to other ones.

Use EnterCriticalSection/LeaveCriticalSection from the RTL if you need
that.
I did not because I thought that would be too slow, but it turns out it's not so yes, it's much better.

If you could somewhat decrease the size of your buffer to something
reasonable - do you really expect to translate a string with 1M chars? -
use the stack. Actually even a 2M data object on the stack might be
reasonable.
That's the highest value that the documentation of the API is giving, so I guess the API will respect its own publicized contract.

function GetSomeString(index : integer) : UnicodeString;
const
   bufsize = 1024; // as you wish
var
   buffer : array[0..bufsize-1] of WideChar;
   pbuffer : PWideChar;
   islongstring : boolean;
   lengthofstring : integer;
begin
   lengthofstring := length(stringfromindex(integer));
   islongstring := lengthofstring > bufsize;
   if (islongstring) then
     pbuffer := getmem(lengthofstring * sizeof(WideChar));
   else
     pbuffer := @buffer;
   CallToAnAPIThatWritesBackAWideString(stringfromindex(integer),
pbuffer, lengthofstring);
   if (islongstring) then
     freemem(pbuffer);
   result := pbuffer;
end;
Thanks for your example, but it implies that the string length is known before calling the API while this is not the case. The API is given a buffer and a maximum length, a buffer into which it writes a zero terminated string. But the length of that string cannot be known beforehand, hence the reason why I wrote it that way. Note also that having buffer local to the function is just as bad (performance wise) as setting the length of the result string.

In the end, many thanks for your suggestions, I'll go with the critical section as it is much safer.

Regards
Olivier
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply via email to