Hi all,
 
  This is an old thread, by I have some new discoveries. ^_^
 
  I discovered a piece of "non-threadsafe" code involving format.
The code resides in Classes.pas, ObjectTextToBinary() and ObjectBinaryToText().
In these procedures, the global variable DecimalSeparator is temporarily
set to a fixed value for performing format conversions.
 
  This means that if one thread is performing component serialization,
while another thread tries to create an exception object with Create__Fmt()
constructor and passed a float number as argument, there is a chance for race
condition on string operation.
 
  Not a big deal, but it is always good to know... ^_^
 
AdamWu
.dlrow eht htiw thgir s'lla ,nevaeh sih ni si doG> Date: Sat, 26 May 2007 
12:30:52 -0500> From: [EMAIL PROTECTED]> To: [email protected]> Subject: Re: 
Exception threadsafety> > Wu Adam wrote:> > The "Exception" class in SysUtils 
unit has a serie of constructors > > Create*Fmt*() that combines "Format" 
functionality into the constructor. > > When I examine its source I found out 
those constructors all use the > > "Format(Format, Args)" routine. However, the 
Delphi documentation > > clearly stated that the "Format(Format, Args)" routine 
is NOT > > threadsafe. So, I think it also implies that the Exception class > > 
constructors that use them are NOT threadsafe, which means, raising an > > 
exception using the Create*Fmt* constructor is NOT threadsafe!(?!)> > > > After 
discovering this problem, I coded my own "threadsafe" version > > exception 
class which uses the threadsafe "Format(Format, Args, > > FmtSettings)" 
routine, feeding it a per-thread copy of FormatSettings.> > > > Yes, you can 
call me paranoid, because even I have the same feeling. So > > I really want to 
know whether my suspect is true or I am practising > > something that is not 
necessary...> > The non-thread-safe part of Format is where it accesses the 
various > global locale settings. The thread-safe version take a 
TFormatSettings > record that provides a local copy of all the relevant 
settings, so it no > longer needs to access the shared global values. If, when 
you create an > exception object, your format string doesn't require access to 
any of > those global variables, then it is safe to create that object.> > Safe 
format strings include s, d, u, x, and p, as long as the data value > is not a 
Variant. If the data value is a Variant, then there may be a > call to 
FloatToStr via FormatVarToStr and Variants._VarToLStr.> > The e, f, g, m, and n 
format strings trigger access to the > DecimalSeparator, ThousandSeparator, 
CurrencyString, CurrencyFormat, and > NegCurFormat variables. In addition, the 
m format string requires > accessing the CurrencyDecimals variable.> > 
Furthermore, accessing those variables is only unsafe if their values > can 
ever change while a call to Format is active. In the VCL source > code, they 
only change due to calls to GetLocaleFormatSettings and > GetFormatSettings. 
Delphi never calls the former, and it only calls the > latter in two places. 
The first is in the initialization section of > SysUtils.pas, which is required 
for initializing the variables when your > program starts up. The other place 
is in TApplication.CheckIniChange, > and the function is only called if 
Application.UpdateFormatSettings is > True. It's True by default, but you can 
set it to False. CheckIniChange > gets called in response to your main window 
receiving a wm_WinIniChange > or TaskbarCreated message.> > -- > Rob> 
_______________________________________________> Delphi mailing list -> 
[email protected]> http://www.elists.org/mailman/listinfo/delphi
_________________________________________________________________
MSN 中文网,最新时尚生活资讯,白领聚集门户。
http://cn.msn.com
_______________________________________________
Delphi mailing list -> [email protected]
http://www.elists.org/mailman/listinfo/delphi

Reply via email to