hee hee. threads are fun

This commit is contained in:
pavlov%netscape.com 2001-01-23 02:02:29 +00:00
parent 7c1970ee45
commit 4f8f2165ba
5 changed files with 88 additions and 7 deletions

View File

@ -32,6 +32,12 @@ interface nsIImageLoader;
[scriptable, uuid(ccf705f6-1dd1-11b2-82ef-e18eccf7f7ec)] [scriptable, uuid(ccf705f6-1dd1-11b2-82ef-e18eccf7f7ec)]
interface nsIImageRequest : nsIRequest interface nsIImageRequest : nsIRequest
{ {
// const values for GetStatus() to be used someday...
// const long STATUS_NONE = 0x0;
// const long STATUS_SIZE_AVAILABLE = 0x1;
// const long STATUS_IMAGE_READY = 0x2;
// const long STATUS_ERROR = 0x4;
void init(in nsIChannel aChannel); void init(in nsIChannel aChannel);
/// @return the image object associated with the request. /// @return the image object associated with the request.

View File

@ -29,6 +29,7 @@
#include "nsIChannel.h" #include "nsIChannel.h"
#include "nsIIOService.h" #include "nsIIOService.h"
#include "nsIRunnable.h"
#include "nsIStreamListener.h" #include "nsIStreamListener.h"
#include "nsIURI.h" #include "nsIURI.h"
@ -49,6 +50,16 @@ nsImageLoader::~nsImageLoader()
NS_IMETHODIMP nsImageLoader::LoadImage(nsIURI *aURI, nsIImageRequest **_retval) NS_IMETHODIMP nsImageLoader::LoadImage(nsIURI *aURI, nsIImageRequest **_retval)
{ {
#ifdef IMAGE_THREADPOOL
if (!mThreadPool) {
NS_NewThreadPool(getter_AddRefs(mThreadPool),
1, 4,
512,
PR_PRIORITY_NORMAL,
PR_GLOBAL_THREAD);
}
#endif
/* do we need a loadgroup of channels here? what does that buy us? /* do we need a loadgroup of channels here? what does that buy us?
if (!mLoadGroup) if (!mLoadGroup)
NS_NewLoadGroup NS_NewLoadGroup
@ -67,6 +78,14 @@ NS_IMETHODIMP nsImageLoader::LoadImage(nsIURI *aURI, nsIImageRequest **_retval)
nsCOMPtr<nsIImageRequest> imgRequest(do_CreateInstance("@mozilla.org/image/request;1")); nsCOMPtr<nsIImageRequest> imgRequest(do_CreateInstance("@mozilla.org/image/request;1"));
imgRequest->Init(newChannel); imgRequest->Init(newChannel);
#ifdef IMAGE_THREADPOOL
nsCOMPtr<nsIRunnable> run(do_QueryInterface(imgRequest));
mThreadPool->DispatchRequest(run);
#else
nsCOMPtr<nsIStreamListener> streamList(do_QueryInterface(imgRequest));
newChannel->AsyncRead(streamList, nsnull);
#endif
*_retval = imgRequest; *_retval = imgRequest;
NS_ADDREF(*_retval); NS_ADDREF(*_retval);

View File

@ -22,8 +22,7 @@
*/ */
#include "nsIImageLoader.h" #include "nsIImageLoader.h"
//#include "nsIDeviceContext.h" #include "nsIThreadPool.h"
#include "nsILoadGroup.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#define NS_IMAGELOADER_CID \ #define NS_IMAGELOADER_CID \
@ -44,6 +43,5 @@ public:
virtual ~nsImageLoader(); virtual ~nsImageLoader();
private: private:
// nsCOMPtr<nsIDeviceContext> mDeviceContext; nsCOMPtr<nsIThreadPool> mThreadPool;
nsCOMPtr<nsILoadGroup> mLoadGroup;
}; };

View File

@ -31,17 +31,22 @@
#include "nsIComponentManager.h" #include "nsIComponentManager.h"
#include "nsIComponentManager.h" #include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsString.h" #include "nsString.h"
#include "nsIEventQueueService.h"
#include "nsIEventQueue.h"
#include "nspr.h" #include "nspr.h"
NS_IMPL_ISUPPORTS4(nsImageRequest, nsIImageRequest, nsIRequest, nsIStreamListener, nsIStreamObserver) NS_IMPL_THREADSAFE_ISUPPORTS5(nsImageRequest, nsIImageRequest, nsIRequest, nsIStreamListener, nsIStreamObserver, nsIRunnable)
nsImageRequest::nsImageRequest() nsImageRequest::nsImageRequest()
{ {
NS_INIT_ISUPPORTS(); NS_INIT_ISUPPORTS();
/* member initializers and constructor code */ /* member initializers and constructor code */
mProcessing = PR_TRUE;
} }
nsImageRequest::~nsImageRequest() nsImageRequest::~nsImageRequest()
@ -49,6 +54,8 @@ nsImageRequest::~nsImageRequest()
/* destructor code */ /* destructor code */
} }
/* void init (in nsIChannel aChannel, in gfx_dimension width, in gfx_dimension height); */ /* void init (in nsIChannel aChannel, in gfx_dimension width, in gfx_dimension height); */
NS_IMETHODIMP nsImageRequest::Init(nsIChannel *aChannel) NS_IMETHODIMP nsImageRequest::Init(nsIChannel *aChannel)
{ {
@ -60,7 +67,7 @@ NS_IMETHODIMP nsImageRequest::Init(nsIChannel *aChannel)
// XXX do not init the image here. this has to be done from the image decoder. // XXX do not init the image here. this has to be done from the image decoder.
mImage = do_CreateInstance("@mozilla.org/gfx/image;2"); mImage = do_CreateInstance("@mozilla.org/gfx/image;2");
return aChannel->AsyncRead(NS_STATIC_CAST(nsIStreamListener*, this), nsnull); return NS_OK;
} }
/* readonly attribute nsIImage image; */ /* readonly attribute nsIImage image; */
@ -149,6 +156,8 @@ NS_IMETHODIMP nsImageRequest::OnStartRequest(nsIChannel *channel, nsISupports *c
/* void onStopRequest (in nsIChannel channel, in nsISupports ctxt, in nsresult status, in wstring statusArg); */ /* void onStopRequest (in nsIChannel channel, in nsISupports ctxt, in nsresult status, in wstring statusArg); */
NS_IMETHODIMP nsImageRequest::OnStopRequest(nsIChannel *channel, nsISupports *ctxt, nsresult status, const PRUnichar *statusArg) NS_IMETHODIMP nsImageRequest::OnStopRequest(nsIChannel *channel, nsISupports *ctxt, nsresult status, const PRUnichar *statusArg)
{ {
mProcessing = PR_FALSE;
if (!mDecoder) return NS_ERROR_FAILURE; if (!mDecoder) return NS_ERROR_FAILURE;
return mDecoder->Close(); return mDecoder->Close();
@ -172,4 +181,48 @@ NS_IMETHODIMP nsImageRequest::OnDataAvailable(nsIChannel *channel, nsISupports *
/** nsIRunnable methods **/
NS_IMETHODIMP nsImageRequest::Run()
{
nsresult rv = NS_OK;
if (!mChannel) return NS_ERROR_NOT_INITIALIZED;
// create an event queue for this thread.
#if 0
nsCOMPtr<nsIEventQueueService> service = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
rv = service->CreateThreadEventQueue();
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIEventQueue> currentThreadQ;
rv = service->GetThreadEventQueue(NS_CURRENT_THREAD,
getter_AddRefs(currentThreadQ));
if (NS_FAILED(rv)) return rv;
#endif
// initiate the AsyncRead from this thread so events are
// sent here for processing.
rv = mChannel->AsyncRead(NS_STATIC_CAST(nsIStreamListener*, this), nsnull);
if (NS_FAILED(rv)) return rv;
#if 0
// process events until we're finished.
PLEvent *event;
while (mProcessing) {
rv = currentThreadQ->WaitForEvent(&event);
if (NS_FAILED(rv)) return rv;
rv = currentThreadQ->HandleEvent(event);
if (NS_FAILED(rv)) return rv;
}
rv = service->DestroyThreadEventQueue();
if (NS_FAILED(rv)) return rv;
#endif
// XXX make sure cleanup happens on the calling thread.
return NS_OK;
}

View File

@ -23,6 +23,8 @@
#include "nsIImageRequest.h" #include "nsIImageRequest.h"
#include "nsIRunnable.h"
#include "nsIChannel.h" #include "nsIChannel.h"
#include "nsIImageContainer.h" #include "nsIImageContainer.h"
#include "nsIImageDecoder.h" #include "nsIImageDecoder.h"
@ -37,7 +39,7 @@
{0x8c, 0xdf, 0xef, 0xfb, 0x70, 0xd1, 0xea, 0x71} \ {0x8c, 0xdf, 0xef, 0xfb, 0x70, 0xd1, 0xea, 0x71} \
} }
class nsImageRequest : public nsIImageRequest, public nsIStreamListener class nsImageRequest : public nsIImageRequest, public nsIStreamListener, public nsIRunnable
{ {
public: public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
@ -45,6 +47,7 @@ public:
NS_DECL_NSIREQUEST NS_DECL_NSIREQUEST
NS_DECL_NSISTREAMLISTENER NS_DECL_NSISTREAMLISTENER
NS_DECL_NSISTREAMOBSERVER NS_DECL_NSISTREAMOBSERVER
NS_DECL_NSIRUNNABLE
nsImageRequest(); nsImageRequest();
virtual ~nsImageRequest(); virtual ~nsImageRequest();
@ -54,4 +57,6 @@ private:
nsCOMPtr<nsIChannel> mChannel; nsCOMPtr<nsIChannel> mChannel;
nsCOMPtr<nsIImageContainer> mImage; nsCOMPtr<nsIImageContainer> mImage;
nsCOMPtr<nsIImageDecoder> mDecoder; nsCOMPtr<nsIImageDecoder> mDecoder;
PRBool mProcessing;
}; };