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)
, 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)
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)
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)
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)
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
// 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];
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) {
qWarning("Failed to read Locale pps, errno=%d", errno);
fprintf(stderr, "Failed to read pps object:%s, errno=%d\n", ppsObject, errno);
return result;
}
// ensure data is null terminated