On x86 compilers without fastcall, simulate it when invoking traces and un-simulate...
[wine-gecko.git] / netwerk / base / src / nsSocketTransport2.h
blobde4133ff467d1daad912e0ce974a17768607b0d1
1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
14 * The Original Code is Mozilla.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 2002
19 * the Initial Developer. All Rights Reserved.
21 * Contributor(s):
22 * Darin Fisher <darin@netscape.com>
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #ifndef nsSocketTransport2_h__
39 #define nsSocketTransport2_h__
41 #ifdef DEBUG_darinf
42 #define ENABLE_SOCKET_TRACING
43 #endif
45 #include "nsSocketTransportService2.h"
46 #include "nsString.h"
47 #include "nsCOMPtr.h"
48 #include "nsInt64.h"
50 #include "nsISocketTransport.h"
51 #include "nsIInterfaceRequestor.h"
52 #include "nsIAsyncInputStream.h"
53 #include "nsIAsyncOutputStream.h"
54 #include "nsIDNSListener.h"
55 #include "nsIDNSRecord.h"
56 #include "nsICancelable.h"
57 #include "nsIClassInfo.h"
59 class nsSocketTransport;
61 //-----------------------------------------------------------------------------
63 // after this short interval, we will return to PR_Poll
64 #define NS_SOCKET_CONNECT_TIMEOUT PR_MillisecondsToInterval(20)
66 //-----------------------------------------------------------------------------
68 class nsSocketInputStream : public nsIAsyncInputStream
70 public:
71 NS_DECL_ISUPPORTS_INHERITED
72 NS_DECL_NSIINPUTSTREAM
73 NS_DECL_NSIASYNCINPUTSTREAM
75 nsSocketInputStream(nsSocketTransport *);
76 virtual ~nsSocketInputStream();
78 PRBool IsReferenced() { return mReaderRefCnt > 0; }
79 nsresult Condition() { return mCondition; }
80 PRUint64 ByteCount() { return mByteCount; }
82 // called by the socket transport on the socket thread...
83 void OnSocketReady(nsresult condition);
85 private:
86 nsSocketTransport *mTransport;
87 nsrefcnt mReaderRefCnt;
89 // access to these is protected by mTransport->mLock
90 nsresult mCondition;
91 nsCOMPtr<nsIInputStreamCallback> mCallback;
92 PRUint32 mCallbackFlags;
93 nsUint64 mByteCount;
96 //-----------------------------------------------------------------------------
98 class nsSocketOutputStream : public nsIAsyncOutputStream
100 public:
101 NS_DECL_ISUPPORTS_INHERITED
102 NS_DECL_NSIOUTPUTSTREAM
103 NS_DECL_NSIASYNCOUTPUTSTREAM
105 nsSocketOutputStream(nsSocketTransport *);
106 virtual ~nsSocketOutputStream();
108 PRBool IsReferenced() { return mWriterRefCnt > 0; }
109 nsresult Condition() { return mCondition; }
110 PRUint64 ByteCount() { return mByteCount; }
112 // called by the socket transport on the socket thread...
113 void OnSocketReady(nsresult condition);
115 private:
116 static NS_METHOD WriteFromSegments(nsIInputStream *, void *,
117 const char *, PRUint32 offset,
118 PRUint32 count, PRUint32 *countRead);
120 nsSocketTransport *mTransport;
121 nsrefcnt mWriterRefCnt;
123 // access to these is protected by mTransport->mLock
124 nsresult mCondition;
125 nsCOMPtr<nsIOutputStreamCallback> mCallback;
126 PRUint32 mCallbackFlags;
127 nsUint64 mByteCount;
130 //-----------------------------------------------------------------------------
132 class nsSocketTransport : public nsASocketHandler
133 , public nsISocketTransport
134 , public nsIDNSListener
135 , public nsIClassInfo
137 public:
138 NS_DECL_ISUPPORTS
139 NS_DECL_NSITRANSPORT
140 NS_DECL_NSISOCKETTRANSPORT
141 NS_DECL_NSIDNSLISTENER
142 NS_DECL_NSICLASSINFO
144 nsSocketTransport();
146 // this method instructs the socket transport to open a socket of the
147 // given type(s) to the given host or proxy.
148 nsresult Init(const char **socketTypes, PRUint32 typeCount,
149 const nsACString &host, PRUint16 port,
150 nsIProxyInfo *proxyInfo);
152 // this method instructs the socket transport to use an already connected
153 // socket with the given address.
154 nsresult InitWithConnectedSocket(PRFileDesc *socketFD,
155 const PRNetAddr *addr);
157 // nsASocketHandler methods:
158 void OnSocketReady(PRFileDesc *, PRInt16 outFlags);
159 void OnSocketDetached(PRFileDesc *);
161 // called when a socket event is handled
162 void OnSocketEvent(PRUint32 type, nsresult status, nsISupports *param);
164 protected:
166 virtual ~nsSocketTransport();
168 private:
170 // event types
171 enum {
172 MSG_ENSURE_CONNECT,
173 MSG_DNS_LOOKUP_COMPLETE,
174 MSG_RETRY_INIT_SOCKET,
175 MSG_TIMEOUT_CHANGED,
176 MSG_INPUT_CLOSED,
177 MSG_INPUT_PENDING,
178 MSG_OUTPUT_CLOSED,
179 MSG_OUTPUT_PENDING
181 nsresult PostEvent(PRUint32 type, nsresult status = NS_OK, nsISupports *param = nsnull);
183 enum {
184 STATE_CLOSED,
185 STATE_IDLE,
186 STATE_RESOLVING,
187 STATE_CONNECTING,
188 STATE_TRANSFERRING
191 //-------------------------------------------------------------------------
192 // these members are "set" at initialization time and are never modified
193 // afterwards. this allows them to be safely accessed from any thread.
194 //-------------------------------------------------------------------------
196 // socket type info:
197 char **mTypes;
198 PRUint32 mTypeCount;
199 nsCString mHost;
200 nsCString mProxyHost;
201 PRUint16 mPort;
202 PRUint16 mProxyPort;
203 PRPackedBool mProxyTransparent;
204 PRPackedBool mProxyTransparentResolvesHost;
206 PRUint16 SocketPort() { return (!mProxyHost.IsEmpty() && !mProxyTransparent) ? mProxyPort : mPort; }
207 const nsCString &SocketHost() { return (!mProxyHost.IsEmpty() && !mProxyTransparent) ? mProxyHost : mHost; }
209 //-------------------------------------------------------------------------
210 // members accessible only on the socket transport thread:
211 // (the exception being initialization/shutdown time)
212 //-------------------------------------------------------------------------
214 // socket state vars:
215 PRUint32 mState; // STATE_??? flags
216 PRPackedBool mAttached;
217 PRPackedBool mInputClosed;
218 PRPackedBool mOutputClosed;
220 // this flag is used to determine if the results of a host lookup arrive
221 // recursively or not. this flag is not protected by any lock.
222 PRPackedBool mResolving;
224 nsCOMPtr<nsICancelable> mDNSRequest;
225 nsCOMPtr<nsIDNSRecord> mDNSRecord;
226 PRNetAddr mNetAddr;
228 // socket methods (these can only be called on the socket thread):
230 void SendStatus(nsresult status);
231 nsresult ResolveHost();
232 nsresult BuildSocket(PRFileDesc *&, PRBool &, PRBool &);
233 nsresult InitiateSocket();
234 PRBool RecoverFromError();
236 void OnMsgInputPending()
238 if (mState == STATE_TRANSFERRING)
239 mPollFlags |= (PR_POLL_READ | PR_POLL_EXCEPT);
241 void OnMsgOutputPending()
243 if (mState == STATE_TRANSFERRING)
244 mPollFlags |= (PR_POLL_WRITE | PR_POLL_EXCEPT);
246 void OnMsgInputClosed(nsresult reason);
247 void OnMsgOutputClosed(nsresult reason);
249 // called when the socket is connected
250 void OnSocketConnected();
252 //-------------------------------------------------------------------------
253 // socket input/output objects. these may be accessed on any thread with
254 // the exception of some specific methods (XXX).
256 PRLock *mLock; // protects members in this section
257 PRFileDesc *mFD;
258 nsrefcnt mFDref; // mFD is closed when mFDref goes to zero.
259 PRBool mFDconnected; // mFD is available to consumer when TRUE.
261 nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
262 nsCOMPtr<nsITransportEventSink> mEventSink;
263 nsCOMPtr<nsISupports> mSecInfo;
265 nsSocketInputStream mInput;
266 nsSocketOutputStream mOutput;
268 friend class nsSocketInputStream;
269 friend class nsSocketOutputStream;
271 // socket timeouts are not protected by any lock.
272 PRUint16 mTimeouts[2];
275 // mFD access methods: called with mLock held.
277 PRFileDesc *GetFD_Locked();
278 void ReleaseFD_Locked(PRFileDesc *fd);
281 // stream state changes (called outside mLock):
283 void OnInputClosed(nsresult reason)
285 // no need to post an event if called on the socket thread
286 if (PR_GetCurrentThread() == gSocketThread)
287 OnMsgInputClosed(reason);
288 else
289 PostEvent(MSG_INPUT_CLOSED, reason);
291 void OnInputPending()
293 // no need to post an event if called on the socket thread
294 if (PR_GetCurrentThread() == gSocketThread)
295 OnMsgInputPending();
296 else
297 PostEvent(MSG_INPUT_PENDING);
299 void OnOutputClosed(nsresult reason)
301 // no need to post an event if called on the socket thread
302 if (PR_GetCurrentThread() == gSocketThread)
303 OnMsgOutputClosed(reason); // XXX need to not be inside lock!
304 else
305 PostEvent(MSG_OUTPUT_CLOSED, reason);
307 void OnOutputPending()
309 // no need to post an event if called on the socket thread
310 if (PR_GetCurrentThread() == gSocketThread)
311 OnMsgOutputPending();
312 else
313 PostEvent(MSG_OUTPUT_PENDING);
316 #ifdef ENABLE_SOCKET_TRACING
317 void TraceInBuf(const char *buf, PRInt32 n);
318 void TraceOutBuf(const char *buf, PRInt32 n);
319 #endif
322 #endif // !nsSocketTransport_h__