Bug 127294 - hangs linux usb detection and keeps cpu at 100% when unplugging a usb audio device
Summary: hangs linux usb detection and keeps cpu at 100% when unplugging a usb audio d...
Status: CLOSED FIXED
Alias: None
Product: kmix
Classification: Applications
Component: general (show other bugs)
Version: unspecified
Platform: unspecified Linux
: NOR normal
Target Milestone: ---
Assignee: Christian Esken
URL:
Keywords:
: 131505 131903 133800 138820 141050 141995 (view as bug list)
Depends on:
Blocks:
 
Reported: 2006-05-14 10:17 UTC by Pierre Habouzit
Modified: 2007-04-28 12:04 UTC (History)
6 users (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Pierre Habouzit 2006-05-14 10:17:21 UTC
Version:            (using KDE KDE 3.5.2)

from debian http://bugs.debian.org/367156
=========================================

Unplugging a usb audio device (in this case a usb headset), has kmix
at 100% cpu usage. At the same time, it prevents linux from detecting 
replugging of the device. killing kmix fixes it. The problem only
appears if kmix was run after the usb device was detected and configured
by alsa and appeared on kmix's card list.
Comment 1 Christian Esken 2006-05-19 10:29:35 UTC
Could you please try the same with the alsamixer applications ?
I need to know whether this KMix specific or an alsalib issue.
Comment 2 Pierre Habouzit 2006-05-19 10:36:58 UTC
submitter was <michael AT www0 DOT org>

I've forwarded the question to him, but I guess that would be more efficient to ask the questions directly to him.
Comment 3 Pierre Habouzit 2006-05-19 12:25:21 UTC
his answer (it seems that 127294@bugs.kde.org didn't worked as expected) :

> Could you please try the same with the alsamixer applications ? 
> I need to know whether this KMix specific or an alsalib issue. 

If alsamixer is run with -c <card number> for the usb headset and then
the device is unplugged, alsamixer closes with:

alsamixer: function snd_mixer_poll_descriptors (POLLNVAL) failed: Success
Comment 4 Ernesto Ruge 2006-07-20 17:19:08 UTC
Same problem here with an Audigy 2 NX (USB) - alsamixer just quit with this errormessage, KMix still uses 100% CPU ...
Comment 5 Christian Esken 2006-07-29 12:27:23 UTC
*** Bug 131505 has been marked as a duplicate of this bug. ***
Comment 6 Christian Esken 2006-07-29 12:40:59 UTC
This can only be fixed if I would have an USB sound device. As long as I don't I cannot fix it. Probably somebody else who owns a USB sound device could fix this issue. Alternatively I can try to fix this, but I would need a volunteer who will compile KDE 3.5 branch every time when I have tried to fix it and report back short-term on the results.

I have an idea how to fix it in Mixer_ALSA::prepareUpdateFromHW() , namely checking for "revents & POLLNVAL", and removing all Socket Notifiers m_sns[i] . The soundcard would still be shown, but it might be possible that you then can't re-plug that soundcard. For that it also it might be neccesary to deactivate the card, closing the mixer device, and so on.
Comment 7 GML 2006-08-04 12:59:26 UTC
Where do you live Christian ? Maybe that somebody from KDE community with USB sound device lives next to you ? Or somebody of LUG could lend a USB sound device ?

At worst, I can compile your patch on my computer, but I need to know the process to success this.
Comment 8 Christian Esken 2006-08-07 22:40:31 UTC
*** Bug 131903 has been marked as a duplicate of this bug. ***
Comment 9 Christian Esken 2006-08-07 22:47:18 UTC
GML, I'll probably find somebody at aKademy 2006 in Dublin. If not, I'll come back to your offer.
Comment 10 GML 2006-08-08 12:04:47 UTC
Christian, could you post a message about this on kde-devel list or on your blog if it in http://www.planetkde.org/ ? This is could help to find somebody with USB device on aKademy.
Comment 11 GML 2006-08-08 12:05:13 UTC
Christian, could you post a message about this on kde-devel list or on your blog if it in http://www.planetkde.org/ ? This is could help to find somebody with USB device on aKademy.
Comment 12 GML 2006-08-08 12:05:54 UTC
I'm sorry for the double post.
Comment 13 Christian Esken 2006-09-19 02:13:54 UTC
*** Bug 133800 has been marked as a duplicate of this bug. ***
Comment 14 Mihail Tomoff 2006-09-30 10:10:31 UTC
Just to add that on SUSE 10.1 64 bit with latest kde's rpms (3.5.4) from the repository, I have the same problem with the usb webcam's mic.
And I've also noticed that even if kmix is started before the plugging of the usb device, after a time it recognizes the new audio device and then the unplugging again leads to the high cpu usage problem. The unplugging does not lead to this problem only if kmix has not recognized the usb device yet.
I tried with other mixers - no problem when I unplug the usb webcam.
Comment 15 Robert Dyck 2006-12-09 00:46:21 UTC
KDE 3.5.5 also. Logitech Quickcam Communicate STX. USB handset OK but it does not have an internal mixer.
Comment 16 Ronny Standtke 2006-12-09 23:53:43 UTC
I just want to add that I have the same problem with KMix 2.6 (KDE-3.5.5) and a Logitech USB Headset.
Comment 17 Christian Esken 2006-12-22 18:08:50 UTC
*** Bug 138820 has been marked as a duplicate of this bug. ***
Comment 18 Christian Esken 2006-12-22 18:17:49 UTC
I got an USB soundstick yesterday and fixed the issue.
The unplugged USB soundcard will still be seen in the KMix GUI, but there is no way around this for Kix in KDE3.x.
KMix will also not any longer prevent replugging your USB sundcard. If you want to be able to control the replugged card, you need to restart KMix (there is and will be no hotplugging for Kix in KDE3.x).
Comment 19 Christian Esken 2006-12-22 20:28:32 UTC
I applied the change to the KDE3 branch. If somebody has a KDE3 checkout, please update and test. If tests are unsuccselful reopen this bug report.
Some ideas for tests would be:
- test all kinds of plugging/unplugging sequences 
- PanelApplet tests
- GUI Configuration saving and restoring
- Volume saving and restoring
Comment 20 Christian Esken 2006-12-22 20:29:18 UTC
SVN commit 615802 by esken:

Fix for bug 127294: hangs linux usb detection and keeps cpu at 100% when unplugging
a usb audio device
CCBUGS: 127294


 M  +6 -1      kmix.cpp  
 M  +6 -0      mixer.cpp  
 M  +1 -0      mixer.h  
 M  +1 -0      mixer_alsa.h  
 M  +21 -12    mixer_alsa9.cpp  


--- branches/KDE/3.5/kdemultimedia/kmix/kmix.cpp #615801:615802
@@ -273,9 +273,12 @@
    // save mixer widgets
    for ( KMixerWidget *mw = m_mixerWidgets.first(); mw != 0; mw = m_mixerWidgets.next() )
    {
+	if ( mw->mixer()->isOpen() )
+	{ // protect from unplugged devices (better do *not* save them)
 		QString grp;
 		grp.sprintf( "%i", mw->id() );
 		mw->saveConfig( config, grp );
+	}
    }
 
    config->setGroup(0);
@@ -478,7 +481,9 @@
     KConfig *cfg = new KConfig( "kmixctrlrc", false );
     for (Mixer *mixer=Mixer::mixers().first(); mixer!=0; mixer=Mixer::mixers().next()) {
 	//kdDebug(67100) << "KMixWindow::saveConfig()" << endl;
-	mixer->volumeSave( cfg );
+	if ( mixer->isOpen() ) { // protect from unplugged devices (better do *not* save them)
+		mixer->volumeSave( cfg );
+	}
     }
     delete cfg;
 }
--- branches/KDE/3.5/kdemultimedia/kmix/mixer.cpp #615801:615802
@@ -248,6 +248,12 @@
   return _mixerBackend->isValid();
 }
 
