2007-03-22 10:30:00 -07:00
|
|
|
/* ***** 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>
|
|
|
|
*
|
|
|
|
* 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 nsSocketTransport2_h__
|
|
|
|
#define nsSocketTransport2_h__
|
|
|
|
|
|
|
|
#ifdef DEBUG_darinf
|
|
|
|
#define ENABLE_SOCKET_TRACING
|
|
|
|
#endif
|
|
|
|
|
Rollup of bug 645263 and bug 646259: Switch to mozilla:: sync primitives. r=cjones,dbaron,doublec,ehsan src=bsmedberg
Bug 645263, part 0: Count sync primitive ctor/dtors. r=dbaron
Bug 645263, part 1: Migrate content/media to mozilla:: sync primitives. r=doublec
Bug 645263, part 2: Migrate modules/plugin to mozilla:: sync primitives. sr=bsmedberg
Bug 645263, part 3: Migrate nsComponentManagerImpl to mozilla:: sync primitives. sr=bsmedberg
Bug 645263, part 4: Migrate everything else to mozilla:: sync primitives. r=dbaron
Bug 645263, part 5: Remove nsAutoLock.*. sr=bsmedberg
Bug 645263, part 6: Make editor test be nicer to deadlock detector. r=ehsan
Bug 645263, part 7: Disable tracemalloc backtraces for xpcshell tests. r=dbaron
Bug 646259: Fix nsCacheService to use a CondVar for notifying. r=cjones
2011-03-31 21:29:02 -07:00
|
|
|
#include "mozilla/Mutex.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
#include "nsSocketTransportService2.h"
|
|
|
|
#include "nsString.h"
|
|
|
|
#include "nsCOMPtr.h"
|
|
|
|
|
|
|
|
#include "nsISocketTransport.h"
|
|
|
|
#include "nsIInterfaceRequestor.h"
|
|
|
|
#include "nsIAsyncInputStream.h"
|
|
|
|
#include "nsIAsyncOutputStream.h"
|
|
|
|
#include "nsIDNSListener.h"
|
|
|
|
#include "nsIDNSRecord.h"
|
|
|
|
#include "nsICancelable.h"
|
2008-02-21 12:39:20 -08:00
|
|
|
#include "nsIClassInfo.h"
|
2007-03-22 10:30:00 -07:00
|
|
|
|
|
|
|
class nsSocketTransport;
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// after this short interval, we will return to PR_Poll
|
|
|
|
#define NS_SOCKET_CONNECT_TIMEOUT PR_MillisecondsToInterval(20)
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
class nsSocketInputStream : public nsIAsyncInputStream
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
NS_DECL_ISUPPORTS_INHERITED
|
|
|
|
NS_DECL_NSIINPUTSTREAM
|
|
|
|
NS_DECL_NSIASYNCINPUTSTREAM
|
|
|
|
|
|
|
|
nsSocketInputStream(nsSocketTransport *);
|
|
|
|
virtual ~nsSocketInputStream();
|
|
|
|
|
|
|
|
PRBool IsReferenced() { return mReaderRefCnt > 0; }
|
|
|
|
nsresult Condition() { return mCondition; }
|
|
|
|
PRUint64 ByteCount() { return mByteCount; }
|
|
|
|
|
|
|
|
// called by the socket transport on the socket thread...
|
|
|
|
void OnSocketReady(nsresult condition);
|
|
|
|
|
|
|
|
private:
|
|
|
|
nsSocketTransport *mTransport;
|
|
|
|
nsrefcnt mReaderRefCnt;
|
|
|
|
|
|
|
|
// access to these is protected by mTransport->mLock
|
|
|
|
nsresult mCondition;
|
|
|
|
nsCOMPtr<nsIInputStreamCallback> mCallback;
|
|
|
|
PRUint32 mCallbackFlags;
|
2009-08-12 01:51:46 -07:00
|
|
|
PRUint64 mByteCount;
|
2007-03-22 10:30:00 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
class nsSocketOutputStream : public nsIAsyncOutputStream
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
NS_DECL_ISUPPORTS_INHERITED
|
|
|
|
NS_DECL_NSIOUTPUTSTREAM
|
|
|
|
NS_DECL_NSIASYNCOUTPUTSTREAM
|
|
|
|
|
|
|
|
nsSocketOutputStream(nsSocketTransport *);
|
|
|
|
virtual ~nsSocketOutputStream();
|
|
|
|
|
|
|
|
PRBool IsReferenced() { return mWriterRefCnt > 0; }
|
|
|
|
nsresult Condition() { return mCondition; }
|
|
|
|
PRUint64 ByteCount() { return mByteCount; }
|
|
|
|
|
|
|
|
// called by the socket transport on the socket thread...
|
|
|
|
void OnSocketReady(nsresult condition);
|
|
|
|
|
|
|
|
private:
|
|
|
|
static NS_METHOD WriteFromSegments(nsIInputStream *, void *,
|
|
|
|
const char *, PRUint32 offset,
|
|
|
|
PRUint32 count, PRUint32 *countRead);
|
|
|
|
|
|
|
|
nsSocketTransport *mTransport;
|
|
|
|
nsrefcnt mWriterRefCnt;
|
|
|
|
|
|
|
|
// access to these is protected by mTransport->mLock
|
|
|
|
nsresult mCondition;
|
|
|
|
nsCOMPtr<nsIOutputStreamCallback> mCallback;
|
|
|
|
PRUint32 mCallbackFlags;
|
2009-08-12 01:51:46 -07:00
|
|
|
PRUint64 mByteCount;
|
2007-03-22 10:30:00 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
class nsSocketTransport : public nsASocketHandler
|
|
|
|
, public nsISocketTransport
|
|
|
|
, public nsIDNSListener
|
|
|
|
, public nsIClassInfo
|
|
|
|
{
|
Rollup of bug 645263 and bug 646259: Switch to mozilla:: sync primitives. r=cjones,dbaron,doublec,ehsan src=bsmedberg
Bug 645263, part 0: Count sync primitive ctor/dtors. r=dbaron
Bug 645263, part 1: Migrate content/media to mozilla:: sync primitives. r=doublec
Bug 645263, part 2: Migrate modules/plugin to mozilla:: sync primitives. sr=bsmedberg
Bug 645263, part 3: Migrate nsComponentManagerImpl to mozilla:: sync primitives. sr=bsmedberg
Bug 645263, part 4: Migrate everything else to mozilla:: sync primitives. r=dbaron
Bug 645263, part 5: Remove nsAutoLock.*. sr=bsmedberg
Bug 645263, part 6: Make editor test be nicer to deadlock detector. r=ehsan
Bug 645263, part 7: Disable tracemalloc backtraces for xpcshell tests. r=dbaron
Bug 646259: Fix nsCacheService to use a CondVar for notifying. r=cjones
2011-03-31 21:29:02 -07:00
|
|
|
typedef mozilla::Mutex Mutex;
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
public:
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
NS_DECL_NSITRANSPORT
|
|
|
|
NS_DECL_NSISOCKETTRANSPORT
|
|
|
|
NS_DECL_NSIDNSLISTENER
|
|
|
|
NS_DECL_NSICLASSINFO
|
|
|
|
|
|
|
|
nsSocketTransport();
|
|
|
|
|
|
|
|
// this method instructs the socket transport to open a socket of the
|
|
|
|
// given type(s) to the given host or proxy.
|
|
|
|
nsresult Init(const char **socketTypes, PRUint32 typeCount,
|
|
|
|
const nsACString &host, PRUint16 port,
|
|
|
|
nsIProxyInfo *proxyInfo);
|
|
|
|
|
|
|
|
// this method instructs the socket transport to use an already connected
|
|
|
|
// socket with the given address.
|
|
|
|
nsresult InitWithConnectedSocket(PRFileDesc *socketFD,
|
|
|
|
const PRNetAddr *addr);
|
|
|
|
|
|
|
|
// nsASocketHandler methods:
|
|
|
|
void OnSocketReady(PRFileDesc *, PRInt16 outFlags);
|
|
|
|
void OnSocketDetached(PRFileDesc *);
|
|
|
|
|
|
|
|
// called when a socket event is handled
|
|
|
|
void OnSocketEvent(PRUint32 type, nsresult status, nsISupports *param);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
virtual ~nsSocketTransport();
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
// event types
|
|
|
|
enum {
|
|
|
|
MSG_ENSURE_CONNECT,
|
|
|
|
MSG_DNS_LOOKUP_COMPLETE,
|
|
|
|
MSG_RETRY_INIT_SOCKET,
|
|
|
|
MSG_TIMEOUT_CHANGED,
|
|
|
|
MSG_INPUT_CLOSED,
|
|
|
|
MSG_INPUT_PENDING,
|
|
|
|
MSG_OUTPUT_CLOSED,
|
|
|
|
MSG_OUTPUT_PENDING
|
|
|
|
};
|
|
|
|
nsresult PostEvent(PRUint32 type, nsresult status = NS_OK, nsISupports *param = nsnull);
|
|
|
|
|
|
|
|
enum {
|
|
|
|
STATE_CLOSED,
|
|
|
|
STATE_IDLE,
|
|
|
|
STATE_RESOLVING,
|
|
|
|
STATE_CONNECTING,
|
|
|
|
STATE_TRANSFERRING
|
|
|
|
};
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
// these members are "set" at initialization time and are never modified
|
|
|
|
// afterwards. this allows them to be safely accessed from any thread.
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// socket type info:
|
|
|
|
char **mTypes;
|
|
|
|
PRUint32 mTypeCount;
|
|
|
|
nsCString mHost;
|
|
|
|
nsCString mProxyHost;
|
|
|
|
PRUint16 mPort;
|
|
|
|
PRUint16 mProxyPort;
|
|
|
|
PRPackedBool mProxyTransparent;
|
|
|
|
PRPackedBool mProxyTransparentResolvesHost;
|
2008-11-04 08:05:46 -08:00
|
|
|
PRUint32 mConnectionFlags;
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
PRUint16 SocketPort() { return (!mProxyHost.IsEmpty() && !mProxyTransparent) ? mProxyPort : mPort; }
|
|
|
|
const nsCString &SocketHost() { return (!mProxyHost.IsEmpty() && !mProxyTransparent) ? mProxyHost : mHost; }
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
// members accessible only on the socket transport thread:
|
|
|
|
// (the exception being initialization/shutdown time)
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
|
|
|
|
// socket state vars:
|
|
|
|
PRUint32 mState; // STATE_??? flags
|
|
|
|
PRPackedBool mAttached;
|
|
|
|
PRPackedBool mInputClosed;
|
|
|
|
PRPackedBool mOutputClosed;
|
|
|
|
|
|
|
|
// this flag is used to determine if the results of a host lookup arrive
|
|
|
|
// recursively or not. this flag is not protected by any lock.
|
|
|
|
PRPackedBool mResolving;
|
|
|
|
|
|
|
|
nsCOMPtr<nsICancelable> mDNSRequest;
|
|
|
|
nsCOMPtr<nsIDNSRecord> mDNSRecord;
|
|
|
|
PRNetAddr mNetAddr;
|
|
|
|
|
|
|
|
// socket methods (these can only be called on the socket thread):
|
|
|
|
|
|
|
|
void SendStatus(nsresult status);
|
|
|
|
nsresult ResolveHost();
|
|
|
|
nsresult BuildSocket(PRFileDesc *&, PRBool &, PRBool &);
|
|
|
|
nsresult InitiateSocket();
|
|
|
|
PRBool RecoverFromError();
|
|
|
|
|
|
|
|
void OnMsgInputPending()
|
|
|
|
{
|
|
|
|
if (mState == STATE_TRANSFERRING)
|
|
|
|
mPollFlags |= (PR_POLL_READ | PR_POLL_EXCEPT);
|
|
|
|
}
|
|
|
|
void OnMsgOutputPending()
|
|
|
|
{
|
|
|
|
if (mState == STATE_TRANSFERRING)
|
|
|
|
mPollFlags |= (PR_POLL_WRITE | PR_POLL_EXCEPT);
|
|
|
|
}
|
|
|
|
void OnMsgInputClosed(nsresult reason);
|
|
|
|
void OnMsgOutputClosed(nsresult reason);
|
|
|
|
|
|
|
|
// called when the socket is connected
|
|
|
|
void OnSocketConnected();
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
// socket input/output objects. these may be accessed on any thread with
|
|
|
|
// the exception of some specific methods (XXX).
|
|
|
|
|
Rollup of bug 645263 and bug 646259: Switch to mozilla:: sync primitives. r=cjones,dbaron,doublec,ehsan src=bsmedberg
Bug 645263, part 0: Count sync primitive ctor/dtors. r=dbaron
Bug 645263, part 1: Migrate content/media to mozilla:: sync primitives. r=doublec
Bug 645263, part 2: Migrate modules/plugin to mozilla:: sync primitives. sr=bsmedberg
Bug 645263, part 3: Migrate nsComponentManagerImpl to mozilla:: sync primitives. sr=bsmedberg
Bug 645263, part 4: Migrate everything else to mozilla:: sync primitives. r=dbaron
Bug 645263, part 5: Remove nsAutoLock.*. sr=bsmedberg
Bug 645263, part 6: Make editor test be nicer to deadlock detector. r=ehsan
Bug 645263, part 7: Disable tracemalloc backtraces for xpcshell tests. r=dbaron
Bug 646259: Fix nsCacheService to use a CondVar for notifying. r=cjones
2011-03-31 21:29:02 -07:00
|
|
|
Mutex mLock; // protects members in this section
|
2007-03-22 10:30:00 -07:00
|
|
|
PRFileDesc *mFD;
|
|
|
|
nsrefcnt mFDref; // mFD is closed when mFDref goes to zero.
|
|
|
|
PRBool mFDconnected; // mFD is available to consumer when TRUE.
|
|
|
|
|
|
|
|
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
|
|
|
|
nsCOMPtr<nsITransportEventSink> mEventSink;
|
|
|
|
nsCOMPtr<nsISupports> mSecInfo;
|
|
|
|
|
|
|
|
nsSocketInputStream mInput;
|
|
|
|
nsSocketOutputStream mOutput;
|
|
|
|
|
|
|
|
friend class nsSocketInputStream;
|
|
|
|
friend class nsSocketOutputStream;
|
|
|
|
|
|
|
|
// socket timeouts are not protected by any lock.
|
|
|
|
PRUint16 mTimeouts[2];
|
|
|
|
|
2010-06-02 19:25:01 -07:00
|
|
|
// QoS setting for socket
|
|
|
|
PRUint8 mQoSBits;
|
|
|
|
|
2007-03-22 10:30:00 -07:00
|
|
|
//
|
|
|
|
// mFD access methods: called with mLock held.
|
|
|
|
//
|
|
|
|
PRFileDesc *GetFD_Locked();
|
|
|
|
void ReleaseFD_Locked(PRFileDesc *fd);
|
|
|
|
|
|
|
|
//
|
|
|
|
// stream state changes (called outside mLock):
|
|
|
|
//
|
|
|
|
void OnInputClosed(nsresult reason)
|
|
|
|
{
|
|
|
|
// no need to post an event if called on the socket thread
|
|
|
|
if (PR_GetCurrentThread() == gSocketThread)
|
|
|
|
OnMsgInputClosed(reason);
|
|
|
|
else
|
|
|
|
PostEvent(MSG_INPUT_CLOSED, reason);
|
|
|
|
}
|
|
|
|
void OnInputPending()
|
|
|
|
{
|
|
|
|
// no need to post an event if called on the socket thread
|
|
|
|
if (PR_GetCurrentThread() == gSocketThread)
|
|
|
|
OnMsgInputPending();
|
|
|
|
else
|
|
|
|
PostEvent(MSG_INPUT_PENDING);
|
|
|
|
}
|
|
|
|
void OnOutputClosed(nsresult reason)
|
|
|
|
{
|
|
|
|
// no need to post an event if called on the socket thread
|
|
|
|
if (PR_GetCurrentThread() == gSocketThread)
|
|
|
|
OnMsgOutputClosed(reason); // XXX need to not be inside lock!
|
|
|
|
else
|
|
|
|
PostEvent(MSG_OUTPUT_CLOSED, reason);
|
|
|
|
}
|
|
|
|
void OnOutputPending()
|
|
|
|
{
|
|
|
|
// no need to post an event if called on the socket thread
|
|
|
|
if (PR_GetCurrentThread() == gSocketThread)
|
|
|
|
OnMsgOutputPending();
|
|
|
|
else
|
|
|
|
PostEvent(MSG_OUTPUT_PENDING);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef ENABLE_SOCKET_TRACING
|
|
|
|
void TraceInBuf(const char *buf, PRInt32 n);
|
|
|
|
void TraceOutBuf(const char *buf, PRInt32 n);
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif // !nsSocketTransport_h__
|