[icecast] Icecast deadlock with 1.3.12 (fixed)

Ned Wolpert ned.wolpert at knowledgenet.com
Fri Jun 20 23:28:02 UTC 2003


   First, let me submit a disclaimer... I know 1.3.12 is unsupported.
However, since icecast2 isn't officially released, I'm abit SOL anyways,
so I'm currently trying to debug it and will release a patch when I'm
done.  (Which I'm doing since the code is GPL and I want to 
contribute... if no one cares, let me know and I'll stop updating the 
list with what i find)

   As some on the list knows, Alex Stansfield found a deadlock condition
(see http://www.xiph.org/archives/icecast/1300.html) back in Sept of
2001 which is found when using the transparent proxy feature.  I'm
hitting that today and I'm working on finding the solution to the 

   The first issue I saw is that the function find_mount_with_req() is 
unlocking mutexes out of order.  Now this may not matter since its 
during the unlocking phase, but I figure I'd mention it.

   Second, there seems to be a looping issue with mutexes being locked 
multiple times with the same thread; which is where the problem may be;
In find_mount_with_req() (which must be called with mutex's locked) if 
the transparent proxy is set, it calls relay_pull_stream(), (line 687) 
which eventually calls source_login which relocks info.source_mutex. 
(This was Alex's find)  At this point, that thread is locked up, and 
eventually the second connection handler thread tries to lock it, and 
the calendar thread too.  The original server is unable to send data so 
it kicks the relay and the server is hosed.

   The potential fix for this is cleaning up the mutex during the 
transparent_proxy configuration (source.c:681) so it behaves like
like the 'alias' one a few lines up.  (So a change to the code went from 
this (line 684):
   xa_debug (1, "DEBUG: Trying transparent proxy with host: 
   if ((sourcecon = relay_pull_stream (req, &err)))

to this:
   xa_debug (1, "DEBUG: Trying transparent proxy with host: [%s]", 
   thread_mutex_unlock (&info.mount_mutex);
   thread_mutex_unlock (&info.source_mutex);
   thread_mutex_unlock (&info.double_mutex);
   sourcecon = relay_pull_stream (req, &err);
   thread_mutex_lock (&info.double_mutex);
   thread_mutex_lock (&info.mount_mutex);
   thread_mutex_lock (&info.source_mutex);
   if (sourcecon)

Simple enough... yes?  But is it correct.  It seems to work in my test 
cases.  If anyone still follows 1.3.12, please add your input.
Finally, the third thing was on line 497, locking &source->mutex.  I'm 
having trouble following the logic flow since it seems that the mutex 
always gets locked through the source_func() function but never 
unlocked.  (Least not in the flows that I've followed)  Any enlightenment?


Ned Wolpert <ned.wolpert at knowledgenet.com>

D08C2F45:  28E7 56CB 58AC C622 5A51  3C42 8B2B 2739 D08C 2F45

      "An idea is something you have; an ideology is
       something that has you."          --Morris Berman

<p>--- >8 ----
List archives:  http://www.xiph.org/archives/
icecast project homepage: http://www.icecast.org/
To unsubscribe from this list, send a message to 'icecast-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.

More information about the Icecast mailing list