Use thread-safe functions where possible.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@36418 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Stefan Neis 2005-12-17 22:01:43 +00:00
parent 120edd5dbd
commit a452689b23
3 changed files with 69 additions and 24 deletions

View File

@ -547,10 +547,21 @@ Returns the current time.
\membersection{wxDateTime::GetTmNow}\label{wxdatetimegettmnow}
\func{static struct tm *}{GetTmNow}{\param{struct tm *}{tm}}
Returns the current time broken down, uses the buffer whose adress is
passed to the function via {\it tm} to store the result.
\membersection{wxDateTime::GetTmNow}
\func{static struct tm *}{GetTmNow}{\void}
Returns the current time broken down.
Returns the current time broken down. Note that this function returns a
pointer to a static buffer that's reused by calls to this function and
certain C library functions (e.g. localtime). If there is any chance your
code might be used in a multi-threaded application, you really should use
the flavour of function \helpref{wxDateTime::GetTmNow}{wxdatetimegettmnow}
taking a parameter.
\membersection{wxDateTime::GetWeekDayName}\label{wxdatetimegetweekdayname}

View File

@ -52,6 +52,21 @@ class WXDLLIMPEXP_BASE wxDateSpan;
* 5. wxDateTimeHolidayAuthority for Easter and other christian feasts
*/
/* Two wrapper functions for thread safety */
#ifdef HAVE_LOCALTIME_R
#define wxLocaltime_r localtime_r
#else
struct tm *wxLocaltime_r(const time_t*, struct tm*)
#warning using pseudo thread-safe wrapper for localtime to emulate localtime_r
#endif
#ifdef HAVE_GMTIME_R
#define wxGmtime_r gmtime_r
#else
struct tm *wxGmtime_r(const time_t*, struct tm*)
#warning using pseudo thread-safe wrapper for gmtime to emulate gmtime_r
#endif
/*
The three (main) classes declared in this header represent:
@ -1055,6 +1070,9 @@ public:
return localtime(&t);
}
// get current time using thread-safe function
static struct tm *GetTmNow(struct tm *tmstruct);
private:
// the current country - as it's the same for all program objects (unless
// it runs on a _really_ big cluster system :-), this is a static member:
@ -1537,7 +1555,8 @@ inline bool wxDateTime::IsInStdRange() const
/* static */
inline wxDateTime wxDateTime::Now()
{
return wxDateTime(*GetTmNow());
struct tm tmstruct;
return wxDateTime(*GetTmNow(&tmstruct));
}
/* static */

View File

