--X1bOJ3K7DJ5YkBrT Content-Type: text/plain; charset=us-ascii Hi! Here is a collection of patches for aRts. I will commit them tomorrow if there are no objections. * /home/stefan/arts/diffs/20000826-buffer-better-readerror-checks.diff Usually an Arts::Buffer is used in aRts for all marshalling purposes, including passing of object references, .mcoptype files, and ordinary MCOP communication. It provides architecture indepant representations of types. This patch improves the way errors are detected when reading sequences from a buffer. This should provide reasonable termination behaviour even if you try to read a sequence of strings out of a buffer containing some random bytes. The old behaviour would have likely caused the buffer to say: "Oh wow, there are 289318212 strings in here? cool, lets read them all", and never come back. Of course, still expect weird results when trying to do something like that, but at least don't any longer see artsd slowly allocating the memory for all those 289318212 strings. ;-) It also fixes an off-by-one error in readByte (you could read one byte post the end of the buffer). This should fix the old-object-references-lying-around issue recently discussed on kde-core-devel. * /home/stefan/arts/diffs/20000826-iomanager-delete-while-in-event.diff Arts::IOManager handles timers and file I/O in aRts. I found out that when removing a timer from within the timer notification, it crashes. This patch fixes this. * /home/stefan/arts/diffs/20000826-retries-for-desuspend.diff Currently, if artsd suspends, and you start another app which uses /dev/dsp and artsd desuspends while this app is still active, it will fail and never do anything again. This patch adds periodic retries for desuspend in such a situation. It depends on the previos (Arts::IOManager) patch. * /home/stefan/arts/diffs/20000826-terminate-artsd-without-soundcard.diff If you start KDE without a soundcard but leave artsd enabled, it will slowly accumulate memory while not doing anything useful (since it will load the samples, but never play them, and load more samples, ...). This patch simply makes artsd terminate immediately if it detects that it can't open the sound device. This is not quite optimal as you might still want to play videos and stuff like this, but it seems to be the more conservative solution than simply "somehow not working right" without sound device. Cu... Stefan -- -* Stefan Westerfeld, stefan@space.twc.de (PGP!), Hamburg/Germany KDE Developer, project infos at http://space.twc.de/~stefan/kde *- --X1bOJ3K7DJ5YkBrT Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="20000826-buffer-better-readerror-checks.diff" Index: buffer.cc =================================================================== RCS file: /home/kde/kdelibs/arts/mcop/buffer.cc,v retrieving revision 1.16 diff -b -u -p -r1.16 buffer.cc --- buffer.cc 2000/08/23 23:44:48 1.16 +++ buffer.cc 2000/08/26 19:14:36 @@ -178,7 +178,7 @@ bool Buffer::readBool() mcopbyte Buffer::readByte() { - if(remaining() >= 0) + if(remaining() >= 1) { return d->contents[d->rpos++]; } @@ -195,7 +195,14 @@ void Buffer::readByteSeq(vector= seqlen) + { for(i=0;i_readError = true; + } } long Buffer::readLong() @@ -219,7 +226,14 @@ void Buffer::readLongSeq(vector& r long i,seqlen = readLong(); result.clear(); + if(remaining() >= seqlen * 4) + { for(i=0;i_readError = true; + } } float Buffer::readFloat() @@ -237,7 +251,14 @@ void Buffer::readFloatSeq(vector& long i,seqlen = readLong(); result.clear(); + if(remaining() >= seqlen * 4) + { for(i=0;i_readError = true; + } } void Buffer::readString(string& result) @@ -264,6 +285,8 @@ void Buffer::readStringSeq(vector_readError) return; + result.push_back(s); } } --X1bOJ3K7DJ5YkBrT Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="20000826-iomanager-delete-while-in-event.diff" Index: iomanager.cc =================================================================== RCS file: /home/kde/kdelibs/arts/mcop/iomanager.cc,v retrieving revision 1.14 diff -b -u -p -r1.14 iomanager.cc --- iomanager.cc 2000/07/19 11:42:49 1.14 +++ iomanager.cc 2000/08/26 19:15:23 @@ -170,12 +170,12 @@ void StdIOManager::processOneEvent(bool gettimeofday(¤ttime,0); list::iterator ti; - for(ti = timeList.begin(); ti != timeList.end(); ti++) - { - while((*ti)->earlier(currenttime)) - (*ti)->doTick(); - timeval timertime = (*ti)->nextNotify(); + ti = timeList.begin(); + while(ti != timeList.end()) + { + TimeWatcher *w = *ti++; + timeval timertime = w->advance(currenttime); // if that may happen in the next ten seconds if(timertime.tv_sec < currenttime.tv_sec+10) @@ -249,10 +249,12 @@ void StdIOManager::processOneEvent(bool gettimeofday(¤ttime,0); list::iterator ti; - for(ti = timeList.begin(); ti != timeList.end(); ti++) + + ti = timeList.begin(); + while(ti != timeList.end()) { - while((*ti)->earlier(currenttime)) - (*ti)->doTick(); + TimeWatcher *w = *ti++; + w->advance(currenttime); } } @@ -335,40 +337,62 @@ void StdIOManager::removeTimer(TimeNotif if(w->notify() == notify) { - timeList.erase(i); - delete w; - - i = timeList.begin(); + i = timeList.erase(i); + w->destroy(); } else i++; } } TimeWatcher::TimeWatcher(int milliseconds, TimeNotify *notify) + : milliseconds(milliseconds),_notify(notify),active(false),destroyed(false) { - _notify = notify; - this->milliseconds = milliseconds; + gettimeofday(&nextNotify,0); - gettimeofday(&_nextNotify,0); - - _nextNotify.tv_usec += (milliseconds%1000)*1000; - _nextNotify.tv_sec += (milliseconds/1000)+(_nextNotify.tv_usec/1000000); - _nextNotify.tv_usec %= 1000000; + nextNotify.tv_usec += (milliseconds%1000)*1000; + nextNotify.tv_sec += (milliseconds/1000)+(nextNotify.tv_usec/1000000); + nextNotify.tv_usec %= 1000000; } -void TimeWatcher::doTick() +timeval TimeWatcher::advance(const timeval& currentTime) { - _nextNotify.tv_usec += (milliseconds%1000)*1000; - _nextNotify.tv_sec += (milliseconds/1000)+(_nextNotify.tv_usec/1000000); - _nextNotify.tv_usec %= 1000000; + active = true; + while(earlier(currentTime)) + { + nextNotify.tv_usec += (milliseconds%1000)*1000; + nextNotify.tv_sec += (milliseconds/1000)+(nextNotify.tv_usec/1000000); + nextNotify.tv_usec %= 1000000; _notify->notifyTime(); + + if(destroyed) + { + delete this; + + struct timeval never = { 0xffffffff, 0 }; + return never; + } + } + active = false; + return nextNotify; } -bool TimeWatcher::earlier(struct timeval reference) +bool TimeWatcher::earlier(const timeval& reference) { - if(_nextNotify.tv_sec > reference.tv_sec) return false; - if(_nextNotify.tv_sec < reference.tv_sec) return true; + if(nextNotify.tv_sec > reference.tv_sec) return false; + if(nextNotify.tv_sec < reference.tv_sec) return true; - return (_nextNotify.tv_usec < reference.tv_usec); + return (nextNotify.tv_usec < reference.tv_usec); +} + +void TimeWatcher::destroy() +{ + if(active) + { + destroyed = true; + } + else + { + delete this; + } } Index: iomanager.h =================================================================== RCS file: /home/kde/kdelibs/arts/mcop/iomanager.h,v retrieving revision 1.10 diff -b -u -p -r1.10 iomanager.h --- iomanager.h 2000/05/17 22:48:20 1.10 +++ iomanager.h 2000/08/26 19:15:23 @@ -95,14 +95,16 @@ public: class TimeWatcher { int milliseconds; TimeNotify *_notify; - struct timeval _nextNotify; + timeval nextNotify; + bool active, destroyed; + bool earlier(const timeval& reference); public: TimeWatcher(int milliseconds, TimeNotify *notify); - inline struct timeval nextNotify() { return _nextNotify; } + inline TimeNotify *notify() { return _notify; }; - bool earlier(struct timeval reference); - void doTick(); + timeval advance(const timeval& currentTime); + void destroy(); }; class IOManager { --X1bOJ3K7DJ5YkBrT Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="20000826-retries-for-desuspend.diff" Index: flow/synth_play_impl.cc =================================================================== RCS file: /home/kde/kdelibs/arts/flow/synth_play_impl.cc,v retrieving revision 1.18 diff -b -u -p -r1.18 synth_play_impl.cc --- flow/synth_play_impl.cc 2000/07/17 13:56:59 1.18 +++ flow/synth_play_impl.cc 2000/08/26 19:20:55 @@ -38,7 +38,8 @@ using namespace Arts; class Synth_PLAY_impl : virtual public Synth_PLAY_skel, virtual public ASProducer, virtual public StdSynthModule, - virtual public IONotify + virtual public IONotify, + virtual public TimeNotify { protected: AudioSubSystem *as; @@ -66,6 +67,7 @@ protected: unsigned long maxsamples; unsigned long channels; + bool retryOpen; public: /* * functions from the SynthModule interface (which is inherited by @@ -77,6 +79,7 @@ public: channels = as->channels(); maxsamples = 0; outblock = 0; + retryOpen = false; inProgress = false; haveSubSys = as->attachProducer(this); @@ -89,9 +92,31 @@ public: audiofd = as->open(); if(audiofd < 0) { + if(Dispatcher::the()->flowSystem()->suspended()) + { + cerr << "[artsd] /dev/dsp currently unavailable (retrying)\n"; + Dispatcher::the()->ioManager()->addTimer(1000, this); + retryOpen = true; + } + else + { printf("Synth_PLAY: audio subsystem init failed\n"); printf("ASError = %s\n",as->error()); - return; + } + } + } + + void notifyTime() { + assert(retryOpen); + + audiofd = as->open(); + + if(audiofd >= 0) + { + streamStart(); + cerr << "[artsd] ok" << endl; + Dispatcher::the()->ioManager()->removeTimer(this); + retryOpen = false; } } @@ -108,6 +133,9 @@ public: } void streamEnd() { + if(retryOpen) + Dispatcher::the()->ioManager()->removeTimer(this); + artsdebug("Synth_PLAY: closing audio fd\n"); if(audiofd >= 0) { --X1bOJ3K7DJ5YkBrT Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="20000826-terminate-artsd-without-soundcard.diff" Index: soundserver/artsd.cc =================================================================== RCS file: /home/kde/kdelibs/arts/soundserver/artsd.cc,v retrieving revision 1.19 diff -b -u -p -r1.19 artsd.cc --- soundserver/artsd.cc 2000/08/11 03:19:54 1.19 +++ soundserver/artsd.cc 2000/08/26 19:19:50 @@ -166,6 +166,12 @@ int main(int argc, char **argv) if(cfgFragmentSize) AudioSubSystem::the()->fragmentSize(cfgFragmentSize); if(cfgFullDuplex) AudioSubSystem::the()->fullDuplex(cfgFullDuplex); + if(!AudioSubSystem::the()->check()) + { + cerr << "Can't open sound device -> exit" << endl; + exit(1); + } + /* start sound server implementation */ SimpleSoundServer server; AudioManager audioManager; Index: flow/audiosubsys.cc =================================================================== RCS file: /home/kde/kdelibs/arts/flow/audiosubsys.cc,v retrieving revision 1.20 diff -b -u -p -r1.20 audiosubsys.cc --- flow/audiosubsys.cc 2000/07/15 22:49:21 1.20 +++ flow/audiosubsys.cc 2000/08/26 19:19:52 @@ -175,6 +175,15 @@ bool AudioSubSystem::fullDuplex() } +bool AudioSubSystem::check() +{ + if(open() < 0) + return false; + + close(); + return true; +} + int AudioSubSystem::open() { #ifdef HAVE_SYS_SOUNDCARD_H Index: flow/audiosubsys.h =================================================================== RCS file: /home/kde/kdelibs/arts/flow/audiosubsys.h,v retrieving revision 1.9 diff -b -u -p -r1.9 audiosubsys.h --- flow/audiosubsys.h 2000/07/12 11:59:46 1.9 +++ flow/audiosubsys.h 2000/08/26 19:19:52 @@ -117,6 +117,8 @@ public: void fullDuplex(bool newFullDuplex); bool fullDuplex(); + bool check(); + int open(); const char *error(); --X1bOJ3K7DJ5YkBrT-- _______________________________________________ Kde-multimedia mailing list Kde-multimedia@master.kde.org http://master.kde.org/mailman/listinfo/kde-multimedia