1 /****************************************************************************
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the Symbian application wrapper of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
44 #ifdef QT_EXPORTS_NOT_FROZEN
45 // If exports in Qt DLLs are not frozen in this build, then we have to pick up the
46 // allocator creation function by import link. We know the function will be present
47 // in the DLLs we test with, as we have to use the DLLs we have built.
49 struct SStdEpocThreadCreateInfo;
51 Q_CORE_EXPORT TInt qt_symbian_SetupThreadHeap(TBool aNotFirst, SStdEpocThreadCreateInfo& aInfo);
56 * Uses link-time symbol preemption to capture a call from the application
57 * startup. On return, there is some kind of heap allocator installed on the
60 TInt UserHeap::SetupThreadHeap(TBool aNotFirst, SStdEpocThreadCreateInfo& aInfo)
62 return qt_symbian_SetupThreadHeap(aNotFirst, aInfo);
65 #else // QT_EXPORTS_NOT_FROZEN
66 // If we are using an export frozen build, it should be compatible with all 4.7.x Qt releases.
67 // We want to use the allocator creation function introduced in qtcore.dll after 4.7.1. But we
68 // can't import link to it, as it may not be present in whatever 4.7.x DLLs we are running with.
69 // So the function is found and called dynamically, by library lookup. If it is not found, we
70 // use the OS allocator creation functions instead.
72 #if defined(QT_LIBINFIX)
73 # define QT_LSTRING2(x) L##x
74 # define QT_LSTRING(x) QT_LSTRING2(x)
75 # define QT_LIBINFIX_UNICODE QT_LSTRING(QT_LIBINFIX)
77 # define QT_LIBINFIX_UNICODE L""
80 _LIT(QtCoreLibName, "qtcore" QT_LIBINFIX_UNICODE L".dll");
82 struct SThreadCreateInfo
86 TThreadFunction iFunction;
88 TAny* iSupervisorStack;
89 TInt iSupervisorStackSize;
92 TInt iInitialThreadPriority;
94 TInt iTotalSize; // Size including any extras (must be a multiple of 8 bytes)
97 struct SStdEpocThreadCreateInfo : public SThreadCreateInfo
99 RAllocator* iAllocator;
100 TInt iHeapInitialSize;
102 TInt iPadding; // Make structure size a multiple of 8 bytes
108 * Uses link-time symbol preemption to capture a call from the application
109 * startup. On return, there is some kind of heap allocator installed on the
112 typedef int (*TSetupThreadHeapFunc)(TBool aNotFirst, SStdEpocThreadCreateInfo& aInfo);
113 // keep the SetupThreadHeap() pointer so that we don't reload QtCore.dll after the first time
114 static TSetupThreadHeapFunc gp_qt_symbian_SetupThreadHeap = 0;
115 static bool gp_qt_symbian_SetupThreadHeap_set = false;
117 TInt UserHeap::SetupThreadHeap(TBool aNotFirst, SStdEpocThreadCreateInfo& aInfo)
122 // on first call, aNotFirst will be false.
123 // on second call, gp_qt_symbian_SetupThreadHeap_set will be false(!) because WSD is zeroed after the first call
124 // on subsequent calls, both will be true and we can use the stored SetupThreadHeap() pointer
125 if (aNotFirst && gp_qt_symbian_SetupThreadHeap_set) {
126 if (gp_qt_symbian_SetupThreadHeap)
127 return (*gp_qt_symbian_SetupThreadHeap)(aNotFirst, aInfo);
129 // attempt to create the fast allocator through a known export ordinal in qtcore.dll
131 gp_qt_symbian_SetupThreadHeap_set = true;
132 if (qtcore.Load(QtCoreLibName) == KErrNone) {
133 const int qt_symbian_SetupThreadHeap_eabi_ordinal = 3713;
134 TLibraryFunction libFunc = qtcore.Lookup(qt_symbian_SetupThreadHeap_eabi_ordinal);
136 TSetupThreadHeapFunc p_qt_symbian_SetupThreadHeap = TSetupThreadHeapFunc(libFunc);
137 gp_qt_symbian_SetupThreadHeap = p_qt_symbian_SetupThreadHeap;
138 r = (*p_qt_symbian_SetupThreadHeap)(aNotFirst, aInfo);
147 // no fast allocator support - use default allocator creation
148 if (!aInfo.iAllocator && aInfo.iHeapInitialSize>0)
152 r = UserHeap::CreateThreadHeap(aInfo, pH);
154 else if (aInfo.iAllocator)
157 RAllocator* pA = aInfo.iAllocator;
159 User::SwitchAllocator(pA);
165 #endif // QT_EXPORTS_NOT_FROZEN