[fpc-devel] cwstring and threads

Martin Schreiber fpmse at bluewin.ch
Sun Apr 16 11:16:39 CEST 2006


On Sunday 16 April 2006 10.51, Florian Klaempfl wrote:
> Martin Schreiber wrote:
> > Hi,
> >
> > Is cwstring threadsave?
> > I suspect there is a problem.
>
> The only problem I could imagine is that the caching of of the iconv_t
> handles causes problem, since they could be accessed multiple times
> without lock.

The problems are gone with locking.

Martin

Index: cwstring.pp
===================================================================
--- cwstring.pp    (revision 3190) 
+++ cwstring.pp    (working copy) 
@@ -109,7 +109,25 @@
   iconv_ucs42ansi,
   iconv_ansi2wide,
   iconv_wide2ansi : iconv_t;
+   
+  lock_ansi2ucs4, 
+  lock_ucs42ansi, 
+  lock_ansi2wide, 
+  lock_wide2ansi : integer; 
 
+procedure lockiconv(var lockcount: integer); 
+begin 
+ while interlockedincrement(lockcount) > 1 do begin 
+  interlockeddecrement(lockcount); 
+  sleep(0); 
+ end; 
+end; 
+ 
+procedure unlockiconv(var lockcount: integer); 
+begin 
+ interlockeddecrement(lockcount); 
+end; 
+   
 procedure Wide2AnsiMove(source:pwidechar;var dest:ansistring;len:SizeInt);
   var
     outlength,
@@ -130,6 +148,7 @@
     srcpos:=source;
     destpos:=pchar(dest);
     outleft:=outlength;
+    lockiconv(lock_wide2ansi); 
     while iconv(iconv_wide2ansi, at srcpos, at srclen, at destpos, at outleft)=size_t(-1) 
do
       begin
         case fpgetCerrno of
@@ -158,6 +177,7 @@
             raise EConvertError.Create('iconv error '+IntToStr(fpgetCerrno));
         end;
       end;
+    unlockiconv(lock_wide2ansi); 
     // truncate string
     setlength(dest,length(dest)-outleft);
   end;
@@ -182,6 +202,7 @@
     srcpos:=source;
     destpos:=pchar(dest);
     outleft:=outlength*2;
+    lockiconv(lock_ansi2wide); 
     while iconv(iconv_ansi2wide, at srcpos, at len, at destpos, at outleft)=size_t(-1) do
       begin
         case fpgetCerrno of
@@ -209,6 +230,7 @@
             raise EConvertError.Create('iconv error '+IntToStr(fpgetCerrno));
         end;
       end;
+    unlockiconv(lock_ansi2wide); 
     // truncate string
     setlength(dest,length(dest)-outleft div 2);
   end;
@@ -253,6 +275,7 @@
     srcpos:=source;
     destpos:=pchar(dest);
     outleft:=outlength*4;
+    lockiconv(lock_ansi2ucs4); 
     while iconv(iconv_ansi2ucs4, at srcpos, at len, at destpos, at outleft)=size_t(-1) do
       begin
         case fpgetCerrno of
@@ -270,6 +293,7 @@
             raise EConvertError.Create('iconv error '+IntToStr(fpgetCerrno));
         end;
       end;
+    unlockiconv(lock_ansi2ucs4); 
     // truncate string
     setlength(dest,length(dest)-outleft div 4);
   end;



More information about the fpc-devel mailing list