+bool Mixer::isOpen() const {
+    if ( _mixerBackend == 0 )
+        return false;
+    else
+        return _mixerBackend->isOpen();
+}
 
 /* ------- WRAPPER METHODS. END -------------------------------- */
 
--- branches/KDE/3.5/kdemultimedia/kmix/mixer.h #615801:615802
@@ -63,6 +63,7 @@
       unsigned int size() const;
       
       bool isValid();
+      bool isOpen() const;
       
       /// Returns a pointer to the mix device with the given number
       MixDevice* operator[](int val_i_num);
--- branches/KDE/3.5/kdemultimedia/kmix/mixer_alsa.h #615801:615802
@@ -33,6 +33,7 @@
 	private:
 		int identify( snd_mixer_selem_id_t *sid );
 		snd_mixer_elem_t* getMixerElem(int devnum);
+		void removeSignalling();
 
 		virtual QString errorText(int mixer_error);
 		typedef QValueList<snd_mixer_selem_id_t *>AlsaMixerSidList;
--- branches/KDE/3.5/kdemultimedia/kmix/mixer_alsa9.cpp #615801:615802
@@ -423,7 +423,21 @@
     }
 }
 
+void Mixer_ALSA::removeSignalling()
+{
+  if ( m_fds )
+      free( m_fds );
+  m_fds = 0;
 
+  if ( m_sns )
+  {
+      for ( int i = 0; i < m_count; i++ )
+          delete m_sns[i];
+      delete [] m_sns;
+      m_sns = 0;
+  }
+}
+
 int
 Mixer_ALSA::close()
 {
@@ -453,24 +467,16 @@
   mixer_sid_list.clear();
   m_mixDevices.clear();
 
-  if ( m_fds )
-      free( m_fds );
-  m_fds = 0;
+  removeSignalling();
 
-  if ( m_sns )
-  {
-      for ( int i = 0; i < m_count; i++ )
-          delete m_sns[i];
-      delete [] m_sns;
-      m_sns = 0;
-  }
-
   return ret;
 }
 
 
 snd_mixer_elem_t* Mixer_ALSA::getMixerElem(int devnum) {
 	snd_mixer_elem_t* elem = 0;
+	if ( ! m_isOpen ) return elem; // unplugging guard
+
 	if ( int( mixer_sid_list.count() ) > devnum ) {
 		snd_mixer_selem_id_t * sid = mixer_sid_list[ devnum ];
 		// The next line (hopefully) only finds selem's, not elem's.
@@ -496,7 +502,7 @@
 
 bool Mixer_ALSA::prepareUpdateFromHW()
 {
-    if ( !m_fds )
+    if ( !m_fds || !m_isOpen )
 	return false;
 
     //kdDebug(67100) << "Mixer_ALSA::prepareUpdate() 1\n";
@@ -518,7 +524,10 @@
             //kdDebug(67100) << "Mixer_ALSA::prepareUpdate() 6\n";
 
 	    if (revents & POLLNVAL) {
+		/* Bug 127294 shows, that we receieve POLLNVAL when the user
+		 unplugs an USB soundcard. Lets close the card. */
 		kdDebug(67100) << "Mixer_ALSA::poll() , Error: poll() returns POLLNVAL\n";
+		close();  // Card was unplugged (unplug, driver unloaded)
 		return false;
 	    }
 	    if (revents & POLLERR) {
Comment 21 Christian Esken 2006-12-22 20:30:21 UTC
*** Bug has been marked as fixed ***.
Comment 22 Christian Esken 2006-12-22 21:33:44 UTC
SVN commit 615814 by esken:

Forward port of bugfix for bug 127294 to KDE4.
CCBUGS: 127294


 M  +8 -3      kmix.cpp  
 M  +0 -15     mixdevice.cpp  
 M  +1 -6      mixdevice.h  
 M  +6 -0      mixer.cpp  
 M  +3 -0      mixer.h  
 M  +1 -0      mixer_alsa.h  
 M  +21 -12    mixer_alsa9.cpp  


--- trunk/KDE/kdemultimedia/kmix/kmix.cpp #615813:615814
@@ -217,8 +217,11 @@
       QWidget *w = m_wsMixers->widget(i);
       if ( w->inherits("KMixerWidget") ) {
          KMixerWidget* mw = (KMixerWidget*)w;
-         QString grp (mw->id());
-         mw->saveConfig( config, grp );
+         if ( mw->mixer()->isOpen() )
+         { // protect from unplugged devices (better do *not* save them)
+             QString grp (mw->id());
+             mw->saveConfig( config, grp );
+         }
       }
    }
 }
@@ -234,7 +237,9 @@
    for ( int i=0; i<Mixer::mixers().count(); ++i)
    {
       Mixer *mixer = (Mixer::mixers())[i];
-      mixer->volumeSave( cfg );
+      if ( mixer->isOpen() ) { // protect from unplugged devices (better do *not* save them)
+          mixer->volumeSave( cfg );
+      }
    }
    delete cfg;
 }
--- trunk/KDE/kdemultimedia/kmix/mixdevice.cpp #615813:615814
@@ -77,22 +77,7 @@
     return _captureVolume;
 }
 
