diff options
Diffstat (limited to 'src/tools')
-rw-r--r-- | src/tools/ntqshared.h | 1 | ||||
-rw-r--r-- | src/tools/ntqstring.h | 46 | ||||
-rw-r--r-- | src/tools/qstring.cpp | 329 | ||||
-rw-r--r-- | src/tools/qthreadinstance_p.h | 1 |
4 files changed, 292 insertions, 85 deletions
diff --git a/src/tools/ntqshared.h b/src/tools/ntqshared.h index 7f02c772a..a556ac200 100644 --- a/src/tools/ntqshared.h +++ b/src/tools/ntqshared.h @@ -45,7 +45,6 @@ #include "ntqglobal.h" #endif // QT_H - struct Q_EXPORT TQShared { TQShared() : count( 1 ) { } diff --git a/src/tools/ntqstring.h b/src/tools/ntqstring.h index b91caf83c..4d473e016 100644 --- a/src/tools/ntqstring.h +++ b/src/tools/ntqstring.h @@ -71,6 +71,7 @@ class TQRegExp; class TQString; class TQCharRef; +class TQMutex; template <class T> class TQDeepCopy; class Q_EXPORT TQChar { @@ -359,22 +360,14 @@ inline bool operator>( TQChar c1, TQChar c2 ) { return !(c2>=c1); } // internal struct Q_EXPORT TQStringData : public TQShared { - TQStringData() : - TQShared(), unicode(0), ascii(0), len(0), issimpletext(TRUE), maxl(0), islatin1(FALSE), security_unpaged(FALSE) { ref(); } - TQStringData(TQChar *u, uint l, uint m) : - TQShared(), unicode(u), ascii(0), len(l), issimpletext(FALSE), maxl(m), islatin1(FALSE), security_unpaged(FALSE) { } + TQStringData(); + TQStringData(TQChar *u, uint l, uint m); ~TQStringData(); void deleteSelf(); TQChar *unicode; char *ascii; - void setDirty() { - if ( ascii ) { - delete [] ascii; - ascii = 0; - } - issimpletext = FALSE; - } + void setDirty(); #ifdef Q_OS_MAC9 uint len; #else @@ -390,6 +383,8 @@ struct Q_EXPORT TQStringData : public TQShared { bool security_unpaged : 1; + TQMutex* mutex; + private: #if defined(TQ_DISABLE_COPY) TQStringData( const TQStringData& ); @@ -646,13 +641,7 @@ public: TQChar constref(uint i) const { return at(i); } - TQChar& ref(uint i) - { // Optimized for easy-inlining by simple compilers. - if ( d->count != 1 || i >= d->len ) - subat( i ); - d->setDirty(); - return d->unicode[i]; - } + TQChar& ref(uint i); const TQChar* unicode() const { return d->unicode; } const char* ascii() const; @@ -747,7 +736,7 @@ private: friend class TQConstString; friend class TQTextStream; - TQString( TQStringData* dd, bool /* dummy */ ) : d(dd) { } + TQString( TQStringData* dd, bool /* dummy */ ); // needed for TQDeepCopy void detach(); @@ -839,25 +828,6 @@ Q_EXPORT TQDataStream &operator>>( TQDataStream &, TQString & ); TQString inline functions *****************************************************************************/ -// These two move code into makeSharedNull() and deletesData() -// to improve cache-coherence (and reduce code bloat), while -// keeping the common cases fast. -// -// No safe way to pre-init shared_null on ALL compilers/linkers. -inline TQString::TQString() : - d(shared_null ? shared_null : makeSharedNull()) -{ - d->ref(); -} -// -inline TQString::~TQString() -{ - if ( d->deref() ) { - if ( d != shared_null ) - d->deleteSelf(); - } -} - // needed for TQDeepCopy inline void TQString::detach() { real_detach(); } diff --git a/src/tools/qstring.cpp b/src/tools/qstring.cpp index a5408cac5..1ea356933 100644 --- a/src/tools/qstring.cpp +++ b/src/tools/qstring.cpp @@ -87,6 +87,12 @@ #define ULLONG_MAX TQ_UINT64_C(18446744073709551615) #endif +#ifdef QT_THREAD_SUPPORT +#include "ntqmutex.h" +#endif // QT_THREAD_SUPPORT + +extern TQMutex *tqt_sharedStringMutex; + static int ucstrcmp( const TQString &as, const TQString &bs ) { const TQChar *a = as.unicode(); @@ -1033,12 +1039,54 @@ static inline bool format(TQChar::Decomposition tag, TQString & str, } // format() #endif +TQStringData::TQStringData() : TQShared(), + unicode(0), + ascii(0), + len(0), + issimpletext(TRUE), + maxl(0), + islatin1(FALSE), + security_unpaged(FALSE) { +#ifdef QT_THREAD_SUPPORT + mutex = new TQMutex( TRUE ); + mutex->lock(); +#endif // QT_THREAD_SUPPORT + ref(); +#ifdef QT_THREAD_SUPPORT + mutex->unlock(); +#endif // QT_THREAD_SUPPORT +} + +TQStringData::TQStringData(TQChar *u, uint l, uint m) : TQShared(), + unicode(u), + ascii(0), + len(l), + issimpletext(FALSE), + maxl(m), + islatin1(FALSE), + security_unpaged(FALSE) { +#ifdef QT_THREAD_SUPPORT + mutex = new TQMutex( TRUE ); +#endif // QT_THREAD_SUPPORT +} + TQStringData::~TQStringData() { - if ( unicode ) delete[] ((char*)unicode); - if ( ascii && security_unpaged ) { - munlock(ascii, LINUX_MEMLOCK_LIMIT_BYTES); - } - if ( ascii ) delete[] ascii; + if ( unicode ) delete[] ((char*)unicode); + if ( ascii && security_unpaged ) { + munlock(ascii, LINUX_MEMLOCK_LIMIT_BYTES); + } + if ( ascii ) delete[] ascii; +#ifdef QT_THREAD_SUPPORT + if ( mutex ) delete mutex; +#endif // QT_THREAD_SUPPORT +} + +void TQStringData::setDirty() { + if ( ascii ) { + delete [] ascii; + ascii = 0; + } + issimpletext = FALSE; } /* @@ -1194,27 +1242,30 @@ TQChar* TQString::latin1ToUnicode( const char *str, uint* len, uint maxlen ) return result; } -static TQChar* internalLatin1ToUnicode( const char *str, uint* len, - uint maxlen = (uint)-1 ) +static TQChar* internalLatin1ToUnicode( const char *str, uint* len, uint maxlen = (uint)-1 ) { TQChar* result = 0; uint l = 0; if ( str ) { if ( maxlen != (uint)-1 ) { - while ( l < maxlen && str[l] ) + while ( l < maxlen && str[l] ) { l++; - } else { + } + } + else { // Faster? l = int(strlen( str )); } TQChar *uc = QT_ALLOC_QCHAR_VEC( l ); result = uc; uint i = l; - while ( i-- ) + while ( i-- ) { *uc++ = *str++; + } } - if ( len ) + if ( len ) { *len = l; + } return result; } @@ -1395,11 +1446,26 @@ QT_STATIC_CONST_IMPL TQChar TQChar::nbsp((ushort)0x00a0); TQStringData* TQString::makeSharedNull() { +#ifdef QT_THREAD_SUPPORT + if (tqt_sharedStringMutex) tqt_sharedStringMutex->lock(); +#endif // QT_THREAD_SUPPORT + + if (TQString::shared_null) { +#ifdef QT_THREAD_SUPPORT + if (tqt_sharedStringMutex) tqt_sharedStringMutex->unlock(); +#endif // QT_THREAD_SUPPORT + return TQString::shared_null; + } + TQString::shared_null = new TQStringData; #if defined( Q_OS_MAC ) || defined(Q_OS_SOLARIS) || defined(Q_OS_HPUX) || defined(Q_OS_AIX) TQString *that = const_cast<TQString *>(&TQString::null); that->d = TQString::shared_null; #endif + +#ifdef QT_THREAD_SUPPORT + if (tqt_sharedStringMutex) tqt_sharedStringMutex->unlock(); +#endif // QT_THREAD_SUPPORT return TQString::shared_null; } @@ -1412,6 +1478,24 @@ TQStringData* TQString::makeSharedNull() \sa isNull() */ +// FIXME +// Original Qt3 code stated that there is +// "No safe way to pre-init shared_null on ALL compilers/linkers" +// Is this still true? + +TQString::TQString() : + d(0) +{ + d = shared_null ? shared_null : makeSharedNull(); +#ifdef QT_THREAD_SUPPORT + d->mutex->lock(); +#endif // QT_THREAD_SUPPORT + d->ref(); +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT +} + /*! Constructs a string of length one, containing the character \a ch. */ @@ -1428,7 +1512,15 @@ TQString::TQString( TQChar ch ) TQString::TQString( const TQString &s ) : d(s.d) { +#ifdef QT_THREAD_SUPPORT + d->mutex->lock(); +#endif // QT_THREAD_SUPPORT + d->ref(); + +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT } /*! @@ -1451,7 +1543,13 @@ TQString::TQString( int size, bool /*dummy*/ ) d = new TQStringData( uc, 0, l ); } else { d = shared_null ? shared_null : (shared_null=new TQStringData); +#ifdef QT_THREAD_SUPPORT + d->mutex->lock(); +#endif // QT_THREAD_SUPPORT d->ref(); +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT } } @@ -1493,11 +1591,19 @@ TQString::TQString( const TQChar* unicode, uint length ) { if ( !unicode && !length ) { d = shared_null ? shared_null : makeSharedNull(); +#ifdef QT_THREAD_SUPPORT + d->mutex->lock(); +#endif // QT_THREAD_SUPPORT d->ref(); - } else { +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT + } + else { TQChar* uc = QT_ALLOC_QCHAR_VEC( length ); - if ( unicode ) + if ( unicode ) { memcpy(uc, unicode, length*sizeof(TQChar)); + } d = new TQStringData(uc,unicode ? length : 0,length); } } @@ -1556,6 +1662,10 @@ TQString::TQString( const std::string &str ) } #endif +TQString::TQString( TQStringData* dd, bool /* dummy */ ) { + d = dd; +} + /*! \fn TQString::~TQString() @@ -1563,6 +1673,31 @@ TQString::TQString( const std::string &str ) last reference to the string. */ +TQString::~TQString() +{ +#ifdef QT_THREAD_SUPPORT + d->mutex->lock(); +#endif // QT_THREAD_SUPPORT + if ( d->deref() ) { + if ( d != shared_null ) { +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT + d->deleteSelf(); + } + else { +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT + } + } + else { +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT + } +} + /*! Deallocates any space reserved solely by this TQString. @@ -1580,11 +1715,25 @@ void TQString::real_detach() void TQString::deref() { - if ( d && d->deref() ) { - if ( d != shared_null ) - delete d; - d = 0; - } + if ( d ) { +#ifdef QT_THREAD_SUPPORT + d->mutex->lock(); +#endif // QT_THREAD_SUPPORT + if ( d->deref() ) { +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT + if ( d != shared_null ) { + delete d; + } + d = 0; + } + else { +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT + } + } } void TQStringData::deleteSelf() @@ -1624,9 +1773,16 @@ void TQStringData::deleteSelf() */ TQString &TQString::operator=( const TQString &s ) { +#ifdef QT_THREAD_SUPPORT + s.d->mutex->lock(); +#endif // QT_THREAD_SUPPORT s.d->ref(); +#ifdef QT_THREAD_SUPPORT + s.d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT deref(); d = s.d; + return *this; } @@ -1730,6 +1886,10 @@ void TQString::truncate( uint newLen ) */ void TQString::setLength( uint newLen ) { +#ifdef QT_THREAD_SUPPORT + d->mutex->lock(); +#endif // QT_THREAD_SUPPORT + if ( d->count != 1 || newLen > d->maxl || ( newLen * 4 < d->maxl && d->maxl > 4 ) ) { // detach, grow or shrink @@ -1739,12 +1899,24 @@ void TQString::setLength( uint newLen ) uint len = TQMIN( d->len, newLen ); memcpy( nd, d->unicode, sizeof(TQChar) * len ); bool unpaged = d->security_unpaged; +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT deref(); d = new TQStringData( nd, newLen, newMax ); setSecurityUnPaged(unpaged); } - } else { + else { +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT + } + } + else { d->len = newLen; +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT d->setDirty(); } } @@ -1830,10 +2002,21 @@ void TQString::squeeze() */ void TQString::grow( uint newLen ) { +#ifdef QT_THREAD_SUPPORT + d->mutex->lock(); +#endif // QT_THREAD_SUPPORT + if ( d->count != 1 || newLen > d->maxl ) { +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT setLength( newLen ); - } else { + } + else { d->len = newLen; +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT d->setDirty(); } } @@ -5868,13 +6051,15 @@ static TQChar *addOne(TQChar *qch, TQString &str) */ TQString TQString::fromUtf8( const char* utf8, int len ) { - if ( !utf8 ) + if ( !utf8 ) { return TQString::null; + } int slen = 0; if (len >= 0) { - while (slen < len && utf8[slen]) + while (slen < len && utf8[slen]) { slen++; + } } else { slen = int(strlen(utf8)); } @@ -6012,10 +6197,13 @@ TQString TQString::fromLatin1( const char* chars, int len ) { uint l; TQChar *uc; - if ( len < 0 ) + if ( len < 0 ) { len = -1; + } uc = internalLatin1ToUnicode( chars, &l, len ); - return TQString( new TQStringData(uc, l, l), TRUE ); + TQString ret( new TQStringData(uc, l, l), TRUE ); + + return ret; } /*! @@ -6178,7 +6366,8 @@ TQString TQString::fromUcs2( const unsigned short *str ) length++; TQChar* uc = QT_ALLOC_QCHAR_VEC( length ); memcpy( uc, str, length*sizeof(TQChar) ); - return TQString( new TQStringData( uc, length, length ), TRUE ); + TQString ret( new TQStringData( uc, length, length ), TRUE ); + return ret; } } @@ -6225,6 +6414,25 @@ TQString TQString::fromUcs2( const unsigned short *str ) \sa constref() */ +TQChar& TQString::ref(uint i) { +#ifdef QT_THREAD_SUPPORT + d->mutex->lock(); +#endif // QT_THREAD_SUPPORT + if ( (d->count != 1) || (i >= d->len) ) { +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT + subat( i ); + } + else { +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT + } + d->setDirty(); + return d->unicode[i]; +} + /*! \fn TQChar TQString::operator[]( int ) const @@ -6300,27 +6508,48 @@ void TQString::subat( uint i ) TQString& TQString::setUnicode( const TQChar *unicode, uint len ) { - if ( len == 0 ) { // set to null string - if ( d != shared_null ) { // beware of nullstring being set to nullstring - deref(); - d = shared_null ? shared_null : makeSharedNull(); - d->ref(); + if ( len == 0 ) { // set to null string + if ( d != shared_null ) { // beware of nullstring being set to nullstring + deref(); + d = shared_null ? shared_null : makeSharedNull(); +#ifdef QT_THREAD_SUPPORT + d->mutex->lock(); +#endif // QT_THREAD_SUPPORT + d->ref(); +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT + } } - } else if ( d->count != 1 || len > d->maxl || - ( len * 4 < d->maxl && d->maxl > 4 ) ) { - // detach, grown or shrink - uint newMax = computeNewMax( len ); - TQChar* nd = QT_ALLOC_QCHAR_VEC( newMax ); - if ( unicode ) - memcpy( nd, unicode, sizeof(TQChar)*len ); - deref(); - d = new TQStringData( nd, len, newMax ); - } else { - d->len = len; - d->setDirty(); - if ( unicode ) - memcpy( d->unicode, unicode, sizeof(TQChar)*len ); - } + else { +#ifdef QT_THREAD_SUPPORT + d->mutex->lock(); +#endif // QT_THREAD_SUPPORT + if ( d->count != 1 || len > d->maxl || ( len * 4 < d->maxl && d->maxl > 4 ) ) { + // detach, grown or shrink + uint newMax = computeNewMax( len ); + TQChar* nd = QT_ALLOC_QCHAR_VEC( newMax ); + if ( unicode ) { + memcpy( nd, unicode, sizeof(TQChar)*len ); + } +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT + deref(); + d = new TQStringData( nd, len, newMax ); + } + else { + d->len = len; +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT + d->setDirty(); + if ( unicode ) { + memcpy( d->unicode, unicode, sizeof(TQChar)*len ); + } + } + } + return *this; } @@ -7024,15 +7253,23 @@ TQConstString::TQConstString( const TQChar* unicode, uint length ) : */ TQConstString::~TQConstString() { +#ifdef QT_THREAD_SUPPORT + d->mutex->lock(); +#endif // QT_THREAD_SUPPORT + if ( d->count > 1 ) { TQChar* cp = QT_ALLOC_QCHAR_VEC( d->len ); memcpy( cp, d->unicode, d->len*sizeof(TQChar) ); d->unicode = cp; - } else { + } + else { d->unicode = 0; } // The original d->unicode is now unlinked. +#ifdef QT_THREAD_SUPPORT + d->mutex->unlock(); +#endif // QT_THREAD_SUPPORT } /*! diff --git a/src/tools/qthreadinstance_p.h b/src/tools/qthreadinstance_p.h index 98ef3d95b..4d5bff993 100644 --- a/src/tools/qthreadinstance_p.h +++ b/src/tools/qthreadinstance_p.h @@ -101,6 +101,7 @@ public: #endif // Q_OS_WIN32 TQEventLoop* eventLoop; + int cleanupType; }; #endif // QT_THREAD_SUPPORT |