QLocale: Avoid a deadlock in error case

QBBSystemLocaleData emits qwarnings when it fails to open or read a pps object.
If the user code installs a message handler that will invoke QLocale API again
(i.e QDate, QDateTime, ...) which leads to a deadlock situation, since
the QBBSystemLocaleData global static object's ctor() is not yet done.

This patch logs the QBBSystemLocale's warnings to stderr and
skips the Qt message handler.

Change-Id: I3d51f85761253e09b14a44179dd14a887733b392
Reviewed-by: Rafael Roquetto <rafael.roquetto@kdab.com>
This commit is contained in:
El Mehdi Fekari 2013-11-14 16:17:31 +01:00 committed by The Qt Project
parent 711d0a1658
commit 1e446fc991

View File

@ -68,17 +68,20 @@ QBBSystemLocaleData::QBBSystemLocaleData()
, measurementNotifier(0) , measurementNotifier(0)
, hourNotifier(0) , hourNotifier(0)
{ {
// Do not use qWarning to log warnings if qt_safe_open fails to open the pps file
// since the user code may install a message handler that invokes QLocale API again
// (i.e QDate, QDateTime, ...) which will cause a deadlock.
if ((measurementFd = qt_safe_open(ppsUomPath, O_RDONLY)) == -1) if ((measurementFd = qt_safe_open(ppsUomPath, O_RDONLY)) == -1)
qWarning("Failed to open uom pps, errno=%d", errno); fprintf(stderr, "Failed to open uom pps, errno=%d\n", errno);
if ((regionFd = qt_safe_open(ppsRegionLocalePath, O_RDONLY)) == -1) if ((regionFd = qt_safe_open(ppsRegionLocalePath, O_RDONLY)) == -1)
qWarning("Failed to open region pps, errno=%d", errno); fprintf(stderr, "Failed to open region pps, errno=%d\n", errno);
if ((languageFd = qt_safe_open(ppsLanguageLocalePath, O_RDONLY)) == -1) if ((languageFd = qt_safe_open(ppsLanguageLocalePath, O_RDONLY)) == -1)
qWarning("Failed to open language pps, errno=%d", errno); fprintf(stderr, "Failed to open language pps, errno=%d\n", errno);
if ((hourFd = qt_safe_open(ppsHourFormatPath, O_RDONLY)) == -1) if ((hourFd = qt_safe_open(ppsHourFormatPath, O_RDONLY)) == -1)
qWarning("Failed to open hour format pps, errno=%d", errno); fprintf(stderr, "Failed to open hour format pps, errno=%d\n", errno);
// we cannot call this directly, because by the time this constructor is // we cannot call this directly, because by the time this constructor is
// called, the event dispatcher has not yet been created, causing the // called, the event dispatcher has not yet been created, causing the
@ -186,8 +189,12 @@ QByteArray QBBSystemLocaleData::readPpsValue(const char *ppsObject, int ppsFd)
char buffer[ppsBufferSize]; char buffer[ppsBufferSize];
int bytes = qt_safe_read(ppsFd, buffer, ppsBufferSize - 1); int bytes = qt_safe_read(ppsFd, buffer, ppsBufferSize - 1);
// This method is called in the ctor(), so do not use qWarning to log warnings
// if qt_safe_read fails to read the pps file
// since the user code may install a message handler that invokes QLocale API again
// (i.e QDate, QDateTime, ...) which will cause a deadlock.
if (bytes == -1) { if (bytes == -1) {
qWarning("Failed to read Locale pps, errno=%d", errno); fprintf(stderr, "Failed to read pps object:%s, errno=%d\n", ppsObject, errno);
return result; return result;
} }
// ensure data is null terminated // ensure data is null terminated