While trying gnash under Fedora 14 alpha I noticed that it didn't work with youtube, even after clearing cookies. So I did some debugging and found at that there is a bad interaction between gnash and the latest libcurl, the attached gnash-0.8.8-new-libcurl.patch fixes this. The problem is that newer libcurl versions (atleast 7.21.x) return -1 for maxfd from curl_multi_fdset while they are doing dns resolving. This gets combined with a short (7ms) return value from curl_multi_timeout indicating that the thread / caller should just sleep a bit and then retry. However we break out of the cache fill loop when maxfd < 1. We always use a short timeout, so things work fine once we remove the maxfd < 0 check. ### While looking into this I also tried using curl_multi_timeout to get the select timeout as the curl documentation says is mandatory, rather then hardcoding 10ms. See: gnash-0.8.8-curl-multi_timeout.patch, but this does not work. After dns resolution curl_multi_timeout returns a timeout of 30 seconds and despite maxfd being 10 now and thus the fd_sets presumably being filled, the select now hangs until the entire 30 seconds are used up. I've tried changing the hardcoded timeout to various values and it seems that for some reason the curl_multi_fdset returned fd_sets seem to be no good, the select call always times out. Regards, Hans diff -up gnash-0.8.8/libbase/curl_adapter.cpp~ gnash-0.8.8/libbase/curl_adapter.cpp --- gnash-0.8.8/libbase/curl_adapter.cpp~ 2010-08-07 17:50:00.000000000+0200 +++ gnash-0.8.8/libbase/curl_adapter.cpp 2010-08-27 10:44:37.665493001+0200 @@ -648,6 +648,11 @@ CurlStreamFile::fillCache(std::streamsiz log_debug("Max fd: %d", maxfd); #endif + /* HDG: newer libcurl versions (atleast 7.21.x) return -1 for maxfd + while they are doing dns resolving in combination with a short + (7ms) return value from curl_multi_timeout. We always use a short + timeout, so things work fine once we remove the maxfd < 0 check. */ +#if 0 // A value of -1 means no file descriptors were added. if (maxfd < 0) { #if GNASH_CURL_VERBOSE @@ -655,6 +660,7 @@ CurlStreamFile::fillCache(std::streamsiz #endif break; } +#endif FD_ZERO(&readfd); FD_ZERO(&writefd); --- gnash-0.8.8/libbase/curl_adapter.cpp 2010-08-27 10:44:37.665493001+0200 +++ gnash-0.8.8.new/libbase/curl_adapter.cpp 2010-08-27 10:44:48.962493001+0200 @@ -607,11 +607,7 @@ int maxfd; CURLMcode mcode; timeval tv; - - // Hard-coded slect timeout. - // This number is kept low to give more thread switch - // opportunities while waiting for a load. - const long maxSleepUsec = 10000; // 1/100 of a second + long multi_timeout_ms; const unsigned int userTimeout = static_cast( RcInitFile::getDefaultInstance().getStreamsTimeout()*1000); @@ -666,11 +662,16 @@ FD_ZERO(&writefd); FD_ZERO(&exceptfd); - tv.tv_sec = 0; - tv.tv_usec = maxSleepUsec; + mcode = curl_multi_timeout(_mhandle, &multi_timeout_ms); + if (mcode != CURLM_OK) { + throw GnashException(curl_multi_strerror(mcode)); + } + + tv.tv_sec = multi_timeout_ms / 1000; + tv.tv_usec = (multi_timeout_ms % 1000) * 1000; #ifdef GNASH_CURL_VERBOSE - log_debug("select() with %d milliseconds timeout", maxSleepUsec*1000); + log_debug("select() with %ld milliseconds timeout", multi_timeout_ms); #endif // Wait for data on the filedescriptors until a timeout set