Adjust transport socket timeout everytime it's getting put back into the

work queue. Fix WinGate crash (32048) by stopping using polable events in case
when creation of pollable event has failed (until nspr finds a real solution).
Fix 36445. Apply slamm's patch to shut off some compiler warnings.
This commit is contained in:
ruslan%netscape.com 2000-04-20 01:10:30 +00:00
parent 93b356c61b
commit e987cc8f7c
6 changed files with 95 additions and 89 deletions

View File

@ -119,6 +119,10 @@ static PRUint32 sTotalTransportsCreated = 0;
static PRUint32 sTotalTransportsDeleted = 0;
nsSocketTransport::nsSocketTransport():
mSocketTimeout (PR_INTERVAL_NO_TIMEOUT),
mSocketConnectTimeout (PR_MillisecondsToInterval (DEFAULT_SOCKET_CONNECT_TIMEOUT_IN_MS)),
mOnStartWriteFired (PR_FALSE),
mOnStartReadFired (PR_FALSE),
mCancelStatus(NS_OK),
mCloseConnectionOnceDone(PR_FALSE),
mCurrentState(eSocketState_Created),
@ -146,12 +150,8 @@ nsSocketTransport::nsSocketTransport():
mWriteBufferLength (0),
mBufferSegmentSize (0),
mBufferMaxSize (0),
mSocketTimeout (PR_INTERVAL_NO_TIMEOUT),
mSocketConnectTimeout (PR_MillisecondsToInterval (DEFAULT_SOCKET_CONNECT_TIMEOUT_IN_MS)),
mWasConnected (PR_FALSE) ,
mIdleTimeoutInSeconds (0),
mOnStartWriteFired (PR_FALSE),
mOnStartReadFired (PR_FALSE)
mWasConnected (PR_FALSE)
{
NS_INIT_REFCNT();
@ -1432,6 +1432,7 @@ nsSocketTransport::Cancel(nsresult status)
// Wake up the transport on the socket transport thread so it can
// be removed from the select list...
//
mLastActiveTime = PR_IntervalNow ();
rv = mService->AddToWorkQ(this);
PR_LOG(gSocketLog, PR_LOG_DEBUG,
@ -1457,6 +1458,7 @@ nsSocketTransport::Suspend(void)
// Only do this the first time a transport is suspended...
//
if (1 == mSuspendCount) {
mLastActiveTime = PR_IntervalNow ();
rv = mService->AddToWorkQ(this);
}
@ -1484,6 +1486,7 @@ nsSocketTransport::Resume(void)
// be resumed...
//
if (0 == mSuspendCount) {
mLastActiveTime = PR_IntervalNow ();
rv = mService->AddToWorkQ(this);
}
} else {
@ -1568,6 +1571,7 @@ nsSocketTransport::OnWrite(nsIPipe* aPipe, PRUint32 aCount)
// Start the crank.
mOperation = eSocketOperation_ReadWrite;
mLastActiveTime = PR_IntervalNow ();
rv = mService->AddToWorkQ(this);
}
}
@ -1598,6 +1602,7 @@ nsSocketTransport::OnEmpty(nsIPipe* aPipe)
if (GetFlag(eSocketRead_Wait)) {
ClearFlag(eSocketRead_Wait);
mSelectFlags |= PR_POLL_READ;
mLastActiveTime = PR_IntervalNow ();
rv = mService->AddToWorkQ(this);
}
}
@ -1693,6 +1698,7 @@ nsSocketTransport::OnStopLookup(nsISupports *aContext,
// Start processing the transport again - if necessary...
if (GetFlag(eSocketDNS_Wait)) {
ClearFlag(eSocketDNS_Wait);
mLastActiveTime = PR_IntervalNow ();
mService->AddToWorkQ(this);
}
@ -1768,6 +1774,7 @@ nsSocketTransport::AsyncOpen(nsIStreamObserver *observer, nsISupports* ctxt)
mOperation = eSocketOperation_Connect;
SetReadType(eSocketRead_None);
mLastActiveTime = PR_IntervalNow ();
rv = mService->AddToWorkQ(this);
}
@ -1827,6 +1834,7 @@ nsSocketTransport::AsyncRead(nsIStreamListener* aListener,
mOperation = eSocketOperation_ReadWrite;
SetReadType(eSocketRead_Async);
mLastActiveTime = PR_IntervalNow ();
rv = mService->AddToWorkQ(this);
}
@ -1900,6 +1908,7 @@ nsSocketTransport::AsyncWrite(nsIInputStream* aFromStream,
mOperation = eSocketOperation_ReadWrite;
SetWriteType(eSocketWrite_Async);
mLastActiveTime = PR_IntervalNow ();
rv = mService->AddToWorkQ(this);
}
@ -1949,6 +1958,7 @@ nsSocketTransport::OpenInputStream(nsIInputStream* *result)
mOperation = eSocketOperation_ReadWrite;
SetReadType(eSocketRead_Sync);
mLastActiveTime = PR_IntervalNow ();
rv = mService->AddToWorkQ(this);
}