-/*
-long MixDevice::getVolume(Volume::ChannelID chid) {
-   return _volume.getVolume(chid);
-}
 
-long MixDevice::maxVolume() {
-   return _volume.maxVolume();
-}
-
-
-long MixDevice::minVolume() {
-   return _volume.minVolume();
-}
-*/
-
-
 void MixDevice::setEnumId(int enumId)
 {
    if ( enumId < _enumValues.count() ) {
--- trunk/KDE/kdemultimedia/kmix/mixdevice.h #615813:615814
@@ -94,12 +94,7 @@
 
     Volume& playbackVolume();
     Volume& captureVolume();
-/*
-    void setVolume( int channel, int volume );
-    long getVolume(Volume::ChannelID chid);
-    long maxVolume();
-    long minVolume();
-*/
+
     void setEnumId(int);
     unsigned int enumId();
     QList<QString>& enumValues();
--- trunk/KDE/kdemultimedia/kmix/mixer.cpp #615813:615814
@@ -224,6 +224,12 @@
   return driverName;
 }
 
+bool Mixer::isOpen() const {
+    if ( _mixerBackend == 0 )
+        return false;
+    else
+        return _mixerBackend->isOpen();
+}
 
 /* ------- WRAPPER METHODS. END -------------------------------- */
 
--- trunk/KDE/kdemultimedia/kmix/mixer.h #615813:615814
@@ -73,6 +73,9 @@
       /// Open/grab the mixer for further intraction
       bool openIfValid();
 
+      /// Returns wheter the card is open/operational
+      bool isOpen() const;
+
       /// Close/release the mixer
       virtual int close();
 
--- trunk/KDE/kdemultimedia/kmix/mixer_alsa.h #615813:615814
@@ -60,6 +60,7 @@
     void addEnumerated(snd_mixer_elem_t *elem, QList<QString*>&);
     Volume* addVolume(snd_mixer_elem_t *elem, bool capture);
     int setupAlsaPolling();
+    void deinitAlsaPolling();
 
     int identify( snd_mixer_selem_id_t *sid );
     snd_mixer_elem_t* getMixerElem(int devnum);
--- trunk/KDE/kdemultimedia/kmix/mixer_alsa9.cpp #615813:615814
@@ -386,7 +386,21 @@
     }
 }
 
