poco icon indicating copy to clipboard operation
poco copied to clipboard

LocalDateTime determineTzd

Open micheleselea opened this issue 5 years ago • 7 comments

Hi all, I have an issue when I construct a LocalDateTime, because the constructor invoke determineTzd(true) the adjust=true variable make the code call for std::tm* broken = std::localtime(&epochTime); sometimes, and I really never understand why and when, the broken is null so an exception is thrown throw Poco::SystemException("cannot get local time"); This kind of behavior came from a very long time....I don't know if you ever happen to you, and how can you solve it

micheleselea avatar Nov 18 '20 10:11 micheleselea

Did you check the errno? Tried to log epochTime, did you?

Mironenko avatar Nov 24 '20 06:11 Mironenko

No I didn't because it's some kind of tricky error, because is not happen so frequently, and it's inside the LocalDateTime class, so usually a subsequent call to that function works

micheleselea avatar Nov 24 '20 07:11 micheleselea

It's seems to me some "locked" structure or some kind of concurrent access

micheleselea avatar Nov 24 '20 07:11 micheleselea

It's seems to me some "locked" structure or some kind of concurrent access

Indeed, localtime is not threadsafe. Maybe it should be replaced with localtime_r on supported platforms and protected with a dedicated mutex on the rest?

Mironenko avatar Nov 24 '20 07:11 Mironenko

This issue is stale because it has been open for 365 days with no activity.

github-actions[bot] avatar Nov 25 '21 02:11 github-actions[bot]

I'l kick this can down the road, because I have no idea what to do with it - can't reproduce it, and windows seems to have a standard C function with reversed order of arguments?

aleks-f avatar May 25 '22 00:05 aleks-f

@aleks-f exactly windows has a reverse order like that:

void LocalDateTime::determineTzd(bool adjust)
{
	if (adjust)
	{
		std::time_t epochTime = _dateTime.timestamp().epochTime();
#if defined(_WIN32) || defined(POCO_NO_POSIX_TSF)
#if defined(_WIN32_WCE) && _WIN32_WCE < 0x800
		std::tm* broken = wceex_localtime(&epochTime);
#else
		std::tm brokenBuf;
 		std::tm* broken = &brokenBuf;
 		errno_t err = localtime_s(broken, &epochTime);
 		if (err) broken = nullptr;
#endif
		if (!broken) throw Poco::SystemException("cannot get local time");
		_tzd = Timezone::utcOffset() + Timezone::dst(_dateTime.timestamp());
#else
		std::tm broken;
#if defined(POCO_VXWORKS) && (defined(_VXWORKS_COMPATIBILITY_MODE) || (defined(_WRS_VXWORKS_MAJOR) && ((_WRS_VXWORKS_MAJOR < 6) || ((_WRS_VXWORKS_MAJOR == 6)  && (_WRS_VXWORKS_MINOR < 9)))))
		if (localtime_r(&epochTime, &broken) != OK)
			throw Poco::SystemException("cannot get local time");
#else
		if (!localtime_r(&epochTime, &broken))
			throw Poco::SystemException("cannot get local time");
#endif
		_tzd = Timezone::utcOffset() + Timezone::dst(_dateTime.timestamp());
#endif
		adjustForTzd();
	}
	else
	{
		int dst;
		dstOffset(dst);
		_tzd = (Timezone::utcOffset() + dst);
	}
}

It was difficult to reproduce even to me, I never understand why or when that happens...I suppose is related to some thread call condition

micheleselea avatar May 25 '22 09:05 micheleselea

This issue is stale because it has been open for 365 days with no activity.

github-actions[bot] avatar Oct 25 '23 02:10 github-actions[bot]