@ -307,15 +307,16 @@ static int GetTimeZone()
static bool s_timezoneSet = false;
static long gmtoffset = LONG_MAX; // invalid timezone
// ensure that the timezone variable is set by calling localtime
// ensure that the timezone variable is set by calling wxLocaltime_r
if ( !s_timezoneSet )
{
// just call localtime() instead of figuring out whether this system
// supports tzset(), _tzset() or something else
// just call wxLocaltime_r() instead of figuring out whether this
// system supports tzset(), _tzset() or something else
time_t t = 0;
struct tm *tm;
struct tm tmstruct;
tm = localtime(&t);
tm = wxLocaltime_r(&t, &tmstruct);
s_timezoneSet = true;
// note that GMT offset is the opposite of time zone and so to return
@ -430,10 +431,11 @@ static void ReplaceDefaultYearMonthWithCurrent(int *year,
wxDateTime::Month *month)
{
struct tm *tmNow = NULL;
struct tm tmstruct;
if ( *year == wxDateTime::Inv_Year )
{
tmNow = wxDateTime::GetTmNow();
tmNow = wxDateTime::GetTmNow(&tmstruct);
*year = 1900 + tmNow->tm_year;
}
@ -441,7 +443,7 @@ static void ReplaceDefaultYearMonthWithCurrent(int *year,
if ( *month == wxDateTime::Inv_Month )
{
if ( !tmNow )
tmNow = wxDateTime::GetTmNow();
tmNow = wxDateTime::GetTmNow(&tmstruct);
*month = (wxDateTime::Month)tmNow->tm_mon;
}
@ -522,6 +524,13 @@ static wxDateTime::WeekDay GetWeekDayFromName(const wxString& name, int flags)
return wd;
}
/* static */
struct tm *wxDateTime::GetTmNow(struct tm *tmstruct)
{
time_t t = GetTimeNow();
return wxLocaltime_r(&t, tmstruct);
}
// scans all digits (but no more than len) and returns the resulting number
static bool GetNumericToken(size_t len, const wxChar*& p, unsigned long *number)
{
@ -988,7 +997,8 @@ wxDateTime::Country wxDateTime::GetCountry()
{
// try to guess from the time zone name
time_t t = time(NULL);
struct tm *tm = localtime(&t);
struct tm tmstruct;
struct tm *tm = wxLocaltime_r(&t, &tmstruct);
wxString tz = CallStrftime(_T("%Z"), tm);
if ( tz == _T("WET") || tz == _T("WEST") )
@ -1311,9 +1321,10 @@ wxDateTime& wxDateTime::Set(wxDateTime_t hour,
_T("Invalid time in wxDateTime::Set()") );
// get the current date from system
struct tm *tm = GetTmNow();
struct tm tmstruct;
struct tm *tm = GetTmNow(&tmstruct);
wxDATETIME_CHECK( tm, _T("localtime() failed") );
wxDATETIME_CHECK( tm, _T("wxLocaltime_r() failed") );
// make a copy so it isn't clobbered by the call to mktime() below
struct tm tm1(*tm);
@ -1479,7 +1490,8 @@ unsigned long wxDateTime::GetAsDOS() const
{
unsigned long ddt;
time_t ticks = GetTicks();
struct tm *tm = localtime(&ticks);
struct tm tmstruct;
struct tm *tm = wxLocaltime_r(&ticks, &tmstruct);
long year = tm->tm_year;
year -= 80;
@ -1517,14 +1529,15 @@ wxDateTime::Tm wxDateTime::GetTm(const TimeZone& tz) const
if ( time != (time_t)-1 )
{
// use C RTL functions
struct tm tmstruct;
tm *tm;
if ( tz.GetOffset() == -GetTimeZone() )
{
// we are working with local time
tm = localtime(&time);
tm = wxLocaltime_r(&time, &tmstruct);
// should never happen
wxCHECK_MSG( tm, Tm(), _T("localtime() failed") );
wxCHECK_MSG( tm, Tm(), _T("wxLocaltime_r() failed") );
}
else
{
@ -1536,10 +1549,10 @@ wxDateTime::Tm wxDateTime::GetTm(const TimeZone& tz) const
if ( time >= 0 )
#endif
{
tm = gmtime(&time);
tm = wxGmtime_r(&time, &tmstruct);
// should never happen
wxCHECK_MSG( tm, Tm(), _T("gmtime() failed") );
wxCHECK_MSG( tm, Tm(), _T("wxGmtime_r() failed") );
}
else
{
@ -2120,9 +2133,10 @@ int wxDateTime::IsDST(wxDateTime::Country country) const
time_t timet = GetTicks();
if ( timet != (time_t)-1 )
{
tm *tm = localtime(&timet);
struct tm tmstruct;
tm *tm = wxLocaltime_r(&timet, &tmstruct);
wxCHECK_MSG( tm, -1, _T("localtime() failed") );
wxCHECK_MSG( tm, -1, _T("wxLocaltime_r() failed") );
return tm->tm_isdst;
}
@ -2184,14 +2198,15 @@ wxString wxDateTime::Format(const wxChar *format, const TimeZone& tz) const
if ( (time != (time_t)-1) && !wxStrstr(format, _T("%l")) )
{
// use strftime()
tm *tm;
struct tm tmstruct;
struct tm *tm;
if ( tz.GetOffset() == -GetTimeZone() )
{
// we are working with local time
tm = localtime(&time);
tm = wxLocaltime_r(&time, &tmstruct);
// should never happen
wxCHECK_MSG( tm, wxEmptyString, _T("localtime() failed") );
wxCHECK_MSG( tm, wxEmptyString, _T("wxLocaltime_r() failed") );
}
else
{
@ -2204,10 +2219,10 @@ wxString wxDateTime::Format(const wxChar *format, const TimeZone& tz) const
if ( time >= 0 )
#endif
{
tm = gmtime(&time);
tm = wxGmtime_r(&time, &tmstruct);
// should never happen
wxCHECK_MSG( tm, wxEmptyString, _T("gmtime() failed") );
wxCHECK_MSG( tm, wxEmptyString, _T("wxGmtime_r() failed") );
}
else
{