+void Mixer_ALSA::deinitAlsaPolling()
+{
+  if ( m_fds )
+      free( m_fds );
+  m_fds = 0;
 
+  if ( m_sns )
+  {
+      for ( int i = 0; i < m_count; i++ )
+          delete m_sns[i];
+      delete [] m_sns;
+      m_sns = 0;
+  }
+}
+
 int
 Mixer_ALSA::close()
 {
@@ -417,18 +431,8 @@
   m_mixDevices.clear();
   m_id2numHash.clear();
 
-  if ( m_fds )
-      free( m_fds );
-  m_fds = 0;
+  deinitAlsaPolling();
 
-  if ( m_sns )
-  {
-      for ( int i = 0; i < m_count; i++ )
-          delete m_sns[i];
-      delete [] m_sns;
-      m_sns = 0;
-  }
-
   return ret;
 }
 
@@ -439,6 +443,8 @@
  */
 snd_mixer_elem_t* Mixer_ALSA::getMixerElem(int idx) {
 	snd_mixer_elem_t* elem = 0;
+        if ( ! m_isOpen ) return elem; // unplugging guard
+
 	if ( idx == -1 ) {
 		return elem;
 	}
@@ -476,7 +482,7 @@
 }
 
 bool Mixer_ALSA::prepareUpdateFromHW() {
-    if ( !m_fds )
+    if ( !m_fds || !m_isOpen )
         return false;
 
     // Poll on fds with 10ms timeout
@@ -495,7 +501,10 @@
     //kDebug(67100) << "Mixer_ALSA::prepareUpdate() 6\n";
 
 	    if (revents & POLLNVAL) {
+                /* Bug 127294 shows, that we receieve POLLNVAL when the user
+                 unplugs an USB soundcard. Lets close the card. */
 		kDebug(67100) << "Mixer_ALSA::poll() , Error: poll() returns POLLNVAL\n";
+                close();  // Card was unplugged (unplug, driver unloaded)
 		return false;
 	    }
 	    if (revents & POLLERR) {
Comment 23 Christian Esken 2007-02-20 22:58:17 UTC
*** Bug 141995 has been marked as a duplicate of this bug. ***
Comment 24 Christian Esken 2007-02-20 22:59:49 UTC
Remark for further readers: This is fixed in KDE 3.5.6
Comment 25 Uwe Klein 2007-02-21 11:49:00 UTC
hey, thanks for the help.
Why did i not find the other bug reports
while searching the bug-db after it was 
back online again on tuesday?

"kmix 100% cpu" should have found me 
somehthing.
Comment 26 Christian Esken 2007-04-28 12:04:27 UTC
*** Bug 141050 has been marked as a duplicate of this bug. ***