summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2011-03-22 18:22:30 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2011-03-22 18:22:30 (GMT)
commit5d8aa54a68b9509510ba1fa7164e04d7a424583a (patch)
tree8d30aa133b129e52dc85587d55b5662952c88a29
parent807508482b6f5aeb819f1d39d4cb7e63c37d589c (diff)
parent7cce8ce5af4087c662db657887b7971a2931e849 (diff)
downloadQt-5d8aa54a68b9509510ba1fa7164e04d7a424583a.zip
Qt-5d8aa54a68b9509510ba1fa7164e04d7a424583a.tar.gz
Qt-5d8aa54a68b9509510ba1fa7164e04d7a424583a.tar.bz2
Merge branch 'master' of git://scm.dev.nokia.troll.no/qt/qt-symbian-team
* 'master' of git://scm.dev.nokia.troll.no/qt/qt-symbian-team: Make createpackage and patch_capabilties scripts use tmp dir Fix for QTBUG-16985. Revert "QComboBox fix for QTBUG-16985" Moving Symbian CPU core detection to qthread_symbian.cpp QComboBox fix for QTBUG-16985 Making Symbian helper threads exit cleanly at app exit
-rwxr-xr-xbin/createpackage.pl41
-rwxr-xr-xbin/patch_capabilities.pl50
-rw-r--r--mkspecs/common/symbian/symbian.conf2
-rw-r--r--mkspecs/features/symbian/sis_targets.prf21
-rw-r--r--src/corelib/kernel/qeventdispatcher_symbian.cpp50
-rw-r--r--src/corelib/thread/qthread_symbian.cpp57
-rw-r--r--src/corelib/thread/qthread_unix.cpp26
-rw-r--r--src/gui/widgets/qcombobox.cpp32
8 files changed, 174 insertions, 105 deletions
diff --git a/bin/createpackage.pl b/bin/createpackage.pl
index df91876..b7457e1 100755
--- a/bin/createpackage.pl
+++ b/bin/createpackage.pl
@@ -58,7 +58,7 @@ use File::Spec;
use File::Path;
# use CWD abs_bath, which is exported only on request
use Cwd 'abs_path';
-
+use File::Copy;
sub Usage() {
print <<ENDUSAGESTRING;
@@ -84,6 +84,8 @@ Where supported options are as follows:
[-g|gcce-is-armv5] = Convert gcce platform to armv5.
[-d|dont-patch] = Skip automatic patching of capabilities and pkg file if default certificate
is used. Instead non-self-signable capabilities just cause warnings.
+ [-t|tmp-dir <path>] = Specifies temporary directory to be used for package creation.
+ Defaults to 'createpackage_tmp' under same directory as templatepkg.
Where parameters are as follows:
templatepkg = Name of .pkg file template
target = Either debug or release
@@ -130,6 +132,7 @@ my $signed_sis_name = "";
my $onlyUnsigned = "";
my $convertGcce = "";
my $dontPatchCaps = "";
+my $tempPackageDir = "";
unless (GetOptions('i|install' => \$install,
'p|preprocess' => \$preprocessonly,
@@ -139,7 +142,8 @@ unless (GetOptions('i|install' => \$install,
's|stub' => \$stub,
'n|sisname=s' => \$signed_sis_name,
'g|gcce-is-armv5' => \$convertGcce,
- 'd|dont-patch' => \$dontPatchCaps,)) {
+ 'd|dont-patch' => \$dontPatchCaps,
+ 't|tmp-dir=s' => \$tempPackageDir,)) {
Usage();
}
@@ -190,18 +194,22 @@ $key = $ARGV[3] or $key = "";
my $passphrase;
$passphrase = $ARGV[4] or $passphrase = "";
+if ($tempPackageDir eq "") {
+ my ($templateVolume, $templatePath, $templateFileName) = File::Spec->splitpath($templatepkg);
+ $tempPackageDir = File::Spec->catpath($templateVolume, $templatePath."createpackage_tmp", "");
+}
+
+mkpath($tempPackageDir);
+
# Generate output pkg basename (i.e. file name without extension)
my $pkgoutputbasename = $templatepkg;
-my $preservePkgOutput = "";
$pkgoutputbasename =~ s/_template/_$targetplatform/g;
$pkgoutputbasename =~ s/_installer\.pkg/_installer___temp\.pkg/g;
-if ($pkgoutputbasename eq $templatepkg) {
- $preservePkgOutput = "1";
-}
$pkgoutputbasename =~ s/\.pkg//g;
# Store output file names to variables
-my $pkgoutput = $pkgoutputbasename.".pkg";
+my ($dummy1, $dummy2, $pkgoutput) = File::Spec->splitpath($pkgoutputbasename.".pkg");
+$pkgoutput = $tempPackageDir."/".$pkgoutput;
my $sisoutputbasename;
if ($signed_sis_name eq "") {
$sisoutputbasename = $pkgoutputbasename;
@@ -300,9 +308,7 @@ unlink $unsigned_sis_name;
if (!$onlyUnsigned) {
unlink $signed_sis_name;
}
-if (!$preservePkgOutput) {
- unlink $pkgoutput;
-}
+unlink $pkgoutput;
# Preprocess PKG
@@ -334,6 +340,11 @@ print OUTPUT $_;
close OUTPUT;
if ($preprocessonly) {
+ # Copy preprocessed file from tmp dir to pkg file dir
+ my ($templateVolume, $templatePath, $templateFileName) = File::Spec->splitpath($templatepkg);
+ my ($dummy1, $dummy2, $copyFileName) = File::Spec->splitpath($pkgoutput);
+ my $copyTarget = File::Spec->catpath($templateVolume, $templatePath, $copyFileName);
+ copy($pkgoutput, $copyTarget) or die "Preprocessed pkg file '$pkgoutput' cannot be copied.";
exit;
}
@@ -354,7 +365,7 @@ if($stub) {
system ("$patch_capabilities -c $pkgoutput") and print ("Warning: Package check for self-signing viability failed. Installing the package on a device will most likely fail!\n\n");
} else {
print("Auto-patching self-signed package.\n");
- system ("$patch_capabilities $pkgoutput") and die ("ERROR: Automatic patching failed");
+ system ("$patch_capabilities -t $tempPackageDir $pkgoutput") and die ("ERROR: Automatic patching failed");
}
}
@@ -377,9 +388,6 @@ if($stub) {
print ("\nUnsigned package creation failed!\n");
}
- if (!$preservePkgOutput) {
- unlink $pkgoutput;
- }
print ("\n");
exit;
}
@@ -405,10 +413,7 @@ if($stub) {
print ("\tAdditionally signed the SIS with certificate: $row->[0]!\n");
}
- # remove temporary pkg and unsigned sis
- if (!$preservePkgOutput) {
- unlink $pkgoutput;
- }
+ # remove temporary unsigned sis
if (!$preserveUnsigned) {
unlink $unsigned_sis_name;
}
diff --git a/bin/patch_capabilities.pl b/bin/patch_capabilities.pl
index 91ab4b8..40b6a17 100755
--- a/bin/patch_capabilities.pl
+++ b/bin/patch_capabilities.pl
@@ -53,6 +53,7 @@
use File::Copy;
use File::Spec;
+use File::Path;
sub Usage() {
print("This script can be used to set capabilities of all binaries\n");
@@ -63,11 +64,13 @@ sub Usage() {
print(" symbian-sbsv2 platform, 'target-platform' is REQUIRED. ***\n\n");
print(" *** NOTE2: When patching gcce binaries built with symbian-sbsv2 toolchain,\n");
print(" armv5 must be specified as platform.\n");
- print("\nUsage: patch_capabilities.pl [-c] pkg_filename [target-platform [capability list]]\n");
+ print("\nUsage: patch_capabilities.pl [-c|-t tmp_path] pkg_filename [target-platform [capability list]]\n");
print("\nE.g. patch_capabilities.pl myapp_template.pkg release-armv5 \"All -TCB\"\n");
print("\nThe parameter -c can be used to just check if package is compatible with self-signing\n");
print("without actually doing any patching.\n");
print("Explicit capability list cannot be used with -c parameter.\n");
+ print("\nThe parameter -t can be used to specify a dir under which the temporary files are created.\n");
+ print("Defaults to 'patch_capabilities_tmp' under the path to pkg file.\n");
exit();
}
@@ -101,6 +104,7 @@ if (@ARGV)
my $pkgFileName = shift(@ARGV);
my $justCheck = "";
my $msgPrefix = "Patching:";
+ my $tempPatchPath = "";
if ($pkgFileName eq "-c") {
$pkgFileName = shift(@ARGV);
@@ -108,6 +112,18 @@ if (@ARGV)
$msgPrefix = "Warning:";
}
+ if ($pkgFileName eq "-t") {
+ $tempPatchPath = shift(@ARGV);
+ $pkgFileName = shift(@ARGV);
+ }
+
+ my ($pkgVolume, $pkgPath, $pkgPlainFileName) = File::Spec->splitpath($pkgFileName);
+ if ($tempPatchPath eq "") {
+ $tempPatchPath = File::Spec->catpath($pkgVolume, $pkgPath."patch_capabilities_tmp", "");
+ }
+
+ mkpath($tempPatchPath);
+
# These variables will only be set for template .pkg files.
my $target;
my $platform;
@@ -165,8 +181,9 @@ if (@ARGV)
# Start with no binaries listed.
my @binaries = ();
+ my $binariesDelimeter = "///";
- my $tempPkgFileName = $pkgFileName."_@@TEMP@@";
+ my $tempPkgFileName = $tempPatchPath."/__TEMP__".$pkgPlainFileName;
if (!$justCheck) {
unlink($tempPkgFileName);
@@ -216,19 +233,23 @@ if (@ARGV)
$sourcePath =~ s/\$\(TARGET\)/$target/gm;
}
+ my ($dummy1, $dummy2, $binaryBaseName) = File::Spec->splitpath($sourcePath);
+
if ($justCheck) {
- push (@binaries, $sourcePath);
+ push (@binaries, $binaryBaseName.$binariesDelimeter.$sourcePath);
} else {
- # Change the source file name (but only if not already patched)
+ # Copy original files over to patching dir
+ # Patching dir will be flat to make it cleanable with QMAKE_CLEAN, so path
+ # will be collapsed into the file name to avoid name collisions in the rare
+ # case where custom pkg rules are used to install files with same names from
+ # different directories (probably using platform checks to choose only one of them.)
my $patchedSourcePath = $sourcePath;
- if ($patchedSourcePath !~ m/_patched_caps/)
- {
- $newLine =~ s/(^.*)(\.dll|\.exe)(.*)(\.dll|\.exe)/$1_patched_caps$2$3$4/i;
- $patchedSourcePath =~ s/(^.*)(\.dll|\.exe)/$1_patched_caps$2/i;
+ $patchedSourcePath =~ s/[\/\\:]/_/g;
+ $patchedSourcePath = "$tempPatchPath/$patchedSourcePath";
+ $newLine =~ s/^.*(\.dll|\.exe)(.*)(\.dll|\.exe)/\"$patchedSourcePath$2$3/i;
- copy($sourcePath, $patchedSourcePath) or die "$sourcePath cannot be copied for patching.";
- }
- push (@binaries, $patchedSourcePath);
+ copy($sourcePath, $patchedSourcePath) or die "$sourcePath cannot be copied for patching.";
+ push (@binaries, $binaryBaseName.$binariesDelimeter.$patchedSourcePath);
}
}
}
@@ -250,10 +271,13 @@ if (@ARGV)
my $baseCommandToExecute = "${epocToolsDir}elftran -vid 0x0 -capability \"%s\" ";
# Actually set the capabilities of the listed binaries.
- foreach my $binaryPath(@binaries)
+ foreach my $binariesItem(@binaries)
{
+ $binariesItem =~ m|^(.*)$binariesDelimeter(.*)$|;
+ my $binaryBaseName = $1;
+ my $binaryPath = $2;
+
# Create the command line for setting the capabilities.
- my ($binaryVolume, $binaryDirs, $binaryBaseName) = File::Spec->splitpath($binaryPath);
my $commandToExecute = $baseCommandToExecute;
my $executeNeeded = "";
if (@capabilitiesSpecified)
diff --git a/mkspecs/common/symbian/symbian.conf b/mkspecs/common/symbian/symbian.conf
index d9f6279..74acc64 100644
--- a/mkspecs/common/symbian/symbian.conf
+++ b/mkspecs/common/symbian/symbian.conf
@@ -93,7 +93,7 @@ contains(QMAKE_HOST.os,Windows) {
QMAKE_COPY = copy /y
QMAKE_COPY_DIR = xcopy /s /q /y /i
QMAKE_MOVE = move
- QMAKE_DEL_FILE = del 2> NUL
+ QMAKE_DEL_FILE = del /q 2> NUL
QMAKE_MKDIR = mkdir
QMAKE_DEL_DIR = rmdir
QMAKE_DEL_TREE = rmdir /s /q
diff --git a/mkspecs/features/symbian/sis_targets.prf b/mkspecs/features/symbian/sis_targets.prf
index 9963b30..d0fe881 100644
--- a/mkspecs/features/symbian/sis_targets.prf
+++ b/mkspecs/features/symbian/sis_targets.prf
@@ -26,6 +26,9 @@ equals(GENERATE_SIS_TARGETS, true) {
qtPrepareTool(QMAKE_CREATEPACKAGE, createpackage)
+ CREATEPACKAGE_DIR = $$OBJECTS_DIR/createpackage_tmp
+ QMAKE_CLEAN += $$CREATEPACKAGE_DIR/*
+
symbian-abld|symbian-sbsv2 {
symbian-sbsv2 {
CONVERT_GCCE_PARAM = -g
@@ -48,7 +51,7 @@ equals(GENERATE_SIS_TARGETS, true) {
sis_target.depends += $${baseTarget}_template.pkg
ok_sis_target.target = ok_sis
- ok_sis_target.commands = $$QMAKE_CREATEPACKAGE $$CONVERT_GCCE_PARAM $(QT_SIS_OPTIONS) $${baseTarget}_template.pkg \
+ ok_sis_target.commands = $$QMAKE_CREATEPACKAGE $$CONVERT_GCCE_PARAM -t $$CREATEPACKAGE_DIR $(QT_SIS_OPTIONS) $${baseTarget}_template.pkg \
$(QT_SIS_TARGET) $(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE)
unsigned_sis_target.target = unsigned_sis
@@ -65,7 +68,7 @@ equals(GENERATE_SIS_TARGETS, true) {
unsigned_sis_target.depends += $${baseTarget}_template.pkg
ok_unsigned_sis_target.target = ok_unsigned_sis
- ok_unsigned_sis_target.commands = $$QMAKE_CREATEPACKAGE $$CONVERT_GCCE_PARAM $(QT_SIS_OPTIONS) -o $${baseTarget}_template.pkg $(QT_SIS_TARGET)
+ ok_unsigned_sis_target.commands = $$QMAKE_CREATEPACKAGE $$CONVERT_GCCE_PARAM -t $$CREATEPACKAGE_DIR $(QT_SIS_OPTIONS) -o $${baseTarget}_template.pkg $(QT_SIS_TARGET)
target_sis_target.target = $${baseTarget}.sis
target_sis_target.commands = $(MAKE) -f $(MAKEFILE) sis
@@ -77,7 +80,7 @@ equals(GENERATE_SIS_TARGETS, true) {
installer_sis_target.depends = $${baseTarget}_installer.pkg sis
ok_installer_sis_target.target = ok_installer_sis
- ok_installer_sis_target.commands = $$QMAKE_CREATEPACKAGE $(QT_SIS_OPTIONS) $${baseTarget}_installer.pkg - \
+ ok_installer_sis_target.commands = $$QMAKE_CREATEPACKAGE -t $$CREATEPACKAGE_DIR $(QT_SIS_OPTIONS) $${baseTarget}_installer.pkg - \
$(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE)
ok_installer_sis_target.depends = $${baseTarget}_installer.pkg
@@ -86,7 +89,7 @@ equals(GENERATE_SIS_TARGETS, true) {
unsigned_installer_sis_target.depends = $${baseTarget}_installer.pkg unsigned_sis
ok_unsigned_installer_sis_target.target = ok_unsigned_installer_sis
- ok_unsigned_installer_sis_target.commands = $$QMAKE_CREATEPACKAGE $(QT_SIS_OPTIONS) -o $${baseTarget}_installer.pkg
+ ok_unsigned_installer_sis_target.commands = $$QMAKE_CREATEPACKAGE -t $$CREATEPACKAGE_DIR $(QT_SIS_OPTIONS) -o $${baseTarget}_installer.pkg
ok_unsigned_installer_sis_target.depends = $${baseTarget}_installer.pkg
fail_sis_nocache_target.target = fail_sis_nocache
@@ -106,7 +109,7 @@ equals(GENERATE_SIS_TARGETS, true) {
stub_sis_target.depends += $${baseTarget}_stub.pkg
ok_stub_sis_target.target = ok_stub_sis
- ok_stub_sis_target.commands = $$QMAKE_CREATEPACKAGE -s $(QT_SIS_OPTIONS) $${baseTarget}_stub.pkg \
+ ok_stub_sis_target.commands = $$QMAKE_CREATEPACKAGE -t $$CREATEPACKAGE_DIR -s $(QT_SIS_OPTIONS) $${baseTarget}_stub.pkg \
$(QT_SIS_TARGET) $(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE)
QMAKE_EXTRA_TARGETS += sis_target \
@@ -150,12 +153,12 @@ equals(GENERATE_SIS_TARGETS, true) {
!equals(TARGET, "$$baseTarget"):sis_destdir = $$sis_destdir/$$dirname(TARGET)
sis_target.target = sis
- sis_target.commands = $$QMAKE_CREATEPACKAGE $(QT_SIS_OPTIONS) $${baseTarget}_template.pkg \
+ sis_target.commands = $$QMAKE_CREATEPACKAGE -t $$CREATEPACKAGE_DIR $(QT_SIS_OPTIONS) $${baseTarget}_template.pkg \
- $(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE)
sis_target.depends = first $${baseTarget}_template.pkg
unsigned_sis_target.target = unsigned_sis
- unsigned_sis_target.commands = $$QMAKE_CREATEPACKAGE $(QT_SIS_OPTIONS) -o $${baseTarget}_template.pkg
+ unsigned_sis_target.commands = $$QMAKE_CREATEPACKAGE -t $$CREATEPACKAGE_DIR $(QT_SIS_OPTIONS) -o $${baseTarget}_template.pkg
unsigned_sis_target.depends = first $${baseTarget}_template.pkg
target_sis_target.target = $${sis_destdir}/$${baseTarget}.sis
@@ -166,12 +169,12 @@ equals(GENERATE_SIS_TARGETS, true) {
installer_sis_target.depends = $${baseTarget}_installer.pkg sis
ok_installer_sis_target.target = ok_installer_sis
- ok_installer_sis_target.commands = $$QMAKE_CREATEPACKAGE $(QT_SIS_OPTIONS) $${baseTarget}_installer.pkg - \
+ ok_installer_sis_target.commands = $$QMAKE_CREATEPACKAGE -t $$CREATEPACKAGE_DIR $(QT_SIS_OPTIONS) $${baseTarget}_installer.pkg - \
$(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE)
ok_installer_sis_target.depends = $${baseTarget}_installer.pkg
unsigned_installer_sis_target.target = unsigned_installer_sis
- unsigned_installer_sis_target.commands = $$QMAKE_CREATEPACKAGE $(QT_SIS_OPTIONS) -o $${baseTarget}_installer.pkg
+ unsigned_installer_sis_target.commands = $$QMAKE_CREATEPACKAGE -t $$CREATEPACKAGE_DIR $(QT_SIS_OPTIONS) -o $${baseTarget}_installer.pkg
unsigned_installer_sis_target.depends = $${baseTarget}_installer.pkg unsigned_sis
!isEmpty(sis_destdir):!equals(sis_destdir, "."):!equals(sis_destdir, "./") {
diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp
index 53796be..4c01bde 100644
--- a/src/corelib/kernel/qeventdispatcher_symbian.cpp
+++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp
@@ -43,6 +43,7 @@
#include <private/qthread_p.h>
#include <qcoreapplication.h>
#include <private/qcoreapplication_p.h>
+#include <qsemaphore.h>
#include <unistd.h>
#include <errno.h>
@@ -654,34 +655,54 @@ class QIdleDetectorThread
{
public:
QIdleDetectorThread()
- : m_state(STATE_RUN), m_stop(false)
+ : m_state(STATE_RUN), m_stop(false), m_running(false)
{
- qt_symbian_throwIfError(m_lock.CreateLocal(0));
+ start();
+ }
+
+ ~QIdleDetectorThread()
+ {
+ stop();
+ }
+
+ void start()
+ {
+ QMutexLocker lock(&m_mutex);
+ if (m_running)
+ return;
+ m_stop = false;
+ m_state = STATE_RUN;
TInt err = m_idleDetectorThread.Create(KNullDesC(), &idleDetectorThreadFunc, 1024, &User::Allocator(), this);
if (err != KErrNone)
- m_lock.Close();
- qt_symbian_throwIfError(err);
+ return; // Fail silently on error. Next kick will try again. Exception might stop the event being processed
m_idleDetectorThread.SetPriority(EPriorityAbsoluteBackgroundNormal);
m_idleDetectorThread.Resume();
+ m_running = true;
+ // get a callback from QCoreApplication destruction to stop this thread
+ qAddPostRoutine(StopIdleDetectorThread);
}
- ~QIdleDetectorThread()
+ void stop()
{
+ QMutexLocker lock(&m_mutex);
+ if (!m_running)
+ return;
// 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_kick.release();
m_idleDetectorThread.SetPriority(EPriorityNormal);
TRequestStatus s;
m_idleDetectorThread.Logon(s);
User::WaitForRequest(s);
m_idleDetectorThread.Close();
- m_lock.Close();
+ m_running = false;
}
void kick()
{
+ start();
m_state = STATE_KICKED;
- m_lock.Signal();
+ m_kick.release();
}
bool hasRun()
@@ -700,20 +721,29 @@ private:
void IdleLoop()
{
while (!m_stop) {
- m_lock.Wait();
+ m_kick.acquire();
m_state = STATE_RUN;
}
}
+ static void StopIdleDetectorThread();
+
private:
enum IdleStates {STATE_KICKED, STATE_RUN} m_state;
bool m_stop;
+ bool m_running;
RThread m_idleDetectorThread;
- RSemaphore m_lock;
+ QSemaphore m_kick;
+ QMutex m_mutex;
};
Q_GLOBAL_STATIC(QIdleDetectorThread, idleDetectorThread);
+void QIdleDetectorThread::StopIdleDetectorThread()
+{
+ idleDetectorThread()->stop();
+}
+
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
diff --git a/src/corelib/thread/qthread_symbian.cpp b/src/corelib/thread/qthread_symbian.cpp
index 128124f..1474b36 100644
--- a/src/corelib/thread/qthread_symbian.cpp
+++ b/src/corelib/thread/qthread_symbian.cpp
@@ -48,7 +48,14 @@
#include <private/qsystemerror_p.h>
#include <sched.h>
+#include <hal.h>
+#include <hal_data.h>
+// You only find these enumerations on Symbian^3 onwards, so we need to provide our own
+// to remain compatible with older releases. They won't be called by pre-Sym^3 SDKs.
+
+// HALData::ENumCpus
+#define QT_HALData_ENumCpus 119
QT_BEGIN_NAMESPACE
@@ -131,11 +138,7 @@ public:
{
data->symbian_thread_handle.LogonCancel(iStatus);
}
- void RunL()
- {
- data->deref();
- delete this;
- }
+ void RunL();
private:
QThreadData* data;
};
@@ -177,6 +180,7 @@ public:
for (int i=threadsToAdd.size()-1; i>=0; i--) {
// Create an active object to monitor the thread
new (ELeave) QCAdoptedThreadMonitor(threadsToAdd[i]);
+ count++;
threadsToAdd.pop_back();
}
start();
@@ -193,6 +197,8 @@ public:
User::WaitForRequest(started);
monitorThread.Close();
}
+ if (RThread().Id() == adoptedThreadAdder->monitorThread.Id())
+ return;
adoptedThreadAdder->threadsToAdd.push_back(thread);
if (adoptedThreadAdder->stat) {
adoptedThreadAdder->monitorThread.RequestComplete(adoptedThreadAdder->stat, KErrNone);
@@ -204,15 +210,15 @@ public:
CleanupStack::PushL(scheduler);
CActiveScheduler::Install(scheduler);
- adoptedThreadAdder = new(ELeave) QCAddAdoptedThread();
+ adoptedThreadAdder = new(ELeave) QCAddAdoptedThread();
CleanupStack::PushL(adoptedThreadAdder);
adoptedThreadAdder->ConstructL();
+ QCAddAdoptedThread *adder = adoptedThreadAdder;
RThread::Rendezvous(KErrNone);
CActiveScheduler::Start();
- CleanupStack::PopAndDestroy(adoptedThreadAdder);
- adoptedThreadAdder = 0;
+ CleanupStack::PopAndDestroy(adder);
CleanupStack::PopAndDestroy(scheduler);
}
static int monitorThreadFunc(void *)
@@ -224,18 +230,37 @@ public:
delete cleanup;
return ret;
}
+ static void threadDied()
+ {
+ QMutexLocker adoptedThreadMonitorMutexlock(&adoptedThreadMonitorMutex);
+ if (adoptedThreadAdder) {
+ adoptedThreadAdder->count--;
+ if (adoptedThreadAdder->count <= 0 && adoptedThreadAdder->threadsToAdd.size() == 0) {
+ CActiveScheduler::Stop();
+ adoptedThreadAdder = 0;
+ }
+ }
+ }
private:
QVector<QThread*> threadsToAdd;
RThread monitorThread;
static QMutex adoptedThreadMonitorMutex;
- static QCAddAdoptedThread* adoptedThreadAdder;
+ static QCAddAdoptedThread *adoptedThreadAdder;
+ int count;
TRequestStatus *stat;
};
QMutex QCAddAdoptedThread::adoptedThreadMonitorMutex;
QCAddAdoptedThread* QCAddAdoptedThread::adoptedThreadAdder = 0;
+void QCAdoptedThreadMonitor::RunL()
+{
+ data->deref();
+ QCAddAdoptedThread::threadDied();
+ delete this;
+}
+
void QAdoptedThread::init()
{
Q_D(QThread);
@@ -358,10 +383,16 @@ Qt::HANDLE QThread::currentThreadId()
int QThread::idealThreadCount()
{
- int cores = -1;
-
- // ### TODO - Get the number of cores from HAL? when multicore architectures (SMP) are supported
- cores = 1;
+ int cores = 1;
+
+ if (QSysInfo::symbianVersion() >= QSysInfo::SV_SF_3) {
+ TInt inumcpus;
+ TInt err;
+ err = HAL::Get((HALData::TAttribute)QT_HALData_ENumCpus, inumcpus);
+ if (err == KErrNone) {
+ cores = qMax(inumcpus, 1);
+ }
+ }
return cores;
}
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index a1c6458..835378a 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -50,11 +50,6 @@
#include <private/qeventdispatcher_unix_p.h>
-#ifdef Q_OS_SYMBIAN
-#include <hal.h>
-#include <hal_data.h>
-#endif
-
#include "qthreadstorage.h"
#include "qthread_p.h"
@@ -64,12 +59,6 @@
#include <sched.h>
#include <errno.h>
-// You only find these enumerations on Symbian^3 onwards, so we need to provide our own
-// to remain compatible with older releases. They won't be called by pre-Sym^3 SDKs.
-
-// HALData::ENumCpus
-#define QT_HALData_ENumCpus 119
-
#ifdef Q_OS_BSD4
#include <sys/sysctl.h>
#endif
@@ -378,21 +367,6 @@ int QThread::idealThreadCount()
#elif defined(Q_OS_INTEGRITY)
// as of aug 2008 Integrity only supports one single core CPU
cores = 1;
-#elif defined(Q_OS_SYMBIAN)
- if (QSysInfo::symbianVersion() >= QSysInfo::SV_SF_3) {
- TInt inumcpus;
- TInt err;
- err = HAL::Get((HALData::TAttribute)QT_HALData_ENumCpus, inumcpus);
- if (err != KErrNone) {
- cores = 1;
- } else if ( inumcpus <= 0 ) {
- cores = 1;
- } else {
- cores = inumcpus;
- }
- } else {
- cores = 1;
- }
#elif defined(Q_OS_VXWORKS)
// VxWorks
# if defined(QT_VXWORKS_HAS_CPUSET)
diff --git a/src/gui/widgets/qcombobox.cpp b/src/gui/widgets/qcombobox.cpp
index b5dda5a..34e3672 100644
--- a/src/gui/widgets/qcombobox.cpp
+++ b/src/gui/widgets/qcombobox.cpp
@@ -2358,7 +2358,12 @@ void QComboBox::showPopup()
initStyleOption(&opt);
QRect listRect(style->subControlRect(QStyle::CC_ComboBox, &opt,
QStyle::SC_ComboBoxListBoxPopup, this));
+#ifndef Q_WS_S60
QRect screen = d->popupGeometry(QApplication::desktop()->screenNumber(this));
+#else
+ QRect screen = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect());
+#endif
+
QPoint below = mapToGlobal(listRect.bottomLeft());
int belowHeight = screen.bottom() - below.y();
QPoint above = mapToGlobal(listRect.topLeft());
@@ -2486,18 +2491,10 @@ void QComboBox::showPopup()
listRect.setWidth(listRect.height());
//by default popup is centered on screen in landscape
listRect.moveCenter(screen.center());
- if (staConTopRect.IsEmpty()) {
- TRect cbaRect = TRect();
- AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EControlPane, cbaRect);
- AknLayoutUtils::TAknCbaLocation cbaLocation = AknLayoutUtils::CbaLocation();
- switch (cbaLocation) {
- case AknLayoutUtils::EAknCbaLocationRight:
- listRect.setRight(screen.right());
- break;
- case AknLayoutUtils::EAknCbaLocationLeft:
- listRect.setLeft(screen.left());
- break;
- }
+ if (staConTopRect.IsEmpty() && AknLayoutUtils::CbaLocation() != AknLayoutUtils::EAknCbaLocationBottom) {
+ // landscape without stacon, menu should be at the right
+ (opt.direction == Qt::LeftToRight) ? listRect.setRight(screen.right()) :
+ listRect.setLeft(screen.left());
}
}
#endif
@@ -2716,7 +2713,7 @@ void QComboBox::changeEvent(QEvent *e)
initStyleOption(&opt);
if (style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, this)) {
- const QRect screen = d->popupGeometry(QApplication::desktop()->screenNumber(this));
+ QRect screen = qt_TRect2QRect(static_cast<CEikAppUi*>(S60->appUi())->ClientRect());
QRect listRect(style()->subControlRect(QStyle::CC_ComboBox, &opt,
QStyle::SC_ComboBoxListBoxPopup, this));
@@ -2731,13 +2728,14 @@ void QComboBox::changeEvent(QEvent *e)
listRect.setWidth(listRect.height());
//by default popup is centered on screen in landscape
listRect.moveCenter(screen.center());
- if (staConTopRect.IsEmpty()) {
+ if (staConTopRect.IsEmpty() && AknLayoutUtils::CbaLocation() != AknLayoutUtils::EAknCbaLocationBottom) {
// landscape without stacon, menu should be at the right
(opt.direction == Qt::LeftToRight) ? listRect.setRight(screen.right()) :
listRect.setLeft(screen.left());
}
- d->container->setGeometry(listRect);
}
+
+ d->container->setGeometry(listRect);
}
}
#endif
@@ -2770,6 +2768,10 @@ void QComboBox::changeEvent(QEvent *e)
void QComboBox::resizeEvent(QResizeEvent *)
{
Q_D(QComboBox);
+#ifdef Q_WS_S60
+ if (d->viewContainer() && d->viewContainer()->isVisible())
+ showPopup();
+#endif
d->updateLineEditGeometry();
}