Necko: support sending OnDataAvailable() to other threads: Difference between revisions
Line 1: | Line 1: | ||
At the April 2009 Platform work week we had a meeting on making necko support requests from threads other than the main thread. Here's some design notes on what we came up with. | At the April 2009 Platform work week we had a meeting on making necko support requests from threads other than the main thread. Here's some design notes on what we came up with. | ||
== | == Do we actually want to implement this? == | ||
The basic goal here is to allow the off-main-thread HTML 5 parser to get data from the network without having to having to proxy the data to the main thread. The benefits are greater parallelism and reduced interference between the main thread and the parser thread (resulting in better UI responsiveness). | |||
Now that we are moving towards using multiple processes (see [[Content_Processes]]), there is some question of how useful the solution documented here is. In the long run, we are going to be putting the HTML parser in separate processes rather than threads; so this solution is at best a temporary one. But since the API here should be faster to implement than the multi-process one, it might be a useful stopgap implementation for a release or two, until multi-process is ready for prime time. | |||
The | The key question, then, is: just how much performance/responsiveness benefit do we anticipate getting from eliminating proxied network receives, and having the HTML 5 off-thread parser get reads directly? If this is not a significant win, I'd prefer to focus my attention on developing multiprocess networking. | ||
Thoughts on this matter would be appreciated. | |||
== API target: sending OnDataAvailable() to other threads == | == API target: sending OnDataAvailable() to other threads == |
Revision as of 19:15, 6 May 2009
At the April 2009 Platform work week we had a meeting on making necko support requests from threads other than the main thread. Here's some design notes on what we came up with.
Do we actually want to implement this?
The basic goal here is to allow the off-main-thread HTML 5 parser to get data from the network without having to having to proxy the data to the main thread. The benefits are greater parallelism and reduced interference between the main thread and the parser thread (resulting in better UI responsiveness).
Now that we are moving towards using multiple processes (see Content_Processes), there is some question of how useful the solution documented here is. In the long run, we are going to be putting the HTML parser in separate processes rather than threads; so this solution is at best a temporary one. But since the API here should be faster to implement than the multi-process one, it might be a useful stopgap implementation for a release or two, until multi-process is ready for prime time.
The key question, then, is: just how much performance/responsiveness benefit do we anticipate getting from eliminating proxied network receives, and having the HTML 5 off-thread parser get reads directly? If this is not a significant win, I'd prefer to focus my attention on developing multiprocess networking.
Thoughts on this matter would be appreciated.
API target: sending OnDataAvailable() to other threads
In a perfect world, our goal would be an API where any thread could use the full necko interface, and initiate and process network requests completely independently. However, while there's no theoretical reason why necko couldn't be made fully re-entrant, the implementation obstacles involved would be considerable (see notes at end for some details).
Benjamin Smedberg suggested a much more modest goal: that non-main threads be allowed to directly receive the OnDataAvailable() call from the nsIStreamListener interface. All setup of the network channel before this point (and possibly after) would need to be handled on the main thread.
The meeting quickly came to a consensus that something like this would be sufficient for the existing use cases for which a multithreaded necko has been requested: most notably, for an off-main-thread HTML parser to be able to stream in HTML from the network without interfering/delaying the main thread (and vice versa).
There still remain, however, some questions about the exact API:
API Discussion
1) Decision to divert data to other thread should only be made within OnStartRequest().
There seemed to be general agreement that the decision to offload OnDataAvailable() to a different thread should only be possible within OnStartRequest(). By this point, we will have the final channel for the request (i.e. any redirects, auth requests, etc, will have been resolved). We will also have the Content-type of the request, which we will need to determine whether the data should be handled by an off-thread consumer (like the HTML parser) in the first place.
2) How to notify other-thread listener when request is complete?
Two obvious ways come to mind. 1) We could also divert OnStopRequest() to the listener's thread. Or, 2) we could send an additional OnDataAvailable() with data length == 0 to signal the end of the Request. #1 is more intuitive for the programmer; #2 is more conservative, in that the main thread will still receive OnStopRequest. Since compliant nsChannels will need to be modified anyway, no one could think of a good reason not to change them to no longer expect OnStopRequest(), and so #1 is the current winner, pending discovery of any problems with not delivering OnStopReq() to the main thread.
3) Code would need to query both the Channel and any StreamListeners chained between the socket and the target listener, to make sure they are all safe to be switched to a different thread for OnDataAvailable. (We could modify any relevant existing internal listeners to become safe, but since some listeners could come from extensions, we cannot guarantee all listeners will always be safe). Code must be prepared to handle the case where OnDataAvailable cannot be redirected to the desired thread.
Implemention Questions
- cache: no one seems to know exactly what mods might need to be made to the cache to support multiple simultaneous readers.
Notes: Obstacles to a fully-threaded necko API
- A large number of classes would need modification: nsURI, nsChannels, IIOService and the various nsIProtocolHandlers.
- Authorization boxes would need to be popped up from non-main threads
- Many of the necko APIs have been implemented by Javascript extensions, which would suddenly need to be thread-safe