Version: 1.3-CVS (using KDE 3.3.0, SuSE) Compiler: gcc version 3.3.4 (pre 3.3.5 20040809) OS: Linux (i686) release 2.6.8-24-default turning on any script when using the xine engine causes a pop up saying "Audio output unavailable; the device is busy." and then amaroK can't play any music. Turning the script off fixes that problem.
setting bug to unconfirmed.
I can't reproduce this, and frankly, for the life of me can't think of a technical explanation. Waaaay strange bug :) Can anyone besides the reporter reproduce this?
markey did you use the xine engine when you tried to reproduce this? Hope these instructions are clearer: 1) Enable xine engine but turn start playing any songs 2) Go to scripts and select alarm.py. 3) Click run. 4) Configure the alarm to start a minute from the current time. 5) Hopefully amaroK freezes for about a minute and then gives the "Audio output unavailable; the device is busy." popup.
Can no one reproduce this? It still happens in 1.3 on a separate OS (gentoo now) and separate sound card. Modified steps to reproduce: 1) Enable xine engine. 2) start playing any songs 3) Go to scripts and select alarm.py. 3) Click run. 4) Configure the alarm to start a minute from the current time. 5) After playing the third or fourth song in the playlist the "Audio output unavailable; the device is busy." pops up.
Quoting what Alastair said in a mail forwarded to mail list: "It seems that the script inherits all the open files from the parent amarok process. For me this included /dev/snd/pcmC0D0c, which blocked other sound applications including the Xine engine when it moved to the next track. Once I worked out that this was the cause of sound on my computer being blocked, I modified the script to close all files apart from stdin, stdout and stderr. I think this could bite other people apart from me." So, the problem is that because of the way the scripts are run, they would inherit open files, and then unless the plugins would close the files, we'd have this problem. This would also explain similar problems with visualizations. Now we need to find a way to avoid this. :-(
*** Bug 94119 has been marked as a duplicate of this bug. ***
On Saturday 20 August 2005 03:54, Alexandre Oliveira wrote: > So, the problem is that because of the way the scripts are run, they would > inherit open files, and then unless the plugins would close the files, we'd > have this problem. This would also explain similar problems with > visualizations. Now we need to find a way to avoid this. :-( This seems to be the normal behavior of the fork() system call. From the Solaris fork() man page: The fork() and fork1() functions create a new process. The new process (child process) is an exact copy of the calling process (parent process). The child process inherits the following attributes from the parent process: o real user ID, real group ID, effective user ID, effec- tive group ID o environment o open file descriptors [..]
*** Bug 112630 has been marked as a duplicate of this bug. ***
SVN commit 463706 by aoliveira: Reimplementing KProcess/KprocIO::commSetupDoneC to close all file descriptors (apart from in, out and err). This seems to be the only way to fix the "device is busy" problem with xine, explained on bug #103750. As the child would inherit the fds, files wouldn't be closed, and xine-lib wouldn't work due to that. If anyone can think of a better fix, please point it out! BUG: 103750 M +19 -1 scriptmanager.cpp M +16 -1 socketserver.cpp --- trunk/extragear/multimedia/amarok/src/scriptmanager.cpp #463705:463706 @@ -58,7 +58,25 @@ #include <knewstuff/provider.h> // " + //////////////////////////////////////////////////////////////////////////////// +// class AmaroKProcIO +//////////////////////////////////////////////////////////////////////////////// +/** Due to xine-lib, we have to make KProcIO close all fds, otherwise we get "device is busy" messages + * See bug #103750 for more information. + */ +class AmaroKProcIO : public KProcIO { + public: + virtual int commSetupDoneC() { + for (int i = sysconf(_SC_OPEN_MAX) - 1; i > 2; i--) + if (i!=KProcIO::out[0] && i!=KProcIO::in[0] && i!=KProcIO::err[0]) + close(i); + return KProcIO::commSetupDoneC(); + }; +}; + + +//////////////////////////////////////////////////////////////////////////////// // class AmarokScriptNewStuff //////////////////////////////////////////////////////////////////////////////// @@ -436,7 +454,7 @@ if ( m_scripts[name].process ) return false; const KURL url = m_scripts[name].url; - KProcIO* script = new KProcIO(); + AmaroKProcIO* script = new AmaroKProcIO(); // script->setComm( (KProcess::Communication) ( KProcess::Stdin | KProcess::Stdout | KProcess::Stderr ) ); *script << url.path(); --- trunk/extragear/multimedia/amarok/src/socketserver.cpp #463705:463706 @@ -36,6 +36,21 @@ //TODO decide whether to use 16 bit integers or 32 bit floats as data sent to analyzers //TODO allow visualisations to determine their own data sizes +//////////////////////////////////////////////////////////////////////////////// +// class AmaroKProcess +//////////////////////////////////////////////////////////////////////////////// +/** Due to xine-lib, we have to make KProcess close all fds, otherwise we get "device is busy" messages + * See bug #103750 for more information. + */ +class AmaroKProcess : public KProcess { + public: + virtual int commSetupDoneC() { + for (int i = sysconf(_SC_OPEN_MAX) - 1; i > 2; i--) + if (i!=KProcess::out[0] && i!=KProcess::in[0] && i!=KProcess::err[0]) + close(i); + return KProcess::commSetupDoneC(); + }; +}; /// @class amaroK::SocketServer @@ -296,7 +311,7 @@ { switch( state() ) { case On: - m_proc = new KProcess(); + m_proc = new AmaroKProcess(); *m_proc << KStandardDirs::findExe( m_command ) << Selector::instance()->m_server->path() << text( 0 );