View File

@ -40,9 +40,7 @@ nsSocketTransportService::nsSocketTransportService () :
PR_INIT_CLIST(&mWorkQ);
mThread = nsnull;
#ifdef USE_POLLABLE_EVENT
mThreadEvent = nsnull;
#endif /* USE_POLLABLE_EVENT */
mThreadLock = nsnull;
mSelectFDSet = nsnull;
@ -74,12 +72,11 @@ nsSocketTransportService::~nsSocketTransportService()
mActiveTransportList = nsnull;
}
#ifdef USE_POLLABLE_EVENT
if (mThreadEvent) {
if (mThreadEvent)
{
PR_DestroyPollableEvent(mThreadEvent);
mThreadEvent = nsnull;
}
#endif /* USE_POLLABLE_EVENT */
if (mThreadLock) {
PR_DestroyLock(mThreadLock);
@ -139,19 +136,14 @@ nsSocketTransportService::Init(void)
}
}
#ifdef USE_POLLABLE_EVENT
//
// Create the pollable event used to immediately wake up the transport
// thread when it is blocked in PR_Poll(...)
//
if (NS_SUCCEEDED(rv) && !mThreadEvent) {
#ifdef USE_POLLABLE_EVENT
if (NS_SUCCEEDED(rv) && !mThreadEvent)
mThreadEvent = PR_NewPollableEvent();
if (!mThreadEvent) {
rv = NS_ERROR_OUT_OF_MEMORY;
}
}
#endif /* USE_POLLABLE_EVENT */
#endif
//
// Create the synchronization lock for the transport thread...
//
@ -198,14 +190,9 @@ nsresult nsSocketTransportService::AddToWorkQ(nsSocketTransport* aTransport)
// all of the entries at once...
//
if (bFireEvent) {
#ifdef USE_POLLABLE_EVENT
status = PR_SetPollableEvent(mThreadEvent);
#else
//
// Need to break the socket transport thread out of the call to PR_Poll(...)
// since a new transport needs to be processed...
//
#endif /* USE_POLLABLE_EVENT */
if (mThreadEvent)
status = PR_SetPollableEvent(mThreadEvent);
if (PR_FAILURE == status) {
rv = NS_ERROR_FAILURE;
}
@ -363,26 +350,30 @@ NS_IMETHODIMP
nsSocketTransportService::Run(void)
{
PRIntervalTime pollTimeout;
#ifdef USE_POLLABLE_EVENT
//
// Initialize the FDSET used by PR_Poll(...). The first item in the FDSet
// is *always* the pollable event (ie. mThreadEvent).
//
mSelectFDSet[0].fd = mThreadEvent;
mSelectFDSet[0].in_flags = PR_POLL_READ;
mSelectFDSetCount = 1;
pollTimeout = PR_MillisecondsToInterval (DEFAULT_POLL_TIMEOUT_IN_MS);
#else
//
// For now, rather than breaking out of the call to PR_Poll(...) just set
// the time out small enough...
//
// This means that new transports will only be processed once a timeout
// occurs...
//
mSelectFDSetCount = 0;
pollTimeout = PR_MillisecondsToInterval(5);
#endif /* USE_POLLABLE_EVENT */
if (mThreadEvent)
{
//
// Initialize the FDSET used by PR_Poll(...). The first item in the FDSet
// is *always* the pollable event (ie. mThreadEvent).
//
mSelectFDSet[0].fd = mThreadEvent;
mSelectFDSet[0].in_flags = PR_POLL_READ;
mSelectFDSetCount = 1;
pollTimeout = PR_MillisecondsToInterval (DEFAULT_POLL_TIMEOUT_IN_MS);
}
else
{
//
// For now, rather than breaking out of the call to PR_Poll(...) just set
// the time out small enough...
//
// This means that new transports will only be processed once a timeout
// occurs...
//
mSelectFDSetCount = 0;
pollTimeout = PR_MillisecondsToInterval(5);
}
while (mThreadRunning) {
nsresult rv;
@ -437,27 +428,30 @@ nsSocketTransportService::Run(void)
}
}
else {
#ifdef USE_POLLABLE_EVENT
/* Process any pending operations on the mWorkQ... */
NS_ASSERTION(0 == i, "Null transport in active list...");
if (0 == i) {
//
// Clear the pollable event... This call should *never* block since
// PR_Poll(...) said that it had been fired...
//
NS_ASSERTION(!(mSelectFDSet[0].out_flags & PR_POLL_EXCEPT),
if (mThreadEvent)
{
/* Process any pending operations on the mWorkQ... */
NS_ASSERTION(0 == i, "Null transport in active list...");
if (0 == i) {
//
// Clear the pollable event... This call should *never* block since
// PR_Poll(...) said that it had been fired...
//
NS_ASSERTION(!(mSelectFDSet[0].out_flags & PR_POLL_EXCEPT),
"Exception on Pollable event.");
PR_WaitForPollableEvent(mThreadEvent);
PR_WaitForPollableEvent(mThreadEvent);
rv = ProcessWorkQ();
rv = ProcessWorkQ();
}
}
else
{
//
// The pollable event should be the *only* null transport
// in the active transport list.
//
NS_ASSERTION(transport, "Null transport in active list...");
}
#else
//
// The pollable event should be the *only* null transport
// in the active transport list.
//
NS_ASSERTION(transport, "Null transport in active list...");
#endif /* USE_POLLABLE_EVENT */
}
//
// Check to see if the transport has timed out...
@ -478,10 +472,9 @@ nsSocketTransportService::Run(void)
}
} // end-for
#ifndef USE_POLLABLE_EVENT
/* Process any pending operations on the mWorkQ... */
rv = ProcessWorkQ();
#endif /* !USE_POLLABLE_EVENT */
if (!mThreadEvent)
/* Process any pending operations on the mWorkQ... */
rv = ProcessWorkQ();
}
return NS_OK;
@ -582,12 +575,13 @@ nsSocketTransportService::Wakeup (nsIChannel* i_Transport)
AddToWorkQ (transport);
#ifdef USE_POLLABLE_EVENT
PR_SetPollableEvent (mThreadEvent);
#else
if (mThreadEvent)
PR_SetPollableEvent (mThreadEvent);
// else
// XXX/ruslan: normally we would call PR_Interrupt (), but since it did work
// wait till NSPR fixes it one day
#endif
// wait till NSPR fixes it one day
return NS_OK;
}
@ -602,14 +596,15 @@ nsSocketTransportService::Shutdown(void)
// Clear the running flag and wake up the transport thread...
//
mThreadRunning = PR_FALSE;
#ifdef USE_POLLABLE_EVENT
status = PR_SetPollableEvent(mThreadEvent);
// XXX: what should happen if this fails?
NS_ASSERTION(PR_SUCCESS == status, "Unable to wake up the transport thread.");
#else
status = PR_SUCCESS;
#endif /* USE_POLLABLE_EVENT */
if (mThreadEvent)
{
status = PR_SetPollableEvent(mThreadEvent);
// XXX: what should happen if this fails?
NS_ASSERTION(PR_SUCCESS == status, "Unable to wake up the transport thread.");
}
else
status = PR_SUCCESS;
// Wait for the transport thread to exit nsIRunnable::Run()
if (PR_SUCCESS == status) {

View File

@ -81,9 +81,7 @@ public:
protected:
nsIThread* mThread;
#ifdef USE_POLLABLE_EVENT
PRFileDesc* mThreadEvent;
#endif /* USE_POLLABLE_EVENT */
PRLock* mThreadLock;
PRBool mThreadRunning;

View File

@ -49,6 +49,9 @@ CPPSRCS = \
nsHTTPSHandler.cpp \
$(NULL)
install:: $(TARGETS)
$(INSTALL) $(srcdir)/redirect.html $(DIST)/bin/res/errors
EXTRA_DSO_LDOPTS += $(MOZ_COMPONENT_LIBS)
include $(topsrcdir)/config/rules.mk

View File

@ -495,11 +495,11 @@ nsHTTPPipelinedRequest::nsHTTPPipelinedRequest (nsHTTPHandler* i_Handler, const
mBufferSegmentSize (0),
mBufferMaxSize (0),
mMustCommit (PR_FALSE),
mHandler (i_Handler),
mTotalProcessed (0),
mTotalWritten (0),
mListener (nsnull),
mTotalProcessed (0),
mHandler (i_Handler),
mPort (port),
mListener (nsnull),
mOnStopDone (PR_TRUE)
{
NS_INIT_REFCNT ();
@ -795,7 +795,7 @@ nsHTTPPipelinedRequest::OnStopRequest (nsIChannel* channel, nsISupports* i_Conte
nsCOMPtr<nsIStreamListener> consumer;
req -> mConnection -> GetResponseDataListener (getter_AddRefs (consumer));
req -> mConnection -> ResponseCompleted (nsnull, rv, i_Msg);
req -> mConnection -> ResponseCompleted (consumer, rv, i_Msg);
// Notify the HTTPChannel that the request has finished

View File

@ -223,8 +223,8 @@ nsHTTPServerListener::nsHTTPServerListener(nsHTTPChannel* aChannel, nsHTTPHandle
mBodyBytesReceived (0),
mCompressHeaderChecked (PR_FALSE),
mChunkHeaderChecked (PR_FALSE),
mPipelinedRequest (request),
mDataReceived (PR_FALSE)
mDataReceived (PR_FALSE),
mPipelinedRequest (request)
{
nsHTTPRequest * req = nsnull;
mChannel -> mHTTPServerListener = this;
@ -612,7 +612,7 @@ nsHTTPServerListener::OnStopRequest (nsIChannel* channel, nsISupports* i_pContex
// Ignore the return code, since the request is being completed...
//
mHeadersDone = PR_TRUE;
if (mResponse && mResponseDataListener) {
if (mResponse) {
FinishedResponseHeaders();
}
}