[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    KDE/kdemultimedia/phonon-xine
From:       Matthias Kretz <kretz () kde ! org>
Date:       2007-06-02 22:46:04
Message-ID: 1180824364.350102.23872.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 670907 by mkretz:

never delete the AudioPortData immediately as xine might still access it, OTOH if \
~XineEngine is called all those AudioPortData objects that are still waiting for \
termination have to be deleted

 M  +15 -3     audioport.cpp  
 M  +1 -1      audioport.h  
 M  +3 -2      audioport_p.h  
 M  +0 -1      audiopostlist.cpp  
 M  +2 -0      xineengine.cpp  
 M  +4 -0      xineengine.h  


--- trunk/KDE/kdemultimedia/phonon-xine/audioport.cpp #670906:670907
@@ -32,9 +32,10 @@
 namespace Xine
 {
 
-AudioPortDeleter::AudioPortDeleter(const AudioPort &port)
-    : m_port(port)
+AudioPortDeleter::AudioPortDeleter(AudioPortData *dd)
+    : d(dd)
 {
+    XineEngine::addCleanupObject(this);
     startTimer(2000);
 }
 
@@ -44,6 +45,11 @@
     deleteLater();
 }
 
+AudioPortDeleter::~AudioPortDeleter()
+{
+    XineEngine::removeCleanupObject(this);
+}
+
 class AudioPortData : public QSharedData
 {
     public:
@@ -76,12 +82,14 @@
 
 AudioPort &AudioPort::operator=(const AudioPort &rhs)
 {
+    waitALittleWithDying(); // xine still accesses the port after a rewire :(
     d = rhs.d;
     return *this;
 }
 
 AudioPort::~AudioPort()
 {
+    waitALittleWithDying(); // xine still accesses the port after a rewire :(
 }
 
 AudioPort::AudioPort(int deviceIndex)
@@ -155,7 +163,11 @@
 
 void AudioPort::waitALittleWithDying()
 {
-    new AudioPortDeleter(*this);
+    if (d->ref == 1) {
+        // this is the last ref to the data, so it will get deleted in a few \
instructions unless +        new AudioPortDeleter(d);
+        // AudioPortDeleter refs it once more
+    }
 }
 
 AudioPort::operator xine_audio_port_t*() const
--- trunk/KDE/kdemultimedia/phonon-xine/audioport.h #670906:670907
@@ -61,7 +61,7 @@
         ~AudioPort();
 
     private:
-        QSharedDataPointer<AudioPortData> d;
+        QExplicitlySharedDataPointer<AudioPortData> d;
 };
 
 } // namespace Xine
--- trunk/KDE/kdemultimedia/phonon-xine/audioport_p.h #670906:670907
@@ -31,13 +31,14 @@
 {
     Q_OBJECT
     public:
-        AudioPortDeleter(const AudioPort &);
+        AudioPortDeleter(AudioPortData *);
+        ~AudioPortDeleter();
 
     protected:
         void timerEvent(QTimerEvent *);
 
     private:
-        AudioPort m_port;
+        QExplicitlySharedDataPointer<AudioPortData> d;
 };
 } // namespace Xine
 } // namespace Phonon
--- trunk/KDE/kdemultimedia/phonon-xine/audiopostlist.cpp #670906:670907
@@ -151,7 +151,6 @@
             err = xine_post_wire_audio_port(audioSource, d->newOutput);
         }
         Q_ASSERT(err == 1);
-        d->output.waitALittleWithDying(); // xine still accesses the port after a \
rewire :(  d->output = d->newOutput;
     } else {
         kDebug(610) << "no valid audio output given, no audio" << endl;
--- trunk/KDE/kdemultimedia/phonon-xine/xineengine.cpp #670906:670907
@@ -90,6 +90,7 @@
 
     XineEngine::~XineEngine()
     {
+        qDeleteAll(m_cleanupObjects);
         //kDebug(610) << k_funcinfo << endl;
         if (m_nullPort) {
             xine_close_audio_driver(m_xine, m_nullPort);
@@ -171,6 +172,7 @@
                         QList<AudioPostList> posts = xs->audioPostLists();
                         foreach (AudioPostList post, posts) {
                             AudioPort ap = post.audioPort();
+                            kDebug(610) << "telling AudioPort " << ap << " valid = " \
<< ap.isValid() << " output = " << ap.audioOutput() << endl;  if (ap.isValid()) {
                                 QCoreApplication::postEvent(ap.audioOutput(), new \
QEvent(static_cast<QEvent::Type>(Xine::AudioDeviceFailedEvent)));  }
--- trunk/KDE/kdemultimedia/phonon-xine/xineengine.h #670906:670907
@@ -97,6 +97,9 @@
 
             static const QObject *sender();
 
+            static void addCleanupObject(QObject *o) { self()->m_cleanupObjects << \
o; } +            static void removeCleanupObject(QObject *o) { \
self()->m_cleanupObjects.removeAll(o); } +
         protected:
             XineEngine(const KSharedConfigPtr &cfg);
             ~XineEngine();
@@ -123,6 +126,7 @@
                 bool operator==(const AudioOutputInfo& rhs) { return name == \
rhs.name && driver == rhs.driver; }  };
             QList<AudioOutputInfo> m_audioOutputInfos;
+            QList<QObject *> m_cleanupObjects;
             KSharedConfigPtr m_config;
             bool m_useOss;
             const XineEnginePrivate *const d;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic