[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