[icecast] Icecast deadlock with 1.3.12 (fixed)
Ned Wolpert
ned.wolpert at knowledgenet.com
Fri Jun 20 23:28:02 UTC 2003
Folks-
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
deadlock.
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:
[%s]",req->host);
if ((sourcecon = relay_pull_stream (req, &err)))
to this:
xa_debug (1, "DEBUG: Trying transparent proxy with host: [%s]",
req->host);
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?
<p><p>
--
Virtually,
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