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:
darin%meer.net
2006-03-09 20:15:21 +00:00
parent b369945350
commit 2afd3a17be
7 changed files with 0 additions and 1648 deletions

View File

@@ -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);
};

View File

@@ -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;
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -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__

View File

@@ -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;
}

View File

@@ -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__

View File

@@ -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);
}

View File

@@ -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__ */