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)]
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);
/// @return the image object associated with the request.

View File

@ -29,6 +29,7 @@
#include "nsIChannel.h"
#include "nsIIOService.h"
#include "nsIRunnable.h"
#include "nsIStreamListener.h"
#include "nsIURI.h"
@ -49,6 +50,16 @@ nsImageLoader::~nsImageLoader()
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?
if (!mLoadGroup)
NS_NewLoadGroup
@ -67,6 +78,14 @@ NS_IMETHODIMP nsImageLoader::LoadImage(nsIURI *aURI, nsIImageRequest **_retval)
nsCOMPtr<nsIImageRequest> imgRequest(do_CreateInstance("@mozilla.org/image/request;1"));
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;
NS_ADDREF(*_retval);

View File

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

View File

@ -31,17 +31,22 @@
#include "nsIComponentManager.h"
#include "nsIComponentManager.h"
#include "nsIServiceManager.h"
#include "nsString.h"
#include "nsIEventQueueService.h"
#include "nsIEventQueue.h"
#include "nspr.h"
NS_IMPL_ISUPPORTS4(nsImageRequest, nsIImageRequest, nsIRequest, nsIStreamListener, nsIStreamObserver)
NS_IMPL_THREADSAFE_ISUPPORTS5(nsImageRequest, nsIImageRequest, nsIRequest, nsIStreamListener, nsIStreamObserver, nsIRunnable)
nsImageRequest::nsImageRequest()
{
NS_INIT_ISUPPORTS();
/* member initializers and constructor code */
mProcessing = PR_TRUE;
}
nsImageRequest::~nsImageRequest()
@ -49,6 +54,8 @@ nsImageRequest::~nsImageRequest()
/* destructor code */
}
/* void init (in nsIChannel aChannel, in gfx_dimension width, in gfx_dimension height); */
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.
mImage = do_CreateInstance("@mozilla.org/gfx/image;2");
return aChannel->AsyncRead(NS_STATIC_CAST(nsIStreamListener*, this), nsnull);
return NS_OK;
}
/* 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); */
NS_IMETHODIMP nsImageRequest::OnStopRequest(nsIChannel *channel, nsISupports *ctxt, nsresult status, const PRUnichar *statusArg)
{
mProcessing = PR_FALSE;
if (!mDecoder) return NS_ERROR_FAILURE;
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 "nsIRunnable.h"
#include "nsIChannel.h"
#include "nsIImageContainer.h"
#include "nsIImageDecoder.h"
@ -37,7 +39,7 @@
{0x8c, 0xdf, 0xef, 0xfb, 0x70, 0xd1, 0xea, 0x71} \
}
class nsImageRequest : public nsIImageRequest, public nsIStreamListener
class nsImageRequest : public nsIImageRequest, public nsIStreamListener, public nsIRunnable
{
public:
NS_DECL_ISUPPORTS
@ -45,6 +47,7 @@ public:
NS_DECL_NSIREQUEST
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSISTREAMOBSERVER
NS_DECL_NSIRUNNABLE
nsImageRequest();
virtual ~nsImageRequest();
@ -54,4 +57,6 @@ private:
nsCOMPtr<nsIChannel> mChannel;
nsCOMPtr<nsIImageContainer> mImage;
nsCOMPtr<nsIImageDecoder> mDecoder;
PRBool mProcessing;
};