Prevent creation of text codecs when the application is shutting down. This resolves issue #142

Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
(cherry picked from commit 7563c4825f)
r14.1.x
Michele Calgaro 8 months ago
parent b44105403d
commit 57465e08e9
Signed by: MicheleC
GPG Key ID: 2A75B7CA8ADED5CF

@ -89,7 +89,7 @@
#endif #endif
static TQValueList<TQTextCodec*> *all = 0; static TQValueList<TQTextCodec*> *all = 0;
static bool destroying_is_ok; // starts out as 0 static bool codecs_destroyed = false;
static TQTextCodec * localeMapper = 0; static TQTextCodec * localeMapper = 0;
class TQTextCodecCleanup { class TQTextCodecCleanup {
@ -118,18 +118,16 @@ static TQTextCodecCleanup qtextcodec_cleanup;
void TQTextCodec::deleteAllCodecs() void TQTextCodec::deleteAllCodecs()
{ {
codecs_destroyed = true;
if ( !all ) if ( !all )
return; return;
#ifdef TQT_THREAD_SUPPORT #ifdef TQT_THREAD_SUPPORT
TQMutexLocker locker( tqt_global_mutexpool ? TQMutexLocker locker( tqt_global_mutexpool ?
tqt_global_mutexpool->get( &all ) : 0 ); tqt_global_mutexpool->get( &all ) : 0 );
if ( !all )
return;
#endif // TQT_THREAD_SUPPORT #endif // TQT_THREAD_SUPPORT
destroying_is_ok = TRUE;
TQValueList<TQTextCodec*> *ball = all; TQValueList<TQTextCodec*> *ball = all;
all = 0; all = 0;
TQValueList<TQTextCodec*>::Iterator it; TQValueList<TQTextCodec*>::Iterator it;
@ -140,26 +138,10 @@ void TQTextCodec::deleteAllCodecs()
ball->clear(); ball->clear();
delete ball; delete ball;
destroying_is_ok = FALSE; localeMapper = 0;
}
static void realSetup();
static inline void setup()
{
if ( all ) return;
#ifdef TQT_THREAD_SUPPORT
TQMutexLocker locker( tqt_global_mutexpool ?
tqt_global_mutexpool->get( &all ) : 0 );
if ( all ) return;
#endif // TQT_THREAD_SUPPORT
realSetup();
} }
static void setup();
class TQTextStatelessEncoder: public TQTextEncoder { class TQTextStatelessEncoder: public TQTextEncoder {
const TQTextCodec* codec; const TQTextCodec* codec;
@ -429,8 +411,16 @@ TQString TQTextStatelessDecoder::toUnicode(const char* chars, int len)
*/ */
TQTextCodec::TQTextCodec() TQTextCodec::TQTextCodec()
{ {
// 'codecs_destroyed' should never be true at this point
if (!codecs_destroyed)
{
setup(); setup();
#ifdef TQT_THREAD_SUPPORT
TQMutexLocker locker( tqt_global_mutexpool ?
tqt_global_mutexpool->get( &all ) : 0 );
#endif // TQT_THREAD_SUPPORT
all->insert( all->begin(), this ); all->insert( all->begin(), this );
}
} }
@ -442,8 +432,13 @@ TQTextCodec::TQTextCodec()
*/ */
TQTextCodec::~TQTextCodec() TQTextCodec::~TQTextCodec()
{ {
if ( !destroying_is_ok ) if ( !codecs_destroyed )
tqWarning("TQTextCodec::~TQTextCodec() called by application"); tqWarning("TQTextCodec::~TQTextCodec() called by application");
#ifdef TQT_THREAD_SUPPORT
TQMutexLocker locker( tqt_global_mutexpool ?
tqt_global_mutexpool->get( &all ) : 0 );
#endif // TQT_THREAD_SUPPORT
if ( all ) if ( all )
all->remove( this ); all->remove( this );
} }
@ -529,6 +524,11 @@ int TQTextCodec::simpleHeuristicNameMatch(const char* name, const char* hint)
*/ */
TQTextCodec* TQTextCodec::codecForIndex(int i) TQTextCodec* TQTextCodec::codecForIndex(int i)
{ {
if (codecs_destroyed)
{
return nullptr;
}
setup(); setup();
return (uint)i >= all->count() ? 0 : *all->at(i); return (uint)i >= all->count() ? 0 : *all->at(i);
} }
@ -540,6 +540,11 @@ TQTextCodec* TQTextCodec::codecForIndex(int i)
*/ */
TQTextCodec* TQTextCodec::codecForMib(int mib) TQTextCodec* TQTextCodec::codecForMib(int mib)
{ {
if (codecs_destroyed)
{
return nullptr;
}
setup(); setup();
TQValueList<TQTextCodec*>::ConstIterator i; TQValueList<TQTextCodec*>::ConstIterator i;
TQTextCodec* result=0; TQTextCodec* result=0;
@ -818,10 +823,15 @@ void TQTextCodec::setCodecForLocale(TQTextCodec *c) {
TQTextCodec* TQTextCodec::codecForLocale() TQTextCodec* TQTextCodec::codecForLocale()
{ {
if ( localeMapper ) if (codecs_destroyed)
return localeMapper; {
return nullptr;
}
if (!localeMapper)
{
setup(); setup();
}
return localeMapper; return localeMapper;
} }
@ -838,6 +848,11 @@ TQTextCodec* TQTextCodec::codecForLocale()
TQTextCodec* TQTextCodec::codecForName( const char* name, int accuracy ) TQTextCodec* TQTextCodec::codecForName( const char* name, int accuracy )
{ {
if (codecs_destroyed)
{
return nullptr;
}
if ( !name || !*name ) if ( !name || !*name )
return 0; return 0;
@ -879,6 +894,11 @@ TQTextCodec* TQTextCodec::codecForName( const char* name, int accuracy )
*/ */
TQTextCodec* TQTextCodec::codecForContent(const char* chars, int len) TQTextCodec* TQTextCodec::codecForContent(const char* chars, int len)
{ {
if (codecs_destroyed)
{
return nullptr;
}
setup(); setup();
TQValueList<TQTextCodec*>::ConstIterator i; TQValueList<TQTextCodec*>::ConstIterator i;
TQTextCodec* result = 0; TQTextCodec* result = 0;
@ -2777,7 +2797,7 @@ static TQTextCodec *checkForCodec(const char *name) {
return c; return c;
} }
/* the next two functions are implicitely thread safe, /* the next function is implicitely thread safe,
as they are only called by setup() which uses a mutex. as they are only called by setup() which uses a mutex.
*/ */
static void setupLocaleMapper() static void setupLocaleMapper()
@ -2901,12 +2921,32 @@ static void setupLocaleMapper()
} }
static void realSetup() static void setup()
{ {
#if defined(QT_CHECK_STATE) #if defined(QT_CHECK_STATE)
if ( destroying_is_ok ) if ( codecs_destroyed )
tqWarning( "TQTextCodec: creating new codec during codec cleanup!" ); {
// If codecs have been destroyed, the application is being destroyed.
// Do not create new codecs since this could lead to SEGV while trying to
// print a message using tqWarning/tqDebug/tqFatal at this stage
//
// Note: the use of `printf` instead of `tqWarning` is intentional. We should never
// get to this line of code. If we do, we are in some strange exception that we
// didn't think of. Using `tqWarning` could potentially lead to an infinite loop with
// `tqWarning` trying to setup codecs and this method calling `tqWarning` again.
// Using `printf` makes sure this never happens, even for exceptions we didn't foresee.
printf("TQTextCodec: setup() called when codecs have already been destroyed\n"); fflush(stdout);
return;
}
#endif #endif
if ( all ) return;
#ifdef TQT_THREAD_SUPPORT
TQMutexLocker locker( tqt_global_mutexpool ?
tqt_global_mutexpool->get( &all ) : 0 );
#endif // TQT_THREAD_SUPPORT
all = new TQValueList<TQTextCodec*>; all = new TQValueList<TQTextCodec*>;
(void)new TQLatin1Codec; (void)new TQLatin1Codec;

Loading…
Cancel
Save