summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@nokia.com>2010-04-29 09:54:44 +0200
committerThiago Macieira <thiago.macieira@nokia.com>2010-04-29 09:54:44 +0200
commitdcaad8949ea1c1782d27b038f08e9a728c8e3fe5 (patch)
tree3cb49a22f79c5952de4e913146659990d614cd64 /src/corelib
parent917e4e3284a568eecfca26365cc0a545d0f4eb70 (diff)
parent6940070adb45d67a0a9186205a4914a0a6c14135 (diff)
Merge remote branch 'origin/4.6' into qt-4.7-from-4.6
All EGL-related changes from 4.6 were discarded. Conflicts: src/gui/egl/egl.pri src/gui/egl/qegl.cpp src/gui/egl/qegl_p.h src/gui/egl/qegl_stub.cpp src/gui/egl/qeglproperties_p.h src/gui/egl/qeglproperties_stub.cpp src/gui/gui.pro src/multimedia/multimedia/audio/qaudioinput_win32_p.h src/s60installs/bwins/QtGuiu.def src/s60installs/eabi/QtGuiu.def
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/codecs/qiconvcodec.cpp22
-rw-r--r--src/corelib/global/qglobal.cpp28
-rw-r--r--src/corelib/kernel/qeventdispatcher_symbian.cpp127
-rw-r--r--src/corelib/kernel/qeventdispatcher_symbian_p.h5
-rw-r--r--src/corelib/tools/qbytedata_p.h2
-rw-r--r--src/corelib/xml/qxmlstream.g2
-rw-r--r--src/corelib/xml/qxmlstream_p.h4
7 files changed, 133 insertions, 57 deletions
diff --git a/src/corelib/codecs/qiconvcodec.cpp b/src/corelib/codecs/qiconvcodec.cpp
index 0fcdf969b6..44a0a01d8e 100644
--- a/src/corelib/codecs/qiconvcodec.cpp
+++ b/src/corelib/codecs/qiconvcodec.cpp
@@ -168,7 +168,7 @@ Q_GLOBAL_STATIC(QThreadStorage<QIconvCodec::IconvState *>, toUnicodeState)
QString QIconvCodec::convertToUnicode(const char* chars, int len, ConverterState *convState) const
{
if (utf16Codec == reinterpret_cast<QTextCodec *>(~0))
- return QString::fromAscii(chars, len);
+ return QString::fromLatin1(chars, len);
int invalidCount = 0;
int remainingCount = 0;
@@ -207,9 +207,9 @@ QString QIconvCodec::convertToUnicode(const char* chars, int len, ConverterState
static int reported = 0;
if (!reported++) {
fprintf(stderr,
- "QIconvCodec::convertToUnicode: using ASCII for conversion, iconv_open failed\n");
+ "QIconvCodec::convertToUnicode: using Latin-1 for conversion, iconv_open failed\n");
}
- return QString::fromAscii(chars, len);
+ return QString::fromLatin1(chars, len);
}
*pstate = new IconvState(cd);
@@ -273,14 +273,14 @@ QString QIconvCodec::convertToUnicode(const char* chars, int len, ConverterState
// some other error
// note, cannot use qWarning() since we are implementing the codecForLocale :)
- perror("QIconvCodec::convertToUnicode: using ASCII for conversion, iconv failed");
+ perror("QIconvCodec::convertToUnicode: using Latin-1 for conversion, iconv failed");
if (!convState) {
// reset state
iconv(state->cd, 0, &inBytesLeft, 0, &outBytesLeft);
}
- return QString::fromAscii(chars, len);
+ return QString::fromLatin1(chars, len);
}
} while (inBytesLeft != 0);
@@ -353,12 +353,12 @@ QByteArray QIconvCodec::convertFromUnicode(const QChar *uc, int len, ConverterSt
state = new IconvState(QIconvCodec::createIconv_t(0, UTF16));
if (state->cd == reinterpret_cast<iconv_t>(-1)) {
if (!setByteOrder(state->cd)) {
- perror("QIconvCodec::convertFromUnicode: using ASCII for conversion, iconv failed for BOM");
+ perror("QIconvCodec::convertFromUnicode: using Latin-1 for conversion, iconv failed for BOM");
iconv_close(state->cd);
state->cd = reinterpret_cast<iconv_t>(-1);
- return QString(uc, len).toAscii();
+ return QString(uc, len).toLatin1();
}
}
}
@@ -366,9 +366,9 @@ QByteArray QIconvCodec::convertFromUnicode(const QChar *uc, int len, ConverterSt
static int reported = 0;
if (!reported++) {
fprintf(stderr,
- "QIconvCodec::convertFromUnicode: using ASCII for conversion, iconv_open failed\n");
+ "QIconvCodec::convertFromUnicode: using Latin-1 for conversion, iconv_open failed\n");
}
- return QString(uc, len).toAscii();
+ return QString(uc, len).toLatin1();
}
size_t outBytesLeft = len;
@@ -425,12 +425,12 @@ QByteArray QIconvCodec::convertFromUnicode(const QChar *uc, int len, ConverterSt
default:
{
// note, cannot use qWarning() since we are implementing the codecForLocale :)
- perror("QIconvCodec::convertFromUnicode: using ASCII for conversion, iconv failed");
+ perror("QIconvCodec::convertFromUnicode: using Latin-1 for conversion, iconv failed");
// reset to initial state
iconv(state->cd, 0, &inBytesLeft, 0, &outBytesLeft);
- return QString(uc, len).toAscii();
+ return QString(uc, len).toLatin1();
}
}
}
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index dfa2c175c5..373c0b4d8f 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -2079,7 +2079,28 @@ static void mac_default_handler(const char *msg)
}
#endif // Q_CC_MWERKS && Q_OS_MACX
-
+#if !defined(Q_OS_WIN) && !defined(QT_NO_THREAD) && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_QNX) && \
+ defined(_POSIX_THREAD_SAFE_FUNCTIONS) && _POSIX_VERSION >= 200112L
+namespace {
+ // There are two incompatible versions of strerror_r:
+ // a) the XSI/POSIX.1 version, which returns an int,
+ // indicating success or not
+ // b) the GNU version, which returns a char*, which may or may not
+ // be the beginning of the buffer we used
+ // The GNU libc manpage for strerror_r says you should use the the XSI
+ // version in portable code. However, it's impossible to do that if
+ // _GNU_SOURCE is defined so we use C++ overloading to decide what to do
+ // depending on the return type
+ static inline QString fromstrerror_helper(int, const QByteArray &buf)
+ {
+ return QString::fromLocal8Bit(buf);
+ }
+ static inline QString fromstrerror_helper(const char *str, const QByteArray &)
+ {
+ return QString::fromLocal8Bit(str);
+ }
+}
+#endif
QString qt_error_string(int errorCode)
{
@@ -2122,12 +2143,9 @@ QString qt_error_string(int errorCode)
if (ret.isEmpty() && errorCode == ERROR_MOD_NOT_FOUND)
ret = QString::fromLatin1("The specified module could not be found.");
-
#elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && _POSIX_VERSION >= 200112L && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_QNX)
-
QByteArray buf(1024, '\0');
- strerror_r(errorCode, buf.data(), buf.size());
- ret = QString::fromLocal8Bit(buf.constData());
+ ret = fromstrerror_helper(strerror_r(errorCode, buf.data(), buf.size()), buf);
#else
ret = QString::fromLocal8Bit(strerror(errorCode));
#endif
diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp
index 3b86e89060..4566ec001a 100644
--- a/src/corelib/kernel/qeventdispatcher_symbian.cpp
+++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp
@@ -43,7 +43,6 @@
#include <private/qthread_p.h>
#include <qcoreapplication.h>
#include <private/qcoreapplication_p.h>
-#include <qdatetime.h>
#include <unistd.h>
#include <errno.h>
@@ -636,6 +635,74 @@ void QSocketActiveObject::deleteLater()
}
}
+#ifdef QT_SYMBIAN_PRIORITY_DROP
+class QIdleDetectorThread
+{
+public:
+ QIdleDetectorThread()
+ : m_state(STATE_RUN), m_stop(false)
+ {
+ qt_symbian_throwIfError(m_lock.CreateLocal());
+ TInt err = m_idleDetectorThread.Create(KNullDesC(), &idleDetectorThreadFunc, 1024, &User::Allocator(), this);
+ if (err != KErrNone)
+ m_lock.Close();
+ qt_symbian_throwIfError(err);
+ m_idleDetectorThread.SetPriority(EPriorityAbsoluteBackgroundNormal);
+ m_idleDetectorThread.Resume();
+ }
+
+ ~QIdleDetectorThread()
+ {
+ // close down the idle thread because if corelib is loaded temporarily, this would leak threads into the host process
+ m_stop = true;
+ m_lock.Signal();
+ m_idleDetectorThread.SetPriority(EPriorityNormal);
+ TRequestStatus s;
+ m_idleDetectorThread.Logon(s);
+ User::WaitForRequest(s);
+ m_idleDetectorThread.Close();
+ m_lock.Close();
+ }
+
+ void kick()
+ {
+ m_state = STATE_KICKED;
+ m_lock.Signal();
+ }
+
+ bool hasRun()
+ {
+ return m_state == STATE_RUN;
+ }
+
+private:
+ static TInt idleDetectorThreadFunc(TAny* self)
+ {
+ static_cast<QIdleDetectorThread*>(self)->IdleLoop();
+ return KErrNone;
+ }
+
+ void IdleLoop()
+ {
+ while (!m_stop) {
+ m_lock.Wait();
+ m_state = STATE_RUN;
+ }
+ }
+
+private:
+ enum IdleStates {STATE_KICKED, STATE_RUN} m_state;
+ bool m_stop;
+ RThread m_idleDetectorThread;
+ RFastLock m_lock;
+};
+
+Q_GLOBAL_STATIC(QIdleDetectorThread, idleDetectorThread);
+
+const int maxBusyTime = 2000; // maximum time we allow idle detector to be blocked before worrying, in milliseconds
+const int baseDelay = 1000; // minimum delay time used when backing off to allow idling, in microseconds
+#endif
+
QEventDispatcherSymbian::QEventDispatcherSymbian(QObject *parent)
: QAbstractEventDispatcher(parent),
m_selectThread(0),
@@ -647,11 +714,15 @@ QEventDispatcherSymbian::QEventDispatcherSymbian(QObject *parent)
m_iterationCount(0),
m_noSocketEvents(false)
{
+#ifdef QT_SYMBIAN_PRIORITY_DROP
+ m_delay = baseDelay;
+ m_avgEventTime = 0;
+ idleDetectorThread();
+#endif
}
QEventDispatcherSymbian::~QEventDispatcherSymbian()
{
- m_processHandle.Close();
}
void QEventDispatcherSymbian::startingUp()
@@ -720,23 +791,7 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla
m_interrupt = false;
#ifdef QT_SYMBIAN_PRIORITY_DROP
- /*
- * This QTime variable is used to measure the time it takes to finish
- * the event loop. If we take too long in the loop, other processes
- * may be starved and killed. After the first event has completed, we
- * take the current time, and if the remaining events take longer than
- * a preset time, we temporarily lower the priority to force a context
- * switch. For applications that do not take unecessarily long in the
- * event loop, the priority will not be altered.
- */
- QTime time;
- enum {
- FirstRun,
- SubsequentRun,
- TimeStarted
- } timeState = FirstRun;
-
- TProcessPriority priority;
+ QTime eventTimer;
#endif
while (1) {
@@ -752,10 +807,18 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla
}
#ifdef QT_SYMBIAN_PRIORITY_DROP
- if (timeState == SubsequentRun) {
- time.start();
- timeState = TimeStarted;
+ if (idleDetectorThread()->hasRun()) {
+ if (m_delay > baseDelay)
+ m_delay -= baseDelay;
+ m_lastIdleRequestTimer.start();
+ idleDetectorThread()->kick();
+ } else if (m_lastIdleRequestTimer.elapsed() > maxBusyTime) {
+ User::AfterHighRes(m_delay);
+ // allow delay to be up to 1/4 of execution time
+ if (!idleDetectorThread()->hasRun() && m_delay*3 < m_avgEventTime)
+ m_delay += baseDelay;
}
+ eventTimer.start();
#endif
TInt error;
@@ -765,6 +828,12 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla
CActiveScheduler::Current()->Error(error);
}
+#ifdef QT_SYMBIAN_PRIORITY_DROP
+ int eventDur = eventTimer.elapsed()*1000;
+ // average is calcualted as a 5% decaying exponential average
+ m_avgEventTime = (m_avgEventTime * 95 + eventDur * 5) / 100;
+#endif
+
if (!handledSymbianEvent) {
qFatal("QEventDispatcherSymbian::processEvents(): Caught Symbian stray signal");
}
@@ -773,20 +842,6 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla
break;
}
block = false;
-#ifdef QT_SYMBIAN_PRIORITY_DROP
- if (timeState == TimeStarted && time.elapsed() > 100) {
- priority = m_processHandle.Priority();
- m_processHandle.SetPriority(EPriorityBackground);
- time.start();
- // Slight chance of race condition in the next lines, but nothing fatal
- // will happen, just wrong priority.
- if (m_processHandle.Priority() == EPriorityBackground) {
- m_processHandle.SetPriority(priority);
- }
- }
- if (timeState == FirstRun)
- timeState = SubsequentRun;
-#endif
};
emit awake();
diff --git a/src/corelib/kernel/qeventdispatcher_symbian_p.h b/src/corelib/kernel/qeventdispatcher_symbian_p.h
index 52811999e0..05758cacd4 100644
--- a/src/corelib/kernel/qeventdispatcher_symbian_p.h
+++ b/src/corelib/kernel/qeventdispatcher_symbian_p.h
@@ -62,6 +62,7 @@
#include <qmutex.h>
#include <qwaitcondition.h>
#include <qsocketnotifier.h>
+#include <qdatetime.h>
#include <e32base.h>
@@ -280,7 +281,9 @@ private:
QList<QActiveObject *> m_deferredActiveObjects;
- RProcess m_processHandle;
+ int m_delay;
+ int m_avgEventTime;
+ QTime m_lastIdleRequestTimer;
};
#ifdef QT_DEBUG
diff --git a/src/corelib/tools/qbytedata_p.h b/src/corelib/tools/qbytedata_p.h
index c48bb3398d..08249e01d9 100644
--- a/src/corelib/tools/qbytedata_p.h
+++ b/src/corelib/tools/qbytedata_p.h
@@ -84,7 +84,7 @@ public:
}
- inline void append(QByteArray& bd)
+ inline void append(const QByteArray& bd)
{
if (bd.isEmpty())
return;
diff --git a/src/corelib/xml/qxmlstream.g b/src/corelib/xml/qxmlstream.g
index 1b882e093a..e91408f866 100644
--- a/src/corelib/xml/qxmlstream.g
+++ b/src/corelib/xml/qxmlstream.g
@@ -748,7 +748,7 @@ bool QXmlStreamReaderPrivate::parse()
state_stack[tos] = 0;
return true;
} else if (act > 0) {
- if (++tos == stack_size)
+ if (++tos == stack_size-1)
reallocateStack();
Value &val = sym_stack[tos];
diff --git a/src/corelib/xml/qxmlstream_p.h b/src/corelib/xml/qxmlstream_p.h
index ac421cf8b0..f6ab3a19bc 100644
--- a/src/corelib/xml/qxmlstream_p.h
+++ b/src/corelib/xml/qxmlstream_p.h
@@ -61,7 +61,7 @@
class QXmlStreamReader_Table
{
public:
- enum {
+ enum VariousConstants {
EOF_SYMBOL = 0,
AMPERSAND = 5,
ANY = 41,
@@ -1242,7 +1242,7 @@ bool QXmlStreamReaderPrivate::parse()
state_stack[tos] = 0;
return true;
} else if (act > 0) {
- if (++tos == stack_size)
+ if (++tos == stack_size-1)
reallocateStack();
Value &val = sym_stack[tos];