@ -3211,39 +3211,86 @@ struct TQRegExpPrivate
} ;
# ifndef TQT_NO_REGEXP_OPTIM
static TQSingleCleanupHandler < TQCache < TQRegExpEngine > > cleanup_cache ;
# ifndef TQT_THREAD_SUPPORT
static TQCache < TQRegExpEngine > * engineCache = 0 ;
namespace {
// Due to regexpEngine() is called from destructors (including destructors of static TQRegExp
// instances) it may cause it to try to resurrect the engine cache after it's been already
// destroyed, so we should keep an eye on it, hence we have a somewhat peculiar singleton here
// Yay! Handling destruction of statics is so much fun! >_<
class EngineCacheKeaper {
public :
static TQCache < TQRegExpEngine > * getCache ( ) {
if ( wasDestroyed ) {
return nullptr ;
}
static EngineCacheKeaper self ;
return self . doGetCache ( ) ;
}
private :
TQCache < TQRegExpEngine > * doGetCache ( ) {
# ifdef TQT_THREAD_SUPPORT
TQThreadInstance * currentThread = TQThreadInstance : : current ( ) ;
if ( ! currentThread ) {
return nullptr ;
}
TQCache < TQRegExpEngine > * engineCache = engineCaches . localData ( ) ;
# endif // TQT_THREAD_SUPPORT
if ( engineCache = = 0 ) {
engineCache = new TQCache < TQRegExpEngine > ;
engineCache - > setAutoDelete ( TRUE ) ;
# ifdef TQT_THREAD_SUPPORT
engineCaches . setLocalData ( engineCache ) ;
# else
static TQSingleCleanupHandler < TQCache < TQRegExpEngine > > cleanup_cache ;
cleanup_cache . set ( & engineCache ) ;
# endif // !TQT_THREAD_SUPPORT
}
return engineCache ;
}
# ifdef TQT_THREAD_SUPPORT
TQThreadStorage < TQCache < TQRegExpEngine > * > engineCaches ;
# else
TQCache < TQRegExpEngine > * engineCache ;
# endif // TQT_THREAD_SUPPORT
~ EngineCacheKeaper ( ) {
wasDestroyed = TRUE ;
# if !defined(TQT_THREAD_SUPPORT)
delete engineCache ;
# endif // !defined(TQT_THREAD_SUPPORT)
}
static bool wasDestroyed ;
} ;
bool EngineCacheKeaper : : wasDestroyed = 0 ;
}
# endif // TQT_NO_REGEXP_OPTIM
static void regexpEngine ( TQRegExpEngine * & eng , const TQString & pattern ,
bool caseSensitive , bool deref )
{
# ifdef TQT_THREAD_SUPPORT
static TQThreadStorage < TQCache < TQRegExpEngine > * > engineCaches ;
TQCache < TQRegExpEngine > * engineCache = 0 ;
TQThreadInstance * currentThread = TQThreadInstance : : current ( ) ;
if ( currentThread )
engineCache = engineCaches . localData ( ) ;
# endif // TQT_THREAD_SUPPORT
# ifndef TQT_NO_REGEXP_OPTIM
TQCache < TQRegExpEngine > * engineCache = EngineCacheKeaper : : getCache ( ) ;
# endif // TQT_NO_REGEXP_OPTIM
if ( ! deref ) {
# ifndef TQT_NO_REGEXP_OPTIM
# ifdef TQT_THREAD_SUPPORT
if ( currentThread )
# endif
{
if ( engineCache ! = 0 ) {
eng = engineCache - > take ( pattern ) ;
if ( eng = = 0 | | eng - > caseSensitive ( ) ! = caseSensitive ) {
delete eng ;
} else {
eng - > ref ( ) ;
return ;
}
}
}
if ( engineCache ) {
eng = engineCache - > take ( pattern ) ;
if ( eng = = 0 | | eng - > caseSensitive ( ) ! = caseSensitive ) {
delete eng ;
} else {
eng - > ref ( ) ;
return ;
}
}
# endif // TQT_NO_REGEXP_OPTIM
eng = new TQRegExpEngine ( pattern , caseSensitive ) ;
return ;
@ -3251,23 +3298,11 @@ static void regexpEngine( TQRegExpEngine *&eng, const TQString &pattern,
if ( eng - > deref ( ) ) {
# ifndef TQT_NO_REGEXP_OPTIM
# ifdef TQT_THREAD_SUPPORT
if ( currentThread )
# endif
{
if ( engineCache = = 0 ) {
engineCache = new TQCache < TQRegExpEngine > ;
engineCache - > setAutoDelete ( TRUE ) ;
# ifdef TQT_THREAD_SUPPORT
engineCaches . setLocalData ( engineCache ) ;
# else
cleanup_cache . set ( & engineCache ) ;
# endif // !TQT_THREAD_SUPPORT
}
if ( ! pattern . isNull ( ) & &
engineCache - > insert ( pattern , eng , 4 + pattern . length ( ) / 4 ) )
return ;
}
if ( engineCache ) {
if ( ! pattern . isNull ( ) & &
engineCache - > insert ( pattern , eng , 4 + pattern . length ( ) / 4 ) )
return ;
}
# else
Q_UNUSED ( pattern ) ;
# endif // TQT_NO_REGEXP_OPTIM