зеркало из https://github.com/mozilla/pjs.git
fixes crash in js_FreeStack caused by a race condition in necko. see 139556 for the details. r=rpotts, sr=darin
This commit is contained in:
Родитель
0f577ea944
Коммит
7fc5a0ea7e
|
@ -49,6 +49,7 @@
|
|||
#include "nsReadableUtils.h"
|
||||
#include "nsIProxyObjectManager.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsProxyRelease.h"
|
||||
|
||||
static NS_DEFINE_CID(kProxyObjectManagerCID, NS_PROXYEVENT_MANAGER_CID);
|
||||
|
||||
|
@ -520,6 +521,10 @@ nsFileTransport::AsyncRead(nsIStreamListener *aListener,
|
|||
mTransferAmount = aTransferCount;
|
||||
mXferState = OPEN_FOR_READ;
|
||||
|
||||
nsIEventQueueService* eqService = mService->GetCachedEventQueueService();
|
||||
eqService->GetSpecialEventQueue(nsIEventQueueService::CURRENT_THREAD_EVENT_QUEUE, getter_AddRefs(mEventQ));
|
||||
NS_ASSERTION(mEventQ, "No Event Queue on calling thread");
|
||||
|
||||
LOG(("nsFileTransport: AsyncRead [this=%x %s] mOffset=%d mTransferAmount=%d\n",
|
||||
this, mStreamName.get(), mOffset, mTransferAmount));
|
||||
|
||||
|
@ -563,6 +568,10 @@ nsFileTransport::AsyncWrite(nsIStreamProvider *aProvider,
|
|||
mTransferAmount = aTransferCount;
|
||||
mXferState = OPEN_FOR_WRITE;
|
||||
|
||||
nsIEventQueueService* eqService = mService->GetCachedEventQueueService();
|
||||
eqService->GetSpecialEventQueue(nsIEventQueueService::CURRENT_THREAD_EVENT_QUEUE, getter_AddRefs(mEventQ));
|
||||
NS_ASSERTION(mEventQ, "No Event Queue on calling thread");
|
||||
|
||||
LOG(("nsFileTransport: AsyncWrite [this=%x %s] mOffset=%d mTransferAmount=%d\n",
|
||||
this, mStreamName.get(), mOffset, mTransferAmount));
|
||||
|
||||
|
@ -823,27 +832,38 @@ nsFileTransport::Process(nsIProgressEventSink *progressSink)
|
|||
// is reusing the stream.
|
||||
mXferState = CLOSING;
|
||||
DoClose();
|
||||
nsCOMPtr <nsISupports> saveContext = mContext;
|
||||
nsCOMPtr <nsIStreamListener> saveListener = mListener;
|
||||
mListener = nsnull;
|
||||
mContext = nsnull;
|
||||
|
||||
// close the data source
|
||||
NS_IF_RELEASE(mSourceWrapper);
|
||||
mSourceWrapper = nsnull;
|
||||
|
||||
if (progressSink) {
|
||||
progressSink->OnStatus(this, saveContext,
|
||||
NS_NET_STATUS_READ_FROM,
|
||||
NS_ConvertASCIItoUCS2(mStreamName).get());
|
||||
progressSink->OnStatus(this,
|
||||
mContext,
|
||||
NS_NET_STATUS_READ_FROM,
|
||||
NS_ConvertASCIItoUCS2(mStreamName).get());
|
||||
}
|
||||
|
||||
if (saveListener) {
|
||||
saveListener->OnStopRequest(this, saveContext, mStatus);
|
||||
saveListener = 0;
|
||||
if (mListener) {
|
||||
mListener->OnStopRequest(this, mContext, mStatus);
|
||||
mListener = 0;
|
||||
}
|
||||
saveContext = 0;
|
||||
|
||||
// if we have a context, we have to ensure that it is released on the
|
||||
// proper thread.
|
||||
if (mContext) {
|
||||
if (mEventQ) {
|
||||
// see http://bugzilla.mozilla.org/show_bug.cgi?id=139556#c64
|
||||
// for the reason behind this evil reference counting.
|
||||
nsISupports* doomed = mContext.get();
|
||||
NS_ADDREF(doomed);
|
||||
mContext = 0;
|
||||
NS_ProxyRelease(mEventQ, doomed);
|
||||
}
|
||||
else {
|
||||
mContext = nsnull;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1002,16 +1022,31 @@ nsFileTransport::Process(nsIProgressEventSink *progressSink)
|
|||
NS_IF_RELEASE(mSinkWrapper);
|
||||
mSinkWrapper = nsnull;
|
||||
|
||||
if (mProvider) {
|
||||
mProvider->OnStopRequest(this, mContext, mStatus);
|
||||
mProvider = 0;
|
||||
}
|
||||
if (progressSink)
|
||||
progressSink->OnStatus(this, mContext,
|
||||
NS_NET_STATUS_WROTE_TO,
|
||||
NS_ConvertASCIItoUCS2(mStreamName).get());
|
||||
mContext = 0;
|
||||
|
||||
if (mProvider) {
|
||||
mProvider->OnStopRequest(this, mContext, mStatus);
|
||||
mProvider = 0;
|
||||
}
|
||||
|
||||
// if we have a context, we have to ensure that it is released on the
|
||||
// proper thread.
|
||||
if (mContext) {
|
||||
if (mEventQ) {
|
||||
// see http://bugzilla.mozilla.org/show_bug.cgi?id=139556#c64
|
||||
// for the reason behind this evil reference counting.
|
||||
nsISupports* doomed = mContext.get();
|
||||
NS_ADDREF(doomed);
|
||||
mContext = 0;
|
||||
NS_ProxyRelease(mEventQ, doomed);
|
||||
}
|
||||
else {
|
||||
mContext = nsnull;
|
||||
}
|
||||
}
|
||||
mXferState = CLOSING;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1,175 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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):
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
*
|
||||
* 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 NPL, 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 NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsFileTransport_h__
|
||||
#define nsFileTransport_h__
|
||||
|
||||
#include "nsITransport.h"
|
||||
#include "nsIRequest.h"
|
||||
#include "nsIRunnable.h"
|
||||
#include "nsFileSpec.h"
|
||||
#include "prlock.h"
|
||||
#include "nsIEventQueueService.h"
|
||||
#include "nsIPipe.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIStreamProvider.h"
|
||||
#include "nsIProgressEventSink.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsIStreamIO.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsIFile.h"
|
||||
#include "prlog.h"
|
||||
#include "nsFileTransportService.h"
|
||||
|
||||
//#define TIMING
|
||||
|
||||
class nsIInterfaceRequestor;
|
||||
|
||||
class nsFileTransportSourceWrapper;
|
||||
class nsFileTransportSinkWrapper;
|
||||
|
||||
class nsFileTransport : public nsITransport,
|
||||
public nsITransportRequest,
|
||||
public nsIRunnable
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSITRANSPORT
|
||||
NS_DECL_NSIREQUEST
|
||||
NS_DECL_NSITRANSPORTREQUEST
|
||||
NS_DECL_NSIRUNNABLE
|
||||
|
||||
nsFileTransport();
|
||||
// Always make the destructor virtual:
|
||||
virtual ~nsFileTransport();
|
||||
|
||||
// Define a Create method to be used with a factory:
|
||||
static NS_METHOD
|
||||
Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult);
|
||||
|
||||
nsresult Init(nsFileTransportService *aService, nsIFile* file,
|
||||
PRInt32 ioFlags,
|
||||
PRInt32 perm,
|
||||
PRBool closeStreamWhenDone);
|
||||
nsresult Init(nsFileTransportService *aService, const nsACString &name,
|
||||
nsIInputStream *fromStream,
|
||||
const nsACString &contentType,
|
||||
const nsACString &contentCharset,
|
||||
PRInt32 contentLength,
|
||||
PRBool closeStreamWhenDone);
|
||||
nsresult Init(nsFileTransportService *aService,
|
||||
nsIStreamIO* io,
|
||||
PRBool closeStreamWhenDone);
|
||||
|
||||
void Process(nsIProgressEventSink *);
|
||||
void DoClose(void);
|
||||
|
||||
enum XferState {
|
||||
CLOSED,
|
||||
OPEN_FOR_READ,
|
||||
START_READ,
|
||||
READING,
|
||||
END_READ,
|
||||
OPEN_FOR_WRITE,
|
||||
START_WRITE,
|
||||
WRITING,
|
||||
END_WRITE,
|
||||
CLOSING
|
||||
};
|
||||
|
||||
enum RunState {
|
||||
RUNNING,
|
||||
SUSPENDED,
|
||||
CANCELED
|
||||
};
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIProgressEventSink> mProgressSink;
|
||||
nsCOMPtr<nsIInterfaceRequestor> mNotificationCallbacks;
|
||||
nsCOMPtr<nsIStreamIO> mStreamIO;
|
||||
PRUint32 mBufferSegmentSize;
|
||||
PRUint32 mBufferMaxSize;
|
||||
|
||||
nsCOMPtr<nsISupports> mContext;
|
||||
|
||||
// mXferState is only changed by the file transport thread:
|
||||
XferState mXferState;
|
||||
|
||||
// mRunState is only changed by the user's thread, but looked at by the
|
||||
// file transport thread:
|
||||
RunState mRunState;
|
||||
nsresult mCancelStatus;
|
||||
PRInt32 mSuspendCount;
|
||||
PRLock *mLock;
|
||||
|
||||
// The transport is active if it is currently being processed by a thread.
|
||||
PRBool mActive;
|
||||
|
||||
// If FALSE, then the caller can reuse the file transport
|
||||
PRBool mCloseStreamWhenDone;
|
||||
// state variables:
|
||||
nsresult mStatus;
|
||||
PRUint32 mOffset;
|
||||
PRInt32 mTotalAmount;
|
||||
PRInt32 mTransferAmount;
|
||||
|
||||
// reading state variables:
|
||||
nsCOMPtr<nsIStreamListener> mListener;
|
||||
nsFileTransportSourceWrapper *mSourceWrapper;
|
||||
|
||||
// writing state variables:
|
||||
nsCOMPtr<nsIStreamProvider> mProvider;
|
||||
nsCOMPtr<nsIOutputStream> mSink;
|
||||
nsFileTransportSinkWrapper *mSinkWrapper;
|
||||
|
||||
nsCString mStreamName;
|
||||
nsFileTransportService *mService;
|
||||
|
||||
#ifdef TIMING
|
||||
PRIntervalTime mStartTime;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define NS_FILE_TRANSPORT_DEFAULT_SEGMENT_SIZE (4096)
|
||||
#define NS_FILE_TRANSPORT_DEFAULT_BUFFER_SIZE (4*4096) // 16k max
|
||||
|
||||
#endif // nsFileTransport_h__
|
|
@ -122,6 +122,15 @@ nsFileTransportService::GetCachedMimeService()
|
|||
return mMimeService.get();
|
||||
}
|
||||
|
||||
nsIEventQueueService*
|
||||
nsFileTransportService::GetCachedEventQueueService()
|
||||
{
|
||||
if (!mEventQService) {
|
||||
mEventQService = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID);
|
||||
}
|
||||
return mEventQService.get();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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 NPL, 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 NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsFileTransportService_h___
|
||||
#define nsFileTransportService_h___
|
||||
|
||||
#include "nsIFileTransportService.h"
|
||||
#include "nsIThreadPool.h"
|
||||
#include "nsSupportsArray.h"
|
||||
#include "nsIMIMEService.h"
|
||||
|
||||
#define NS_FILE_TRANSPORT_WORKER_COUNT_MIN 1
|
||||
#define NS_FILE_TRANSPORT_WORKER_COUNT_MAX 4//16
|
||||
|
||||
class nsFileTransportService : public nsIFileTransportService
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIFILETRANSPORTSERVICE
|
||||
|
||||
// nsFileTransportService methods:
|
||||
nsFileTransportService();
|
||||
virtual ~nsFileTransportService();
|
||||
|
||||
static NS_METHOD
|
||||
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
|
||||
nsresult Init();
|
||||
|
||||
static nsFileTransportService *GetInstance() { return mInstance; }
|
||||
|
||||
nsIMIMEService* GetCachedMimeService();
|
||||
|
||||
PRInt32 mConnectedTransports;
|
||||
PRInt32 mTotalTransports;
|
||||
PRInt32 mInUseTransports;
|
||||
|
||||
nsresult AddSuspendedTransport(nsITransport* trans);
|
||||
nsresult RemoveSuspendedTransport(nsITransport* trans);
|
||||
|
||||
nsSupportsArray mSuspendedTransportList;
|
||||
|
||||
protected:
|
||||
PRBool mShuttingDown;
|
||||
nsCOMPtr<nsIThreadPool> mPool;
|
||||
PRLock* mLock;
|
||||
nsCOMPtr<nsIMIMEService> mMimeService;
|
||||
static nsFileTransportService* mInstance;
|
||||
};
|
||||
|
||||
#endif /* nsFileTransportService_h___ */
|
|
@ -61,6 +61,7 @@
|
|||
#include "nsITransportSecurityInfo.h"
|
||||
#include "nsMemory.h"
|
||||
#include "nsIProxyInfo.h"
|
||||
#include "nsProxyRelease.h"
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
static PRLogModuleInfo *gSocketTransportLog = nsnull;
|
||||
|
@ -2637,6 +2638,12 @@ nsSocketRequest::SetTransport(nsSocketTransport *aTransport)
|
|||
//
|
||||
NS_IF_RELEASE(mTransport);
|
||||
NS_IF_ADDREF(mTransport = aTransport);
|
||||
|
||||
//
|
||||
// Set the event queue
|
||||
//
|
||||
nsIEventQueueService* eqService = aTransport->mService->GetCachedEventQueueService();
|
||||
eqService->GetSpecialEventQueue(nsIEventQueueService::CURRENT_THREAD_EVENT_QUEUE, getter_AddRefs(mEventQ));
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -2657,9 +2664,21 @@ nsSocketRequest::OnStop()
|
|||
mObserver->OnStartRequest(this, mContext);
|
||||
mStartFired = PR_TRUE;
|
||||
}
|
||||
|
||||
mObserver->OnStopRequest(this, mContext, mStatus);
|
||||
mObserver = 0;
|
||||
mContext = 0;
|
||||
|
||||
if (mContext) {
|
||||
if (mEventQ) {
|
||||
nsISupports* doomed = mContext.get();
|
||||
NS_ADDREF(doomed);
|
||||
mContext = 0;
|
||||
NS_ProxyRelease(mEventQ, doomed);
|
||||
}
|
||||
else {
|
||||
mContext = 0;
|
||||
}
|
||||
}
|
||||
mStopFired = PR_TRUE;
|
||||
}
|
||||
return NS_OK;
|
||||
|
|
|
@ -309,6 +309,8 @@ protected:
|
|||
nsSocketBOS *mBOS; // weak reference
|
||||
nsSocketReadRequest *mReadRequest;
|
||||
nsSocketWriteRequest *mWriteRequest;
|
||||
|
||||
friend nsSocketRequest;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -453,6 +455,8 @@ protected:
|
|||
nsSocketTransport *mTransport;
|
||||
nsCOMPtr<nsIRequestObserver> mObserver;
|
||||
nsCOMPtr<nsISupports> mContext;
|
||||
// Queue where release of context, listener, and/or provider should occur.
|
||||
nsCOMPtr<nsIEventQueue> mEventQ;
|
||||
nsresult mStatus;
|
||||
PRIntn mSuspendCount;
|
||||
PRPackedBool mCanceled;
|
||||
|
|
|
@ -211,6 +211,15 @@ nsSocketTransportService::Init(void)
|
|||
rv = NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (NS_SUCCEEDED(rv) && !mEventQService) {
|
||||
mEventQService = do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID);
|
||||
if (!mEventQService) {
|
||||
rv = NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -791,22 +800,22 @@ nsSocketTransportService::GetNeckoStringByName (const char *aName, PRUnichar **a
|
|||
nsresult res;
|
||||
nsAutoString resultString; resultString.AssignWithConversion(aName);
|
||||
|
||||
if (!m_stringBundle) {
|
||||
if (!mStringBundle) {
|
||||
const char propertyURL[] = NECKO_MSGS_URL;
|
||||
// make sure that we get this service on the UI thread.
|
||||
NS_WITH_PROXIED_SERVICE(nsIStringBundleService, sBundleService, kStringBundleServiceCID,
|
||||
NS_UI_THREAD_EVENTQ, &res);
|
||||
if (NS_SUCCEEDED (res) && (nsnull != sBundleService)) {
|
||||
res = sBundleService->CreateBundle(propertyURL, getter_AddRefs(m_stringBundle));
|
||||
res = sBundleService->CreateBundle(propertyURL, getter_AddRefs(mStringBundle));
|
||||
}
|
||||
}
|
||||
|
||||
if (m_stringBundle)
|
||||
if (mStringBundle)
|
||||
{
|
||||
nsAutoString unicodeName; unicodeName.AssignWithConversion(aName);
|
||||
|
||||
PRUnichar *ptrv = nsnull;
|
||||
res = m_stringBundle->GetStringFromName(unicodeName.get(), &ptrv);
|
||||
res = mStringBundle->GetStringFromName(unicodeName.get(), &ptrv);
|
||||
|
||||
if (NS_FAILED(res))
|
||||
{
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "nsCOMPtr.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsIDNSService.h"
|
||||
#include "nsIEventQueueService.h"
|
||||
|
||||
#if defined(XP_PC) || defined(XP_UNIX) || defined(XP_BEOS) || defined(XP_MAC)
|
||||
//
|
||||
|
@ -99,6 +100,7 @@ public:
|
|||
nsresult GetNeckoStringByName (const char *aName, PRUnichar **aString);
|
||||
|
||||
nsIDNSService* GetCachedDNSService() { return mDNSService.get(); }
|
||||
nsIEventQueueService* GetCachedEventQueueService() { return mEventQService.get(); }
|
||||
|
||||
protected:
|
||||
nsIThread* mThread;
|
||||
|
@ -111,8 +113,9 @@ protected:
|
|||
PRInt32 mSelectFDSetCount;
|
||||
PRPollDesc* mSelectFDSet;
|
||||
nsSocketTransport** mActiveTransportList;
|
||||
nsCOMPtr<nsIStringBundle> m_stringBundle;
|
||||
nsCOMPtr<nsIStringBundle> mStringBundle;
|
||||
nsCOMPtr<nsIDNSService> mDNSService;
|
||||
nsCOMPtr<nsIEventQueueService> mEventQService;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1026,6 +1026,15 @@ nsDNSService::Init()
|
|||
rv = InstallPrefObserver();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// install xpcom shutdown observer
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
do_GetService("@mozilla.org/observer-service;1", &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
||||
mState = DNS_ONLINE;
|
||||
return NS_OK;
|
||||
|
||||
|
@ -1265,6 +1274,13 @@ nsDNSService::Observe(nsISupports * subject,
|
|||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (!nsCRT::strcmp(NS_XPCOM_SHUTDOWN_OBSERVER_ID, topic))
|
||||
{
|
||||
// we need to shutdown!
|
||||
ShutdownInternal();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (nsCRT::strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, topic))
|
||||
return NS_OK;
|
||||
|
||||
|
@ -1302,7 +1318,6 @@ nsDNSService::Observe(nsISupports * subject,
|
|||
mIDNConverter = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -1829,6 +1844,15 @@ nsDNSService::ShutdownInternal()
|
|||
|
||||
(void) RemovePrefObserver();
|
||||
|
||||
|
||||
// remove xpcom shutdown observer
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
do_GetService("@mozilla.org/observer-service;1", &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// reset hashtable
|
||||
// XXX assert hashtable is empty
|
||||
PL_DHashTableFinish(&mHashTable);
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
#
|
||||
# This is a list of local files which get copied to the mozilla:dist directory
|
||||
#
|
||||
|
||||
nsProxyEvent.h
|
||||
nsProxiedService.h
|
|
@ -35,6 +35,7 @@ endif
|
|||
|
||||
EXPORTS = \
|
||||
nsProxyEvent.h \
|
||||
nsProxyRelease.h \
|
||||
nsProxiedService.h \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape 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/NPL/
|
||||
#
|
||||
# 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 Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
||||
DEPTH=..\..\..
|
||||
|
||||
MODULE=xpcom
|
||||
|
||||
EXPORTS = \
|
||||
nsProxyEvent.h \
|
||||
nsProxiedService.h \
|
||||
$(NULL)
|
||||
|
||||
XPIDL_MODULE = proxyObject
|
||||
|
||||
XPIDLSRCS = \
|
||||
.\nsIProxyCreateInstance.idl \
|
||||
.\nsIProxyObjectManager.idl \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
|
@ -50,7 +50,7 @@ static void* PR_CALLBACK
|
|||
ReleaseDestructorEventHandler(PLEvent *self)
|
||||
{
|
||||
nsISupports* owner = (nsISupports*) PL_GetEventOwner(self);
|
||||
NS_DELETEXPCOM(owner);
|
||||
NS_RELEASE(owner);
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
|
@ -60,6 +60,44 @@ ReleaseDestructorDestroyHandler(PLEvent *self)
|
|||
PR_DELETE(self);
|
||||
}
|
||||
|
||||
static void
|
||||
NS_ProxyRelease(nsIEventQueue *eventQ, nsISupports *doomed, PRBool alwaysProxy=PR_FALSE)
|
||||
{
|
||||
if (!doomed)
|
||||
return;
|
||||
|
||||
if (!eventQ) {
|
||||
NS_RELEASE(doomed);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!alwaysProxy) {
|
||||
PRBool onCurrentThread = PR_FALSE;
|
||||
eventQ->IsQueueOnCurrentThread(&onCurrentThread);
|
||||
if (onCurrentThread) {
|
||||
NS_RELEASE(doomed);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
PLEvent *ev = new PLEvent;
|
||||
if (!ev) {
|
||||
NS_ERROR("failed to allocate PLEvent");
|
||||
// we do not release doomed here since it may cause a delete on the the
|
||||
// wrong thread. better to leak than crash.
|
||||
return;
|
||||
}
|
||||
|
||||
PL_InitEvent(ev,
|
||||
(void *) doomed,
|
||||
ReleaseDestructorEventHandler,
|
||||
ReleaseDestructorDestroyHandler);
|
||||
|
||||
PRStatus rv = eventQ->PostEvent(ev);
|
||||
NS_ASSERTION(rv == PR_SUCCESS, "PostEvent failed");
|
||||
}
|
||||
|
||||
|
||||
#define NS_IMPL_PROXY_RELEASE(_class) \
|
||||
NS_IMETHODIMP_(nsrefcnt) _class::Release(void) \
|
||||
{ \
|
||||
|
@ -106,5 +144,7 @@ NS_IMETHODIMP_(nsrefcnt) _class::Release(void)
|
|||
return count; \
|
||||
} \
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче