removed dead interfaces
git-svn-id: svn://10.0.0.236/branches/THREADS_20060307_BRANCH@192103 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -1,88 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsIStreamListener.idl"
|
||||
|
||||
interface nsIEventQueue;
|
||||
|
||||
/**
|
||||
* A stream listener proxy is used to ship data over to another thread specified
|
||||
* by the thread's event queue. The "true" stream listener's methods are
|
||||
* invoked on the other thread.
|
||||
*
|
||||
* This interface only provides the initialization needed after construction.
|
||||
* Otherwise, these objects are used as nsIStreamListener.
|
||||
*/
|
||||
[scriptable, uuid(e400e688-6b54-4a84-8c4e-56b40281981a)]
|
||||
interface nsIStreamListenerProxy : nsIStreamListener
|
||||
{
|
||||
/**
|
||||
* Initializes an nsIStreamListenerProxy.
|
||||
*
|
||||
* @param aListener receives listener notifications on the other thread
|
||||
* @param aEventQ may be NULL indicating the calling thread's event queue
|
||||
* @param aBufferSegmentSize passing zero indicates the default
|
||||
* @param aBufferMaxSize passing zero indicates the default
|
||||
*/
|
||||
void init(in nsIStreamListener aListener,
|
||||
in nsIEventQueue aEventQ,
|
||||
in unsigned long aBufferSegmentSize,
|
||||
in unsigned long aBufferMaxSize);
|
||||
};
|
||||
|
||||
/**
|
||||
* THIS INTERFACE IS DEPRECATED
|
||||
*
|
||||
* An asynchronous stream listener is used to ship data over to another thread specified
|
||||
* by the thread's event queue. The receiver stream listener is then used to receive
|
||||
* the notifications on the other thread.
|
||||
*
|
||||
* This interface only provides the initialization needed after construction. Otherwise,
|
||||
* these objects are used simply as nsIStreamListener.
|
||||
*/
|
||||
[scriptable, uuid(1b012ade-91bf-11d3-8cd9-0060b0fc14a3)]
|
||||
interface nsIAsyncStreamListener : nsIStreamListener
|
||||
{
|
||||
/**
|
||||
* Initializes an nsIAsyncStreamListener.
|
||||
*
|
||||
* @param aReceiver receives listener notifications on the other thread
|
||||
* @param aEventQ may be null indicating the calling thread's event queue
|
||||
*/
|
||||
void init(in nsIStreamListener aReceiver,
|
||||
in nsIEventQueue aEventQ);
|
||||
};
|
||||
@@ -1,497 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsAsyncStreamListener.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsString.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsIEventQueueService.h"
|
||||
#include "nsIIOService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "prlog.h"
|
||||
|
||||
static NS_DEFINE_CID(kEventQueueService, NS_EVENTQUEUESERVICE_CID);
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
static PRLogModuleInfo* gStreamEventLog = 0;
|
||||
#endif
|
||||
|
||||
// prevent name conflicts
|
||||
#define nsStreamListenerEvent nsStreamListenerEvent0
|
||||
#define nsOnStartRequestEvent nsOnStartRequestEvent0
|
||||
#define nsOnStopRequestEvent nsOnStopRequestEvent0
|
||||
#define nsOnDataAvailableEvent nsOnDataAvailableEvent0
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsStreamListenerEvent
|
||||
{
|
||||
public:
|
||||
nsStreamListenerEvent(nsAsyncStreamObserver* listener,
|
||||
nsIRequest* request, nsISupports* context);
|
||||
virtual ~nsStreamListenerEvent();
|
||||
|
||||
nsresult Fire(nsIEventQueue* aEventQ);
|
||||
|
||||
NS_IMETHOD HandleEvent() = 0;
|
||||
|
||||
protected:
|
||||
static void* PR_CALLBACK HandlePLEvent(PLEvent* aEvent);
|
||||
static void PR_CALLBACK DestroyPLEvent(PLEvent* aEvent);
|
||||
|
||||
nsAsyncStreamObserver* mListener;
|
||||
nsIRequest* mRequest;
|
||||
nsISupports* mContext;
|
||||
PLEvent mEvent;
|
||||
};
|
||||
|
||||
#define GET_STREAM_LISTENER_EVENT(_this) \
|
||||
((nsStreamListenerEvent*)((char*)(_this) - offsetof(nsStreamListenerEvent, mEvent)))
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsStreamListenerEvent::nsStreamListenerEvent(nsAsyncStreamObserver* listener,
|
||||
nsIRequest* request, nsISupports* context)
|
||||
: mListener(listener), mRequest(request), mContext(context)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsStreamListenerEvent);
|
||||
|
||||
NS_IF_ADDREF(mListener);
|
||||
NS_IF_ADDREF(mRequest);
|
||||
NS_IF_ADDREF(mContext);
|
||||
}
|
||||
|
||||
nsStreamListenerEvent::~nsStreamListenerEvent()
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsStreamListenerEvent);
|
||||
|
||||
NS_IF_RELEASE(mListener);
|
||||
NS_IF_RELEASE(mRequest);
|
||||
NS_IF_RELEASE(mContext);
|
||||
}
|
||||
|
||||
void* PR_CALLBACK nsStreamListenerEvent::HandlePLEvent(PLEvent* aEvent)
|
||||
{
|
||||
nsStreamListenerEvent* ev = GET_STREAM_LISTENER_EVENT(aEvent);
|
||||
NS_ASSERTION(nsnull != ev,"null event.");
|
||||
|
||||
nsresult rv = ev->HandleEvent();
|
||||
//
|
||||
// If the consumer fails, then cancel the transport. This is necessary
|
||||
// in case where the socket transport is blocked waiting for room in the
|
||||
// pipe, but the consumer fails without consuming all the data.
|
||||
//
|
||||
// Unless the transport is cancelled, it will block forever, waiting for
|
||||
// the pipe to empty...
|
||||
//
|
||||
if (NS_FAILED(rv)) {
|
||||
nsresult cancelRv = ev->mRequest->Cancel(rv);
|
||||
NS_ASSERTION(NS_SUCCEEDED(cancelRv), "Cancel failed");
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
void PR_CALLBACK nsStreamListenerEvent::DestroyPLEvent(PLEvent* aEvent)
|
||||
{
|
||||
nsStreamListenerEvent* ev = GET_STREAM_LISTENER_EVENT(aEvent);
|
||||
NS_ASSERTION(nsnull != ev, "null event.");
|
||||
delete ev;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsStreamListenerEvent::Fire(nsIEventQueue* aEventQueue)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aEventQueue, "nsIEventQueue for thread is null");
|
||||
|
||||
PL_InitEvent(&mEvent,
|
||||
nsnull,
|
||||
nsStreamListenerEvent::HandlePLEvent,
|
||||
nsStreamListenerEvent::DestroyPLEvent);
|
||||
|
||||
return aEventQueue->PostEvent(&mEvent);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsAsyncStreamObserver,
|
||||
nsIRequestObserver)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsAsyncStreamListener, nsAsyncStreamObserver)
|
||||
NS_IMPL_RELEASE_INHERITED(nsAsyncStreamListener, nsAsyncStreamObserver)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAsyncStreamListener::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
{
|
||||
if (!aInstancePtr) return NS_ERROR_NULL_POINTER;
|
||||
if (aIID.Equals(NS_GET_IID(nsIAsyncStreamListener))) {
|
||||
*aInstancePtr = NS_STATIC_CAST(nsIAsyncStreamListener*, this);
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
if (aIID.Equals(NS_GET_IID(nsIStreamListener))) {
|
||||
*aInstancePtr = NS_STATIC_CAST(nsIStreamListener*, this);
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
return nsAsyncStreamObserver::QueryInterface(aIID, aInstancePtr);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAsyncStreamObserver::Init(nsIRequestObserver* aObserver, nsIEventQueue* aEventQ)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
NS_ASSERTION(aObserver, "null observer");
|
||||
mReceiver = aObserver;
|
||||
|
||||
nsCOMPtr<nsIEventQueueService> eventQService =
|
||||
do_GetService(kEventQueueService, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = eventQService->ResolveEventQueue(aEventQ, getter_AddRefs(mEventQueue));
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnStartRequest...
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsOnStartRequestEvent : public nsStreamListenerEvent
|
||||
{
|
||||
public:
|
||||
nsOnStartRequestEvent(nsAsyncStreamObserver* listener,
|
||||
nsIRequest* request, nsISupports* context)
|
||||
: nsStreamListenerEvent(listener, request, context) {}
|
||||
virtual ~nsOnStartRequestEvent() {}
|
||||
|
||||
NS_IMETHOD HandleEvent();
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOnStartRequestEvent::HandleEvent()
|
||||
{
|
||||
#if defined(PR_LOGGING)
|
||||
if (!gStreamEventLog)
|
||||
gStreamEventLog = PR_NewLogModule("netlibStreamEvent");
|
||||
PR_LOG(gStreamEventLog, PR_LOG_DEBUG,
|
||||
("netlibEvent: Handle Start [event=%x]", this));
|
||||
#endif
|
||||
nsIRequestObserver* receiver = (nsIRequestObserver*)mListener->GetReceiver();
|
||||
if (receiver == nsnull) {
|
||||
// must have already called OnStopRequest (it clears the receiver)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult status;
|
||||
nsresult rv = mRequest->GetStatus(&status);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "GetStatus failed");
|
||||
rv = receiver->OnStartRequest(mRequest, mContext);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAsyncStreamObserver::OnStartRequest(nsIRequest *request, nsISupports* context)
|
||||
{
|
||||
nsresult rv;
|
||||
nsOnStartRequestEvent* event =
|
||||
new nsOnStartRequestEvent(this, request, context);
|
||||
if (event == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
PLEventQueue *equeue;
|
||||
mEventQueue->GetPLEventQueue(&equeue);
|
||||
char ts[80];
|
||||
sprintf(ts, "nsAsyncStreamObserver: Start [this=%lx queue=%lx",
|
||||
(long)this, (long)equeue);
|
||||
if (!gStreamEventLog)
|
||||
gStreamEventLog = PR_NewLogModule("netlibStreamEvent");
|
||||
PR_LOG(gStreamEventLog, PR_LOG_DEBUG,
|
||||
("nsAsyncStreamObserver: Start [this=%x queue=%x event=%x]",
|
||||
this, equeue, event));
|
||||
#endif
|
||||
rv = event->Fire(mEventQueue);
|
||||
if (NS_FAILED(rv)) goto failed;
|
||||
return rv;
|
||||
|
||||
failed:
|
||||
delete event;
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnStopRequest
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsOnStopRequestEvent : public nsStreamListenerEvent
|
||||
{
|
||||
public:
|
||||
nsOnStopRequestEvent(nsAsyncStreamObserver* listener,
|
||||
nsISupports* context, nsIRequest* request)
|
||||
: nsStreamListenerEvent(listener, request, context),
|
||||
mStatus(NS_OK) {}
|
||||
virtual ~nsOnStopRequestEvent();
|
||||
|
||||
nsresult Init(nsresult aStatus);
|
||||
NS_IMETHOD HandleEvent();
|
||||
|
||||
protected:
|
||||
nsresult mStatus;
|
||||
};
|
||||
|
||||
nsOnStopRequestEvent::~nsOnStopRequestEvent()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsOnStopRequestEvent::Init(nsresult aStatus)
|
||||
{
|
||||
mStatus = aStatus;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOnStopRequestEvent::HandleEvent()
|
||||
{
|
||||
#if defined(PR_LOGGING)
|
||||
if (!gStreamEventLog)
|
||||
gStreamEventLog = PR_NewLogModule("netlibStreamEvent");
|
||||
PR_LOG(gStreamEventLog, PR_LOG_DEBUG,
|
||||
("netlibEvent: Handle Stop [event=%x]", this));
|
||||
#endif
|
||||
nsIRequestObserver* receiver = (nsIRequestObserver*)mListener->GetReceiver();
|
||||
if (receiver == nsnull) {
|
||||
// must have already called OnStopRequest (it clears the receiver)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult status = NS_OK;
|
||||
nsresult rv = mRequest->GetStatus(&status);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "GetStatus failed");
|
||||
|
||||
//
|
||||
// If the consumer returned a failure code, then pass it out in the
|
||||
// OnStopRequest(...) notification...
|
||||
//
|
||||
if (NS_SUCCEEDED(rv) && NS_FAILED(status)) {
|
||||
mStatus = status;
|
||||
}
|
||||
rv = receiver->OnStopRequest(mRequest, mContext, mStatus);
|
||||
// Call clear on the listener to make sure it's cleanup is done on the correct thread
|
||||
mListener->Clear();
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAsyncStreamObserver::OnStopRequest(nsIRequest* request, nsISupports* context,
|
||||
nsresult aStatus)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
//
|
||||
// Fire the OnStopRequest(...) regardless of what the current
|
||||
// Status is...
|
||||
//
|
||||
nsOnStopRequestEvent* event =
|
||||
new nsOnStopRequestEvent(this, context, request);
|
||||
if (event == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
rv = event->Init(aStatus);
|
||||
if (NS_FAILED(rv)) goto failed;
|
||||
#if defined(PR_LOGGING)
|
||||
PLEventQueue *equeue;
|
||||
mEventQueue->GetPLEventQueue(&equeue);
|
||||
if (!gStreamEventLog)
|
||||
gStreamEventLog = PR_NewLogModule("netlibStreamEvent");
|
||||
PR_LOG(gStreamEventLog, PR_LOG_DEBUG,
|
||||
("nsAsyncStreamObserver: Stop [this=%x queue=%x event=%x]",
|
||||
this, equeue, event));
|
||||
#endif
|
||||
rv = event->Fire(mEventQueue);
|
||||
if (NS_FAILED(rv)) goto failed;
|
||||
return rv;
|
||||
|
||||
failed:
|
||||
delete event;
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OnDataAvailable
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsOnDataAvailableEvent : public nsStreamListenerEvent
|
||||
{
|
||||
public:
|
||||
nsOnDataAvailableEvent(nsAsyncStreamObserver* listener,
|
||||
nsIRequest* request, nsISupports* context)
|
||||
: nsStreamListenerEvent(listener, request, context),
|
||||
mIStream(nsnull), mLength(0) {}
|
||||
virtual ~nsOnDataAvailableEvent();
|
||||
|
||||
nsresult Init(nsIInputStream* aIStream, PRUint32 aSourceOffset,
|
||||
PRUint32 aLength);
|
||||
NS_IMETHOD HandleEvent();
|
||||
|
||||
protected:
|
||||
nsIInputStream* mIStream;
|
||||
PRUint32 mSourceOffset;
|
||||
PRUint32 mLength;
|
||||
};
|
||||
|
||||
nsOnDataAvailableEvent::~nsOnDataAvailableEvent()
|
||||
{
|
||||
NS_RELEASE(mIStream);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsOnDataAvailableEvent::Init(nsIInputStream* aIStream, PRUint32 aSourceOffset,
|
||||
PRUint32 aLength)
|
||||
{
|
||||
mSourceOffset = aSourceOffset;
|
||||
mLength = aLength;
|
||||
mIStream = aIStream;
|
||||
NS_ADDREF(mIStream);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOnDataAvailableEvent::HandleEvent()
|
||||
{
|
||||
#if defined(PR_LOGGING)
|
||||
if (!gStreamEventLog)
|
||||
gStreamEventLog = PR_NewLogModule("netlibStreamEvent");
|
||||
PR_LOG(gStreamEventLog, PR_LOG_DEBUG,
|
||||
("netlibEvent: Handle Data [event=%x]", this));
|
||||
#endif
|
||||
nsIStreamListener* receiver = (nsIStreamListener*)mListener->GetReceiver();
|
||||
if (receiver == nsnull) {
|
||||
// must have already called OnStopRequest (it clears the receiver)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult status;
|
||||
nsresult rv = mRequest->GetStatus(&status);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "GetStatus failed");
|
||||
|
||||
//
|
||||
// Only send OnDataAvailable(... ) notifications if all previous calls
|
||||
// have succeeded...
|
||||
//
|
||||
if (NS_SUCCEEDED(rv) && NS_SUCCEEDED(status)) {
|
||||
rv = receiver->OnDataAvailable(mRequest, mContext,
|
||||
mIStream, mSourceOffset, mLength);
|
||||
}
|
||||
else {
|
||||
NS_WARNING("not calling OnDataAvailable");
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAsyncStreamListener::OnDataAvailable(nsIRequest* request, nsISupports* context,
|
||||
nsIInputStream *aIStream,
|
||||
PRUint32 aSourceOffset,
|
||||
PRUint32 aLength)
|
||||
{
|
||||
nsresult rv;
|
||||
nsOnDataAvailableEvent* event =
|
||||
new nsOnDataAvailableEvent(this, request, context);
|
||||
if (event == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
rv = event->Init(aIStream, aSourceOffset, aLength);
|
||||
if (NS_FAILED(rv)) goto failed;
|
||||
#if defined(PR_LOGGING)
|
||||
PLEventQueue *equeue;
|
||||
mEventQueue->GetPLEventQueue(&equeue);
|
||||
if (!gStreamEventLog)
|
||||
gStreamEventLog = PR_NewLogModule("netlibStreamEvent");
|
||||
PR_LOG(gStreamEventLog, PR_LOG_DEBUG,
|
||||
("nsAsyncStreamObserver: Data [this=%x queue=%x event=%x]",
|
||||
this, equeue, event));
|
||||
#endif
|
||||
rv = event->Fire(mEventQueue);
|
||||
if (NS_FAILED(rv)) goto failed;
|
||||
return rv;
|
||||
|
||||
failed:
|
||||
delete event;
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_METHOD
|
||||
nsAsyncStreamObserver::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
if (aOuter)
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
nsAsyncStreamObserver* l = new nsAsyncStreamObserver();
|
||||
if (l == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(l);
|
||||
nsresult rv = l->QueryInterface(aIID, aResult);
|
||||
NS_RELEASE(l);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsAsyncStreamListener::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
if (aOuter)
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
nsAsyncStreamListener* l = new nsAsyncStreamListener();
|
||||
if (l == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(l);
|
||||
nsresult rv = l->QueryInterface(aIID, aResult);
|
||||
NS_RELEASE(l);
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1,124 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsAsyncStreamListener_h__
|
||||
#define nsAsyncStreamListener_h__
|
||||
|
||||
#include "nsIStreamListenerProxy.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIEventQueue.h"
|
||||
#include "nsIRequestObserver.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIRequest.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsAsyncStreamObserver : public nsIRequestObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
|
||||
// nsAsyncStreamObserver methods:
|
||||
nsAsyncStreamObserver()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~nsAsyncStreamObserver() {}
|
||||
|
||||
static NS_METHOD
|
||||
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
|
||||
NS_METHOD Init(nsIRequestObserver *, nsIEventQueue *);
|
||||
|
||||
nsISupports* GetReceiver() { return mReceiver.get(); }
|
||||
void Clear() { mReceiver = nsnull; }
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIEventQueue> mEventQueue;
|
||||
nsCOMPtr<nsIRequestObserver> mReceiver;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsAsyncStreamListener : public nsAsyncStreamObserver,
|
||||
public nsIAsyncStreamListener
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIStreamListener methods:
|
||||
NS_IMETHOD OnStartRequest(nsIRequest* request,
|
||||
nsISupports* context)
|
||||
{
|
||||
return nsAsyncStreamObserver::OnStartRequest(request, context);
|
||||
}
|
||||
|
||||
NS_IMETHOD OnStopRequest(nsIRequest* request,
|
||||
nsISupports* context,
|
||||
nsresult aStatus)
|
||||
{
|
||||
return nsAsyncStreamObserver::OnStopRequest(request, context, aStatus);
|
||||
}
|
||||
|
||||
NS_IMETHOD OnDataAvailable(nsIRequest* request, nsISupports* context,
|
||||
nsIInputStream *aIStream,
|
||||
PRUint32 aSourceOffset,
|
||||
PRUint32 aLength);
|
||||
|
||||
// nsIAsyncStreamListener methods:
|
||||
NS_IMETHOD Init(nsIStreamListener* aListener, nsIEventQueue* aEventQ) {
|
||||
return nsAsyncStreamObserver::Init(aListener, aEventQ);
|
||||
}
|
||||
|
||||
// nsAsyncStreamListener methods:
|
||||
nsAsyncStreamListener() {
|
||||
MOZ_COUNT_CTOR(nsAsyncStreamListener);
|
||||
}
|
||||
|
||||
virtual ~nsAsyncStreamListener() {
|
||||
MOZ_COUNT_DTOR(nsAsyncStreamListener);
|
||||
}
|
||||
|
||||
static NS_METHOD
|
||||
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif // nsAsyncStreamListener_h__
|
||||
@@ -1,449 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsStreamListenerProxy.h"
|
||||
#include "netCore.h"
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsIPipe.h"
|
||||
#include "nsAutoLock.h"
|
||||
#include "prlog.h"
|
||||
#include "nsIOService.h"
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
static PRLogModuleInfo *gStreamListenerProxyLog;
|
||||
#endif
|
||||
|
||||
#define LOG(args) PR_LOG(gStreamListenerProxyLog, PR_LOG_DEBUG, args)
|
||||
|
||||
#define DEFAULT_BUFFER_SEGMENT_SIZE 4096
|
||||
#define DEFAULT_BUFFER_MAX_SIZE (4*4096)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Design Overview
|
||||
//
|
||||
// A stream listener proxy maintains a pipe. When the request makes data
|
||||
// available, the proxy copies as much of that data as possible into the pipe.
|
||||
// If data was written to the pipe, then the proxy posts an asynchronous event
|
||||
// corresponding to the amount of data written. If no data could be written,
|
||||
// because the pipe was full, then WOULD_BLOCK is returned to the request,
|
||||
// indicating that the request should suspend itself.
|
||||
//
|
||||
// Once suspended in this manner, the request is only resumed when the pipe is
|
||||
// emptied.
|
||||
//
|
||||
// XXX The current design does NOT allow the request to be "externally"
|
||||
// suspended!! For the moment this is not a problem, but it should be fixed.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// nsStreamListenerProxy implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
nsStreamListenerProxy::nsStreamListenerProxy()
|
||||
: mObserverProxy(nsnull)
|
||||
, mLock(nsnull)
|
||||
, mPendingCount(0)
|
||||
, mPipeEmptied(PR_FALSE)
|
||||
, mListenerStatus(NS_OK)
|
||||
{
|
||||
}
|
||||
|
||||
nsStreamListenerProxy::~nsStreamListenerProxy()
|
||||
{
|
||||
if (mLock) {
|
||||
PR_DestroyLock(mLock);
|
||||
mLock = nsnull;
|
||||
}
|
||||
NS_IF_RELEASE(mObserverProxy);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsStreamListenerProxy::GetListener(nsIStreamListener **listener)
|
||||
{
|
||||
NS_ENSURE_TRUE(mObserverProxy, NS_ERROR_NOT_INITIALIZED);
|
||||
nsIRequestObserver* obs = mObserverProxy->Observer();
|
||||
if (!obs)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
return CallQueryInterface(obs, listener);
|
||||
}
|
||||
|
||||
PRUint32
|
||||
nsStreamListenerProxy::GetPendingCount()
|
||||
{
|
||||
return PR_AtomicSet((PRInt32 *) &mPendingCount, 0);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// nsOnDataAvailableEvent internal class...
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
class nsOnDataAvailableEvent : public nsARequestObserverEvent
|
||||
{
|
||||
public:
|
||||
nsOnDataAvailableEvent(nsStreamListenerProxy *proxy,
|
||||
nsIRequest *request,
|
||||
nsISupports *context,
|
||||
nsIInputStream *source,
|
||||
PRUint32 offset)
|
||||
: nsARequestObserverEvent(request, context)
|
||||
, mProxy(proxy)
|
||||
, mSource(source)
|
||||
, mOffset(offset)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsOnDataAvailableEvent);
|
||||
NS_PRECONDITION(mProxy, "null pointer");
|
||||
NS_ADDREF(mProxy);
|
||||
}
|
||||
|
||||
~nsOnDataAvailableEvent()
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsOnDataAvailableEvent);
|
||||
NS_RELEASE(mProxy);
|
||||
}
|
||||
|
||||
void HandleEvent();
|
||||
|
||||
protected:
|
||||
nsStreamListenerProxy *mProxy;
|
||||
nsCOMPtr<nsIInputStream> mSource;
|
||||
PRUint32 mOffset;
|
||||
};
|
||||
|
||||
void
|
||||
nsOnDataAvailableEvent::HandleEvent()
|
||||
{
|
||||
LOG(("nsOnDataAvailableEvent: HandleEvent [req=%x]", mRequest.get()));
|
||||
|
||||
if (NS_FAILED(mProxy->GetListenerStatus())) {
|
||||
LOG(("nsOnDataAvailableEvent: Discarding event [listener_status=%x, req=%x]\n",
|
||||
mProxy->GetListenerStatus(), mRequest.get()));
|
||||
return;
|
||||
}
|
||||
|
||||
nsresult status = NS_OK;
|
||||
nsresult rv = mRequest->GetStatus(&status);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "GetStatus failed");
|
||||
|
||||
// We should only forward this event to the listener if the request is
|
||||
// still in a "good" state. Because these events are being processed
|
||||
// asynchronously, there is a very real chance that the listener might
|
||||
// have cancelled the request after _this_ event was triggered.
|
||||
|
||||
if (NS_FAILED(status)) {
|
||||
LOG(("nsOnDataAvailableEvent: Not calling OnDataAvailable [req=%x]",
|
||||
mRequest.get()));
|
||||
return;
|
||||
}
|
||||
|
||||
// Find out from the listener proxy how many bytes to report.
|
||||
PRUint32 count = mProxy->GetPendingCount();
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
{
|
||||
PRUint32 avail;
|
||||
mSource->Available(&avail);
|
||||
LOG(("nsOnDataAvailableEvent: Calling the consumer's OnDataAvailable "
|
||||
"[offset=%u count=%u avail=%u req=%x]\n",
|
||||
mOffset, count, avail, mRequest.get()));
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIStreamListener> listener;
|
||||
rv = mProxy->GetListener(getter_AddRefs(listener));
|
||||
|
||||
LOG(("handle dataevent=%8lX\n",(long)this));
|
||||
|
||||
// Forward call to listener
|
||||
if (listener)
|
||||
rv = listener->OnDataAvailable(mRequest, mContext,
|
||||
mSource, mOffset, count);
|
||||
|
||||
LOG(("nsOnDataAvailableEvent: Done with the consumer's OnDataAvailable "
|
||||
"[rv=%x, req=%x]\n", rv, mRequest.get()));
|
||||
|
||||
// XXX Need to suspend the underlying request... must consider
|
||||
// other pending events (such as OnStopRequest). These
|
||||
// should not be forwarded to the listener if the request
|
||||
// is suspended. Also, handling the Resume could be tricky.
|
||||
|
||||
if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
|
||||
NS_NOTREACHED("listener returned NS_BASE_STREAM_WOULD_BLOCK"
|
||||
" -- support for this is not implemented");
|
||||
rv = NS_BINDING_FAILED;
|
||||
}
|
||||
|
||||
// Cancel the request on unexpected errors
|
||||
if (NS_FAILED(rv) && (rv != NS_BASE_STREAM_CLOSED)) {
|
||||
LOG(("OnDataAvailable failed [rv=%x] canceling request!\n"));
|
||||
mRequest->Cancel(rv);
|
||||
}
|
||||
|
||||
mProxy->SetListenerStatus(rv);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// nsStreamListenerProxy::nsISupports implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS4(nsStreamListenerProxy,
|
||||
nsIStreamListener,
|
||||
nsIRequestObserver,
|
||||
nsIStreamListenerProxy,
|
||||
nsIInputStreamObserver)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// nsStreamListenerProxy::nsIRequestObserver implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStreamListenerProxy::OnStartRequest(nsIRequest *request,
|
||||
nsISupports *context)
|
||||
{
|
||||
NS_ENSURE_TRUE(mObserverProxy, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIObservableInputStream> obs(do_QueryInterface(mPipeIn, &rv));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// This will create a cyclic reference between the pipe and |this|, which
|
||||
// will be broken when onStopRequest is called.
|
||||
rv = obs->SetObserver(this);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
return mObserverProxy->OnStartRequest(request, context);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStreamListenerProxy::OnStopRequest(nsIRequest *request,
|
||||
nsISupports *context,
|
||||
nsresult status)
|
||||
{
|
||||
NS_ENSURE_TRUE(mObserverProxy, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
mPipeIn = 0;
|
||||
mPipeOut = 0;
|
||||
|
||||
return mObserverProxy->OnStopRequest(request, context, status);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// nsIStreamListener implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStreamListenerProxy::OnDataAvailable(nsIRequest *request,
|
||||
nsISupports *context,
|
||||
nsIInputStream *source,
|
||||
PRUint32 offset,
|
||||
PRUint32 count)
|
||||
{
|
||||
nsresult rv;
|
||||
PRUint32 bytesWritten=0;
|
||||
|
||||
LOG(("nsStreamListenerProxy: OnDataAvailable [offset=%u count=%u req=%x]\n",
|
||||
offset, count, request));
|
||||
|
||||
NS_ENSURE_TRUE(mObserverProxy, NS_ERROR_NOT_INITIALIZED);
|
||||
NS_PRECONDITION(mRequestToResume == 0, "Unexpected call to OnDataAvailable");
|
||||
NS_PRECONDITION(mPipeIn, "Pipe not initialized");
|
||||
NS_PRECONDITION(mPipeOut, "Pipe not initialized");
|
||||
|
||||
//
|
||||
// Any non-successful listener status gets passed back to the caller
|
||||
//
|
||||
{
|
||||
nsresult status = mListenerStatus;
|
||||
if (NS_FAILED(status)) {
|
||||
LOG(("nsStreamListenerProxy: Listener failed [status=%x req=%x]\n",
|
||||
status, request));
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
mPipeEmptied = PR_FALSE;
|
||||
//
|
||||
// Try to copy data into the pipe.
|
||||
//
|
||||
// If the pipe is full, then we return NS_BASE_STREAM_WOULD_BLOCK
|
||||
// so the calling request can suspend itself. If, however, we detect
|
||||
// that the pipe was emptied during this time, we retry copying data
|
||||
// into the pipe.
|
||||
//
|
||||
rv = mPipeOut->WriteFrom(source, count, &bytesWritten);
|
||||
|
||||
LOG(("nsStreamListenerProxy: Wrote data to pipe [rv=%x count=%u bytesWritten=%u req=%x]\n",
|
||||
rv, count, bytesWritten, request));
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
|
||||
nsAutoLock lock(mLock);
|
||||
if (mPipeEmptied) {
|
||||
LOG(("nsStreamListenerProxy: Pipe emptied; looping back [req=%x]\n", request));
|
||||
continue;
|
||||
}
|
||||
LOG(("nsStreamListenerProxy: Pipe full; setting request to resume [req=%x]\n", request));
|
||||
mRequestToResume = request;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
if (bytesWritten == 0) {
|
||||
LOG(("nsStreamListenerProxy: Copied zero bytes; not posting an event [req=%x]\n", request));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Copied something into the pipe...
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Update the pending count; return if able to piggy-back on a pending event.
|
||||
//
|
||||
PRUint32 total = PR_AtomicAdd((PRInt32 *) &mPendingCount, bytesWritten);
|
||||
if (total > bytesWritten) {
|
||||
LOG(("nsStreamListenerProxy: Piggy-backing pending event [total=%u, req=%x]\n",
|
||||
total, request));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// Post an event for the number of bytes actually written.
|
||||
//
|
||||
nsOnDataAvailableEvent *ev =
|
||||
new nsOnDataAvailableEvent(this, request, context, mPipeIn, offset);
|
||||
if (!ev) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// Reuse the event queue of the observer proxy
|
||||
LOG(("post dataevent=%8lX queue=%8lX\n",(long)ev,(long)mObserverProxy->EventQueue()));
|
||||
rv = mObserverProxy->FireEvent(ev);
|
||||
if (NS_FAILED(rv))
|
||||
delete ev;
|
||||
return rv;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// nsStreamListenerProxy::nsIStreamListenerProxy implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStreamListenerProxy::Init(nsIStreamListener *listener,
|
||||
nsIEventQueue *eventQ,
|
||||
PRUint32 bufferSegmentSize,
|
||||
PRUint32 bufferMaxSize)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(listener);
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
if (!gStreamListenerProxyLog)
|
||||
gStreamListenerProxyLog = PR_NewLogModule("nsStreamListenerProxy");
|
||||
#endif
|
||||
|
||||
//
|
||||
// Create the RequestToResume lock
|
||||
//
|
||||
mLock = PR_NewLock();
|
||||
if (!mLock) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
//
|
||||
// Create the request observer proxy
|
||||
//
|
||||
mObserverProxy = new nsRequestObserverProxy();
|
||||
if (!mObserverProxy) return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(mObserverProxy);
|
||||
|
||||
//
|
||||
// Create the pipe
|
||||
//
|
||||
if (bufferSegmentSize == 0)
|
||||
bufferSegmentSize = DEFAULT_BUFFER_SEGMENT_SIZE;
|
||||
if (bufferMaxSize == 0)
|
||||
bufferMaxSize = DEFAULT_BUFFER_MAX_SIZE;
|
||||
// The segment size must not exceed the maximum
|
||||
bufferSegmentSize = PR_MIN(bufferMaxSize, bufferSegmentSize);
|
||||
|
||||
// Use the necko buffer cache for the default buffers
|
||||
nsIMemory *allocator = nsnull;
|
||||
if (bufferSegmentSize == DEFAULT_BUFFER_SEGMENT_SIZE)
|
||||
allocator = nsIOService::gBufferCache;
|
||||
nsresult rv = NS_NewPipe(getter_AddRefs(mPipeIn),
|
||||
getter_AddRefs(mPipeOut),
|
||||
bufferSegmentSize,
|
||||
bufferMaxSize,
|
||||
PR_TRUE, PR_TRUE, allocator);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIRequestObserver> observer = do_QueryInterface(listener);
|
||||
return mObserverProxy->Init(observer, eventQ);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// nsStreamListenerProxy::nsIInputStreamObserver implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStreamListenerProxy::OnEmpty(nsIInputStream *inputStream)
|
||||
{
|
||||
LOG(("nsStreamListenerProxy: OnEmpty\n"));
|
||||
//
|
||||
// The pipe has been emptied by the listener. If the request
|
||||
// has been suspended (waiting for the pipe to be emptied), then
|
||||
// go ahead and resume it. But take care not to resume while
|
||||
// holding the "ChannelToResume" lock.
|
||||
//
|
||||
nsCOMPtr<nsIRequest> req;
|
||||
{
|
||||
nsAutoLock lock(mLock);
|
||||
if (mRequestToResume) {
|
||||
req = mRequestToResume;
|
||||
mRequestToResume = 0;
|
||||
}
|
||||
mPipeEmptied = PR_TRUE; // Flag this call
|
||||
}
|
||||
if (req) {
|
||||
LOG(("nsStreamListenerProxy: Resuming request\n"));
|
||||
req->Resume();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStreamListenerProxy::OnClose(nsIInputStream *aInputStream)
|
||||
{
|
||||
LOG(("nsStreamListenerProxy: OnClose\n"));
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsStreamListenerProxy_h__
|
||||
#define nsStreamListenerProxy_h__
|
||||
|
||||
#include "nsRequestObserverProxy.h"
|
||||
#include "nsIStreamListenerProxy.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsIObservableInputStream.h"
|
||||
#include "nsIRequest.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
class nsStreamListenerProxy : public nsIStreamListenerProxy
|
||||
, public nsIInputStreamObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSISTREAMLISTENERPROXY
|
||||
NS_DECL_NSIINPUTSTREAMOBSERVER
|
||||
|
||||
nsStreamListenerProxy();
|
||||
virtual ~nsStreamListenerProxy();
|
||||
|
||||
nsresult GetListener(nsIStreamListener **);
|
||||
|
||||
void SetListenerStatus(nsresult status) { mListenerStatus = status; }
|
||||
nsresult GetListenerStatus() { return mListenerStatus; }
|
||||
|
||||
PRUint32 GetPendingCount();
|
||||
|
||||
protected:
|
||||
nsRequestObserverProxy *mObserverProxy;
|
||||
|
||||
nsCOMPtr<nsIInputStream> mPipeIn;
|
||||
nsCOMPtr<nsIOutputStream> mPipeOut;
|
||||
|
||||
nsCOMPtr<nsIRequest> mRequestToResume;
|
||||
PRLock *mLock;
|
||||
PRUint32 mPendingCount;
|
||||
PRBool mPipeEmptied;
|
||||
nsresult mListenerStatus;
|
||||
};
|
||||
|
||||
#endif // nsStreamListenerProxy_h__
|
||||
@@ -1,297 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Darin Fisher <darin@netscape.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsStreamObserverProxy.h"
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIEventQueueService.h"
|
||||
#include "nsString.h"
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
PRLogModuleInfo *gStreamProxyLog;
|
||||
#endif
|
||||
#define LOG(args) PR_LOG(gStreamProxyLog, PR_LOG_DEBUG, args)
|
||||
|
||||
static NS_DEFINE_CID(kEventQueueService, NS_EVENTQUEUESERVICE_CID);
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsStreamObserverEvent implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
nsStreamObserverEvent::nsStreamObserverEvent(nsStreamProxyBase *aProxy,
|
||||
nsIRequest *aRequest,
|
||||
nsISupports *aContext)
|
||||
: mProxy(aProxy)
|
||||
, mRequest(aRequest)
|
||||
, mContext(aContext)
|
||||
{
|
||||
NS_IF_ADDREF(mProxy);
|
||||
}
|
||||
|
||||
nsStreamObserverEvent::~nsStreamObserverEvent()
|
||||
{
|
||||
NS_IF_RELEASE(mProxy);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsStreamObserverEvent::FireEvent(nsIEventQueue *aEventQ)
|
||||
{
|
||||
NS_PRECONDITION(aEventQ, "null event queue");
|
||||
|
||||
PL_InitEvent(&mEvent, nsnull,
|
||||
nsStreamObserverEvent::HandlePLEvent,
|
||||
nsStreamObserverEvent::DestroyPLEvent);
|
||||
|
||||
PRStatus status = aEventQ->PostEvent(&mEvent);
|
||||
return status == PR_SUCCESS ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
void* PR_CALLBACK
|
||||
nsStreamObserverEvent::HandlePLEvent(PLEvent *aEvent)
|
||||
{
|
||||
nsStreamObserverEvent *ev = GET_STREAM_OBSERVER_EVENT(aEvent);
|
||||
NS_ASSERTION(ev, "null event");
|
||||
|
||||
// Pass control the real event handler
|
||||
if (ev)
|
||||
ev->HandleEvent();
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
void PR_CALLBACK
|
||||
nsStreamObserverEvent::DestroyPLEvent(PLEvent *aEvent)
|
||||
{
|
||||
nsStreamObserverEvent *ev = GET_STREAM_OBSERVER_EVENT(aEvent);
|
||||
NS_ASSERTION(ev, "null event");
|
||||
delete ev;
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsOnStartRequestEvent internal class...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
class nsOnStartRequestEvent : public nsStreamObserverEvent
|
||||
{
|
||||
public:
|
||||
nsOnStartRequestEvent(nsStreamProxyBase *aProxy,
|
||||
nsIRequest *aRequest,
|
||||
nsISupports *aContext)
|
||||
: nsStreamObserverEvent(aProxy, aRequest, aContext)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsOnStartRequestEvent);
|
||||
}
|
||||
|
||||
~nsOnStartRequestEvent()
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsOnStartRequestEvent);
|
||||
}
|
||||
|
||||
NS_IMETHOD HandleEvent();
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOnStartRequestEvent::HandleEvent()
|
||||
{
|
||||
LOG(("nsOnStartRequestEvent: HandleEvent [event=%x req=%x]\n",
|
||||
this, mRequest.get()));
|
||||
|
||||
nsCOMPtr<nsIStreamObserver> observer = mProxy->GetReceiver();
|
||||
if (!observer) {
|
||||
LOG(("nsOnStartRequestEvent: Already called OnStopRequest (observer is NULL)\n"));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult rv = observer->OnStartRequest(mRequest, mContext);
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("OnStartRequest failed [rv=%x] canceling request!\n", rv));
|
||||
mRequest->Cancel(rv);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsOnStopRequestEvent internal class...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
class nsOnStopRequestEvent : public nsStreamObserverEvent
|
||||
{
|
||||
public:
|
||||
nsOnStopRequestEvent(nsStreamProxyBase *aProxy,
|
||||
nsIRequest *aRequest, nsISupports *aContext,
|
||||
nsresult aStatus, const PRUnichar *aStatusText)
|
||||
: nsStreamObserverEvent(aProxy, aRequest, aContext)
|
||||
, mStatus(aStatus)
|
||||
, mStatusText(aStatusText)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsOnStopRequestEvent);
|
||||
}
|
||||
|
||||
~nsOnStopRequestEvent()
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsOnStopRequestEvent);
|
||||
}
|
||||
|
||||
NS_IMETHOD HandleEvent();
|
||||
|
||||
protected:
|
||||
nsresult mStatus;
|
||||
nsString mStatusText;
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOnStopRequestEvent::HandleEvent()
|
||||
{
|
||||
LOG(("nsOnStopRequestEvent: HandleEvent [event=%x req=%x]\n",
|
||||
this, mRequest.get()));
|
||||
|
||||
nsCOMPtr<nsIStreamObserver> observer = mProxy->GetReceiver();
|
||||
if (!observer) {
|
||||
LOG(("nsOnStopRequestEvent: Already called OnStopRequest (observer is NULL)\n"));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
//
|
||||
// Do not allow any more events to be handled after OnStopRequest
|
||||
//
|
||||
mProxy->SetReceiver(nsnull);
|
||||
|
||||
return observer->OnStopRequest(mRequest,
|
||||
mContext,
|
||||
mStatus,
|
||||
mStatusText.get());
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsStreamProxyBase: nsISupports implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsStreamProxyBase,
|
||||
nsIStreamObserver)
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsStreamProxyBase: nsIStreamObserver implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsStreamProxyBase::OnStartRequest(nsIRequest *aRequest,
|
||||
nsISupports *aContext)
|
||||
{
|
||||
LOG(("nsStreamProxyBase: OnStartRequest [this=%x req=%x]\n", this, aRequest));
|
||||
nsOnStartRequestEvent *ev =
|
||||
new nsOnStartRequestEvent(this, aRequest, aContext);
|
||||
if (!ev)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsresult rv = ev->FireEvent(GetEventQueue());
|
||||
if (NS_FAILED(rv))
|
||||
delete ev;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStreamProxyBase::OnStopRequest(nsIRequest *aRequest,
|
||||
nsISupports *aContext,
|
||||
nsresult aStatus,
|
||||
const PRUnichar *aStatusText)
|
||||
{
|
||||
LOG(("nsStreamProxyBase: OnStopRequest [this=%x req=%x status=%x]\n",
|
||||
this, aRequest, aStatus));
|
||||
nsOnStopRequestEvent *ev =
|
||||
new nsOnStopRequestEvent(this, aRequest, aContext, aStatus, aStatusText);
|
||||
if (!ev)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsresult rv = ev->FireEvent(GetEventQueue());
|
||||
if (NS_FAILED(rv))
|
||||
delete ev;
|
||||
return rv;
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsStreamProxyBase: implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
nsresult
|
||||
nsStreamProxyBase::SetEventQueue(nsIEventQueue *aEventQ)
|
||||
{
|
||||
#if defined(PR_LOGGING)
|
||||
if (!gStreamProxyLog)
|
||||
gStreamProxyLog = PR_NewLogModule("nsStreamProxy");
|
||||
#endif
|
||||
nsresult rv = NS_OK;
|
||||
if ((aEventQ == NS_CURRENT_EVENTQ) || (aEventQ == NS_UI_THREAD_EVENTQ)) {
|
||||
nsCOMPtr<nsIEventQueueService> serv =
|
||||
do_GetService(kEventQueueService, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
rv = serv->GetSpecialEventQueue((PRInt32) aEventQ,
|
||||
getter_AddRefs(mEventQ));
|
||||
} else
|
||||
mEventQ = aEventQ;
|
||||
return rv;
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsStreamObserverProxy: nsISupports implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(nsStreamObserverProxy,
|
||||
nsStreamProxyBase,
|
||||
nsIStreamObserverProxy)
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsStreamObserverProxy: nsIStreamObserverProxy implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsStreamObserverProxy::Init(nsIStreamObserver *aObserver,
|
||||
nsIEventQueue *aEventQ)
|
||||
{
|
||||
NS_PRECONDITION(aObserver, "null observer");
|
||||
SetReceiver(aObserver);
|
||||
return SetEventQueue(aEventQ);
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsStreamObserverProxy_h__
|
||||
#define nsStreamObserverProxy_h__
|
||||
|
||||
#include "nsIStreamObserver.h"
|
||||
#include "nsIEventQueue.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "prlog.h"
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
extern PRLogModuleInfo *gStreamProxyLog;
|
||||
#endif
|
||||
|
||||
class nsStreamProxyBase : public nsIStreamObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISTREAMOBSERVER
|
||||
|
||||
nsStreamProxyBase() { }
|
||||
virtual ~nsStreamProxyBase() {}
|
||||
|
||||
nsIEventQueue *GetEventQueue() { return mEventQ.get(); }
|
||||
nsIStreamObserver *GetReceiver() { return mReceiver.get(); }
|
||||
|
||||
nsresult SetEventQueue(nsIEventQueue *);
|
||||
|
||||
nsresult SetReceiver(nsIStreamObserver *aReceiver) {
|
||||
PRBool same = ::SameCOMIdentity(aReceiver, this);
|
||||
NS_ASSERTION((!same), "aReceiver is self");
|
||||
mReceiver = aReceiver;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIEventQueue> mEventQ;
|
||||
nsCOMPtr<nsIStreamObserver> mReceiver;
|
||||
};
|
||||
|
||||
class nsStreamObserverProxy : public nsStreamProxyBase
|
||||
, public nsIStreamObserverProxy
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_FORWARD_NSISTREAMOBSERVER(nsStreamProxyBase::)
|
||||
NS_DECL_NSISTREAMOBSERVERPROXY
|
||||
};
|
||||
|
||||
class nsStreamObserverEvent
|
||||
{
|
||||
public:
|
||||
nsStreamObserverEvent(nsStreamProxyBase *proxy,
|
||||
nsIRequest *request, nsISupports *context);
|
||||
virtual ~nsStreamObserverEvent();
|
||||
|
||||
nsresult FireEvent(nsIEventQueue *);
|
||||
NS_IMETHOD HandleEvent() = 0;
|
||||
|
||||
protected:
|
||||
static void* PR_CALLBACK HandlePLEvent(PLEvent *);
|
||||
static void PR_CALLBACK DestroyPLEvent(PLEvent *);
|
||||
|
||||
PLEvent mEvent;
|
||||
nsStreamProxyBase *mProxy;
|
||||
nsCOMPtr<nsIRequest> mRequest;
|
||||
nsCOMPtr<nsISupports> mContext;
|
||||
};
|
||||
|
||||
#define GET_STREAM_OBSERVER_EVENT(_mEvent_ptr) \
|
||||
((nsStreamObserverEvent *) \
|
||||
((char *)(_mEvent_ptr) - offsetof(nsStreamObserverEvent, mEvent)))
|
||||
|
||||
#endif /* !nsStreamObserverProxy_h__ */
|
||||
Reference in New Issue
Block a user