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