KSyCoca, Thread safety, and Cache invalidation
David Faure
faure at kde.org
Sun Sep 13 22:04:01 BST 2015
On Tuesday 14 July 2015 16:01:09 Thiago Macieira wrote:
>
> If you need a machine-comparable time with other systems or across reboots,
> use QDateTime::currentDateTimeUtc(). That avoids refreshing the timezone
> database to convert to local time.
>
> Only use QDateTime::currentDateTime() if you want to show something to the
> user. There's no other valid reason. (writing to a log counts as "showing to
> the user")
What if I need to compare a file's modification time with a given timestamp?
This code:
qCDebug(SYCOCA) << "checking file timestamps";
const QDateTime stamp = QDateTime::fromMSecsSinceEpoch(timestamp);
for (QStringList::ConstIterator it = dirs.begin(); it != dirs.end(); ++it) {
const QString dir = *it;
QFileInfo inf(dir);
if (inf.lastModified() > stamp) {
qCDebug(SYCOCA) << "timestamp changed:" << dir;
return false;
}
... doesn't appear to be threadsafe due to QDateTime's timezone conversion.
It's really a problem that QDateTime isn't threadsafe, it's really unexpected
for application programmers.
Helgrind says:
==24943== Possible data race during read of size 8 at 0x67A5AC0 by thread #1
==24943== Locks held: none
==24943== at 0x573B068: qt_timezone() (qdatetime.cpp:2153)
==24943== by 0x573BA87: localMSecsToEpochMSecs(long long, QDateTimePrivate::DaylightStatus*, QDate*, QTime*, QString*) (qdatetime.cpp:2480)
==24943== by 0x5741BAB: QDateTimePrivate::toMSecsSinceEpoch() const (qdatetime.cpp:2685)
==24943== by 0x573CEFB: QDateTime::toMSecsSinceEpoch() const (qdatetime.cpp:3346)
==24943== by 0x573E8F7: QDateTime::operator<(QDateTime const&) const (qdatetime.cpp:3989)
==24943== by 0x4E9832C: QDateTime::operator>(QDateTime const&) const (qdatetime.h:283)
==24943== by 0x4E96980: checkTimestamps(long long, QStringList const&) (ksycoca.cpp:571)
==24943== This conflicts with a previous write of size 8 by thread #2
==24943== Locks held: none
==24943== at 0x64AC567: __tzfile_compute (tzfile.c:773)
==24943== by 0x64AB2E8: __tz_convert (tzset.c:635)
==24943== by 0x573B4ED: qt_localtime(long long, QDate*, QTime*, QDateTimePrivate::DaylightStatus*) (qdatetime.cpp:2337)
==24943== by 0x573B95D: epochMSecsToLocalTime(long long, QDate*, QTime*, QDateTimePrivate::DaylightStatus*) (qdatetime.cpp:2440)
==24943== by 0x573D1D8: QDateTime::setMSecsSinceEpoch(long long) (qdatetime.cpp:3435)
==24943== by 0x573EB83: QDateTime::fromMSecsSinceEpoch(long long, Qt::TimeSpec, int) (qdatetime.cpp:4266)
==24943== by 0x573EA8C: QDateTime::fromTime_t(unsigned int) (qdatetime.cpp:4186)
==24943== by 0x5815ABB: QFileSystemMetaData::modificationTime() const (qfilesystemmetadata_p.h:274)
==24943== Address 0x67a5ac0 is 0 bytes inside data symbol "timezone"
Should we have a QFileInfo::lastModifiedUtc()? Or to make this all much more intuitive,
should there be a mutex in epochMSecsToLocalTime and localMSecsToEpochMSecs?
[the same one, obviously]
--
David Faure, faure at kde.org, http://www.davidfaure.fr
Working on KDE Frameworks 5
More information about the kde-core-devel
mailing list