Mozilla has been working hard to improve Firefox on Android. The following is a guest post from Steve Workman of Mozilla’s networking team which describes an effort to improve DNS performance. – Josh
It started with some crashes on Android that were due to
getaddrinfo being called from multiple threads. The problem was that the version of
getaddrinfo supplied by Bionic (Android’s minimal-but-fast libc implementation) in pre-Honeycomb Android isn’t thread-safe. This is because
fclose etc. aren’t thread-safe. Multiple accesses were being made to a file pointer when reading the local hosts file, resulting in crashes.
Why were we calling
getaddrinfo on multiple threads? Calls to
getaddrinfo can block until a response is received from a DNS server. This can take a while, especially if there is a problem and we wait for the timeout. Making parallel
getaddrinfo calls allows us to cut down on waiting and get more done at once. Sockets can be opened sooner, HTTP requests can be sent sooner, and ultimately your content can be received and displayed sooner. Not being able to make parallel calls to
getaddrinfo would be a serious performance regression, especially on mobile where round trip times are generally longer.
First we needed a quick fix for the crash – a performance regression is better than a crash regression. We temporarily serialized calls to
getaddrinfo and prefetching (predictive DNS resolution) was disabled.
After that, we decided to provide our own thread-safe version of
getaddrinfo, bypassing Bionic’s. Our implementation would have
mmap‘d access to the local hosts file, using
close directly, thus providing a thread-safe function. However, since we were dealing with a library-exposed function, it meant calls to functions and use of structures which were not exposed; at least not officially. After a few failed attempts in which we were trying to get away with dependencies on some unofficially exposed symbols, we finally pulled in a pretty complete version of the host resolver from Gingerbread. This added to our library size a bit, but it allowed for parallel calls to
getaddrinfo on Android again. Given the potential for such calls to block for the duration of a DNS request, we believe this is a good tradeoff.
This change is currently scheduled to ship in Firefox 11.