[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: branches/KDE/4.2/kdepim/kalarm [POSSIBLY UNSAFE]
From: David Jarvie <software () astrojar ! org ! uk>
Date: 2009-06-14 17:23:24
Message-ID: 1245000204.746419.13726.nullmailer () svn ! kde ! org
[Download RAW message or body]
SVN commit 981996 by djarvie:
Bug 194745: fix crash crash when more than one alarm with audio is displayed
simultaneously, e.g. when alarms are redisplayed at startup.
M +3 -2 Changelog
M +51 -19 messagewin.cpp [POSSIBLY UNSAFE: system]
M +6 -2 messagewin.h
--- branches/KDE/4.2/kdepim/kalarm/Changelog #981995:981996
@@ -1,10 +1,11 @@
KAlarm Change Log
-=== Version 2.1.9 --- 10 June 2009 ===
+=== Version 2.1.9 --- 14 June 2009 ===
- Fix email alarms sending multiple mails, when sent via KMail.
- Fix crash when closing remote calendars.
+- Fix crash when more than one alarm with audio is displayed simultaneously.
-=== Version 2.1.8 --- 25 May 2009 ===
+=== Version 2.1.8 (KDE 4.2.4) --- 25 May 2009 ===
- Fix crash on exit from birthday import dialogue.
- Fix crash when an alarm is open for edit when its last occurrence triggers,
and the edit is then saved.
--- branches/KDE/4.2/kdepim/kalarm/messagewin.cpp #981995:981996
@@ -143,6 +143,11 @@
QList<MessageWin*> MessageWin::mWindowList;
QMap<QString, unsigned> MessageWin::mErrorMessages;
+// There can only be one audio thread at a time: trying to play multiple
+// sound files simultaneously would result in a cacophony, and besides
+// that, Phonon currently crashes...
+QPointer<AudioThread> MessageWin::mAudioThread;
+MessageWin* MessageWin::mAudioOwner = 0;
/******************************************************************************
@@ -176,7 +181,6 @@
mConfirmAck(event->confirmAck()),
mNoDefer(true),
mInvalid(false),
- mAudioThread(0),
mEvent(*event),
mResource(AlarmCalendar::resources()->resourceForEvent(mEventID)),
mEditButton(0),
@@ -263,7 +267,6 @@
mShowEdit(false),
mNoDefer(true),
mInvalid(false),
- mAudioThread(0),
mEvent(*event),
mResource(0),
mEditButton(0),
@@ -296,7 +299,6 @@
*/
MessageWin::MessageWin()
: MainWindowBase(0, WFLAGS),
- mAudioThread(0),
mEditButton(0),
mDeferButton(0),
mSilenceButton(0),
@@ -325,7 +327,7 @@
MessageWin::~MessageWin()
{
kDebug() << mEventID;
- if (mAudioThread)
+ if (mAudioOwner == this && mAudioThread)
mAudioThread->quit();
mErrorMessages.remove(mEventID);
mWindowList.removeAll(this);
@@ -1082,15 +1084,7 @@
{
if (!mVolume && mFadeVolume <= 0)
return; // ensure zero volume doesn't play anything
- // An audio file is specified. Because initialising the sound system
- // and loading the file may take some time, call it in a separate
- // thread to allow the window to display first.
- mAudioThread = new AudioThread(this, mAudioFile, mVolume, mFadeVolume, \
mFadeSeconds, mAudioRepeat);
- connect(mAudioThread, SIGNAL(readyToPlay()), SLOT(playReady()));
- connect(mAudioThread, SIGNAL(finished()), SLOT(playFinished()));
- if (mSilenceButton)
- connect(mSilenceButton, SIGNAL(clicked()), mAudioThread, SLOT(quit()));
- mAudioThread->start();
+ startAudio(); // play the audio file
}
else if (mSpeak)
{
@@ -1101,10 +1095,9 @@
}
/******************************************************************************
-* Speak the message.
-* Called asynchronously to avoid delaying the display of the message.
+* Speak the message.
+* Called asynchronously to avoid delaying the display of the message.
*/
-
void MessageWin::slotSpeak()
{
QString error;
@@ -1130,6 +1123,42 @@
}
/******************************************************************************
+* Called when another window's audio thread has been destructed.
+* Start playing this window's audio file. Because initialising the sound system
+* and loading the file may take some time, it is called in a separate thread to
+* allow the window to display first.
+*/
+void MessageWin::startAudio()
+{
+ if (mAudioThread)
+ {
+ // An audio file is already playing for another message
+ // window, so wait until it has finished.
+ connect(mAudioThread, SIGNAL(destroyed(QObject*)), SLOT(audioTerminating()));
+ }
+ else
+ {
+ kDebug() << QThread::currentThread();
+ mAudioThread = new AudioThread(this, mAudioFile, mVolume, mFadeVolume, \
mFadeSeconds, mAudioRepeat); + mAudioOwner = this;
+ connect(mAudioThread, SIGNAL(readyToPlay()), SLOT(playReady()));
+ connect(mAudioThread, SIGNAL(finished()), SLOT(playFinished()));
+ if (mSilenceButton)
+ connect(mSilenceButton, SIGNAL(clicked()), mAudioThread, SLOT(quit()));
+ mAudioThread->start();
+ }
+}
+
+/******************************************************************************
+* Called when another window's audio thread is being destructed.
+* Wait until the destructor has finished.
+*/
+void MessageWin::audioTerminating()
+{
+ QTimer::singleShot(0, this, SLOT(startAudio()));
+}
+
+/******************************************************************************
* Called when the audio file is ready to start playing.
*/
void MessageWin::playReady()
@@ -1152,7 +1181,8 @@
clearErrorMessage(ErrMsg_AudioFile);
}
}
- mAudioThread->quit();
+ delete mAudioThread;
+ mAudioOwner = 0;
}
/******************************************************************************
@@ -1161,6 +1191,7 @@
*/
AudioThread::~AudioThread()
{
+ kDebug();
quit(); // stop playing and tidy up
wait(); // wait for run() to exit
}
@@ -1176,6 +1207,7 @@
mMutex.unlock();
return;
}
+ kDebug() << QThread::currentThread() << mFile;
QString audioFile = mFile;
mFile.replace(QRegExp("^file:/*"), "/");
Phonon::MediaSource source(audioFile);
@@ -1198,8 +1230,8 @@
fader->fadeIn(mFadeSeconds);
mPath.insertEffect(fader);
}
- connect(mAudioObject, SIGNAL(stateChanged(Phonon::State, Phonon::State)), \
SLOT(playStateChanged(Phonon::State)));
- connect(mAudioObject, SIGNAL(finished()), SLOT(checkAudioPlay()));
+ connect(mAudioObject, SIGNAL(stateChanged(Phonon::State, Phonon::State)), \
SLOT(playStateChanged(Phonon::State)), Qt::DirectConnection); + connect(mAudioObject, \
SIGNAL(finished()), SLOT(checkAudioPlay()), Qt::DirectConnection); mPlayedOnce = \
false; mMutex.unlock();
emit readyToPlay();
--- branches/KDE/4.2/kdepim/kalarm/messagewin.h #981995:981996
@@ -25,6 +25,7 @@
#include <QList>
#include <QMap>
+#include <QPointer>
#include "mainwindowbase.h"
#include "alarmevent.h"
@@ -90,6 +91,8 @@
void slotShowKMailMessage();
#endif
void slotSpeak();
+ void audioTerminating();
+ void startAudio();
void playReady();
void playFinished();
void enableButtons();
@@ -113,6 +116,9 @@
static QList<MessageWin*> mWindowList; // list of existing message windows
static QMap<QString, unsigned> mErrorMessages; // error messages currently \
displayed, by event ID + // Sound file playing
+ static QPointer<AudioThread> mAudioThread; // thread to play audio file
+ static MessageWin* mAudioOwner; // window which owns mAudioThread
// Properties needed by readProperties()
QString mMessage;
QFont mFont;
@@ -136,8 +142,6 @@
bool mShowEdit; // display the Edit button
bool mNoDefer; // don't display a Defer option
bool mInvalid; // restored window is invalid
- // Sound file playing
- AudioThread* mAudioThread; // thread to play audio file
// Miscellaneous
KAEvent mEvent; // the whole event, for updating the \
calendar file AlarmResource* mResource; // resource which the event \
comes/came from
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic