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