extragear/multimedia/amarok/src

Seb Ruiz me at sebruiz.net
Sun Oct 8 09:55:58 UTC 2006


SVN commit 593566 by seb:

Apply Ovy's atomicstring patches
I've removed building the unit test to avoid increasing build times further
CCMAIL: amarok at kde.org
CCMAIL: ovy at alum.mit.edu



 M  +35 -25    atomicstring.cpp  
 M  +15 -9     atomicstring.h  
 A             atomicstring_unittest.cpp   [License: no copyright]
 M  +4 -4      metabundle.cpp  


--- trunk/extragear/multimedia/amarok/src/atomicstring.cpp #593565:593566
@@ -98,9 +98,12 @@
 
 AtomicString::AtomicString(): m_string( 0 ) { }
 
-AtomicString::AtomicString( const AtomicString &other ): m_string( other.m_string )
+AtomicString::AtomicString( const AtomicString &other )
 {
+    storeMutex.lock();
+    m_string = other.m_string;
     ref( m_string );
+    storeMutex.unlock();
 }
 
 AtomicString::AtomicString( const QString &string ): m_string( 0 )
@@ -108,36 +111,36 @@
     if( string.isEmpty() )
         return;
 
-    Data *s = new Data( string );
+    Data *s = new Data( string );  // note: s is a shallow copy
     storeMutex.lock();
     m_string = static_cast<Data*>( *( s_store.insert( s ).first ) );
+    ref( m_string );
+    uint rc = s->refcount;
+    if( rc ) {
+	// Inserted -- we need to make s a deep copy, as this copy
+	// may be refcounted by the caller thread outside our locks
+	// Hand hold C++ as to which operator= to use
+	(QString &) (*s) = QDeepCopy<QString>(string);
+    }
     storeMutex.unlock();
-    ref( m_string );
-    if( !s->refcount )
-        delete s;
+    if ( !rc ) delete( s );	// already present
 }
 
 AtomicString::~AtomicString()
 {
+    storeMutex.lock();
     deref( m_string );
+    storeMutex.unlock();
 }
 
-QString AtomicString::string() const
-{
-    if( m_string )
-        return *m_string;
-    return QString::null;
-}
-
-const QString *AtomicString::operator->() const
-{
-    return ptr();
-}
-
 QString AtomicString::deepCopy() const
 {
-    if( m_string )
-        return QDeepCopy<QString>( *m_string );
+    if (m_string) {
+	storeMutex.lock();
+	QDeepCopy<QString> copy( *m_string );
+	storeMutex.unlock();
+	return copy;
+    }
     return QString::null;
 }
 
@@ -155,8 +158,12 @@
 
 uint AtomicString::refcount() const
 {
-    if( m_string )
-        return m_string->refcount;
+    if ( m_string ) {
+	storeMutex.lock();
+	uint rc = m_string->refcount;
+	storeMutex.unlock();
+	return rc;
+    } 
     return 0;
 }
 
@@ -164,9 +171,11 @@
 {
     if( m_string == other.m_string )
         return *this;
+    storeMutex.lock();
     deref( m_string );
     m_string = other.m_string;
     ref( m_string );
+    storeMutex.unlock();
     return *this;
 }
 
@@ -175,23 +184,24 @@
     return m_string == other.m_string;
 }
 
-void AtomicString::deref( Data *s )
+// needs to be called holding the lock
+inline void AtomicString::deref( Data *s )
 {
     if( !s )
         return;
     if( !( --s->refcount ) )
     {
-        storeMutex.lock();
         s_store.erase( s );
-        storeMutex.unlock();
         delete s;
     }
 }
 
-void AtomicString::ref( Data *s )
+// needs to be called holding the lock
+inline void AtomicString::ref( Data *s )
 {
     if( s )
         s->refcount++;
 }
 
 AtomicString::set_type AtomicString::s_store;
+QMutex AtomicString::storeMutex;
--- trunk/extragear/multimedia/amarok/src/atomicstring.h #593565:593566
@@ -85,9 +85,11 @@
     bool operator==( const AtomicString &other ) const;
 
     /**
-     * @return the string
+     * Identical to deepCopy() because of QString's thread unsafety
+     * 
+     * @return the string. 
      */
-    QString string() const;
+    inline QString string() const { return deepCopy(); }
 
     /**
      * Implicitly casts to a QString.
@@ -96,12 +98,6 @@
     inline operator QString() const { return string(); }
 
     /**
-     * For convenience, so you can do atomicstring->QStringfunction(),
-     * instead of atomicstring.string().QStringfunction().
-     */
-    const QString *operator->() const;
-
-    /**
      * Useful for threading.
      * @return a deep copy of the string
      */
@@ -126,11 +122,21 @@
      * Guaranteed to be equivalent for equivalent strings, and different for
      * different ones. This can be useful for certain kinds of hacks, but
      * shouldn't normally be used.
+     *
+     * Note: DO NOT COPY this pointer with QString() or QString=. It is not
+     * thread safe to do it (QString internal refcount)
      * @return the internal pointer to the string
      */
     const QString *ptr() const;
 
     /**
+     * For convenience, so you can do atomicstring->QStringfunction(),
+     * instead of atomicstring.string().QStringfunction(). The same warning
+     * applies as for the above ptr() function.
+     */
+    inline const QString *operator->() const { return ptr(); }
+
+    /**
      * For debugging purposes.
      * @return the number of nonempty AtomicStrings equivalent to this one
      */
@@ -160,7 +166,7 @@
 
     Data *m_string;
 
-    QMutex storeMutex;
+    static QMutex storeMutex;
 };
 
 #endif
--- trunk/extragear/multimedia/amarok/src/metabundle.cpp #593565:593566
@@ -176,7 +176,7 @@
         , m_saveFileref( 0 )
         , m_podcastBundle( 0 )
         , m_lastFmBundle( 0 )
-		, m_isSearchDirty(true)
+        , m_isSearchDirty(true)
 {
     init();
 }
@@ -210,7 +210,7 @@
     , m_saveFileref( 0 )
     , m_podcastBundle( 0 )
     , m_lastFmBundle( 0 )
-	, m_isSearchDirty(true)
+    , m_isSearchDirty(true)
 {
     if ( exists() )
     {
@@ -266,7 +266,7 @@
         , m_saveFileref( 0 )
         , m_podcastBundle( 0 )
         , m_lastFmBundle( 0 )
-		, m_isSearchDirty(true)
+	, m_isSearchDirty(true)
 {
     if( title.contains( '-' ) )
     {
@@ -862,7 +862,7 @@
 
         for (int i = 0; i < NUM_COLUMNS; i++) {
             if ((columnMask & (1 << i)) > 0) {
-                if (m_searchStr.isEmpty()) m_searchStr += ' ';
+                if (!m_searchStr.isEmpty()) m_searchStr += ' ';
                 m_searchStr += prettyText(i).lower();
             }
         }



More information about the Amarok mailing list