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

List:       kde-multimedia
Subject:    Collected aRts patches
From:       Stefan Westerfeld <stefan () space ! twc ! de>
Date:       2000-08-26 20:02:53
[Download RAW message or body]

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 *-         

["20000826-buffer-better-readerror-checks.diff" (text/plain)]

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<mcopbyte
 	long i,seqlen = readLong();
 
 	result.clear();
+	if(remaining() >= seqlen)
+	{
 	for(i=0;i<seqlen;i++) result.push_back(readByte());
+	}
+	else
+	{
+		d->_readError = true;
+	}
 }
 
 long Buffer::readLong()
@@ -219,7 +226,14 @@ void Buffer::readLongSeq(vector<long>& r
 	long i,seqlen = readLong();
 
 	result.clear();
+	if(remaining() >= seqlen * 4)
+	{
 	for(i=0;i<seqlen;i++) result.push_back(readLong());
+	}
+	else
+	{
+		d->_readError = true;
+	}
 }
 
 float Buffer::readFloat()
@@ -237,7 +251,14 @@ void Buffer::readFloatSeq(vector<float>&
 	long i,seqlen = readLong();
 
 	result.clear();
+	if(remaining() >= seqlen * 4)
+	{
 	for(i=0;i<seqlen;i++) result.push_back(readFloat());
+	}
+	else
+	{
+		d->_readError = true;
+	}
 }
 
 void Buffer::readString(string& result)
@@ -264,6 +285,8 @@ void Buffer::readStringSeq(vector<string
 		string s;
 
 		readString(s);
+		if(d->_readError) return;
+
 		result.push_back(s);
 	}
 }

["20000826-iomanager-delete-while-in-event.diff" (text/plain)]

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(&currenttime,0);
 
 		list<TimeWatcher *>::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(&currenttime,0);
 
 		list<TimeWatcher *>::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 {

["20000826-retries-for-desuspend.diff" (text/plain)]

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)
 		{

["20000826-terminate-artsd-without-soundcard.diff" (text/plain)]

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();
 

_______________________________________________
Kde-multimedia mailing list
Kde-multimedia@master.kde.org
http://master.kde.org/mailman/listinfo/kde-multimedia


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

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