Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / netwerk / base / src / nsSocketTransport2.h
blob35efa229a46a33d6dc58b72e7e57bed010b39901
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;
205 PRUint32 mConnectionFlags;
207 PRUint16 SocketPort() { return (!mProxyHost.IsEmpty() && !mProxyTransparent) ? mProxyPort : mPort; }
208 const nsCString &SocketHost() { return (!mProxyHost.IsEmpty() && !mProxyTransparent) ? mProxyHost : mHost; }
210 //-------------------------------------------------------------------------
211 // members accessible only on the socket transport thread:
212 // (the exception being initialization/shutdown time)
213 //-------------------------------------------------------------------------
215 // socket state vars:
216 PRUint32 mState; // STATE_??? flags
217 PRPackedBool mAttached;
218 PRPackedBool mInputClosed;
219 PRPackedBool mOutputClosed;
221 // this flag is used to determine if the results of a host lookup arrive
222 // recursively or not. this flag is not protected by any lock.
223 PRPackedBool mResolving;
225 nsCOMPtr<nsICancelable> mDNSRequest;
226 nsCOMPtr<nsIDNSRecord> mDNSRecord;
227 PRNetAddr mNetAddr;
229 // socket methods (these can only be called on the socket thread):
231 void SendStatus(nsresult status);
232 nsresult ResolveHost();
233 nsresult BuildSocket(PRFileDesc *&, PRBool &, PRBool &);
234 nsresult InitiateSocket();
235 PRBool RecoverFromError();
237 void OnMsgInputPending()
239 if (mState == STATE_TRANSFERRING)
240 mPollFlags |= (PR_POLL_READ | PR_POLL_EXCEPT);
242 void OnMsgOutputPending()
244 if (mState == STATE_TRANSFERRING)
245 mPollFlags |= (PR_POLL_WRITE | PR_POLL_EXCEPT);
247 void OnMsgInputClosed(nsresult reason);
248 void OnMsgOutputClosed(nsresult reason);
250 // called when the socket is connected
251 void OnSocketConnected();
253 //-------------------------------------------------------------------------
254 // socket input/output objects. these may be accessed on any thread with
255 // the exception of some specific methods (XXX).
257 PRLock *mLock; // protects members in this section
258 PRFileDesc *mFD;
259 nsrefcnt mFDref; // mFD is closed when mFDref goes to zero.
260 PRBool mFDconnected; // mFD is available to consumer when TRUE.
262 nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
263 nsCOMPtr<nsITransportEventSink> mEventSink;
264 nsCOMPtr<nsISupports> mSecInfo;
266 nsSocketInputStream mInput;
267 nsSocketOutputStream mOutput;
269 friend class nsSocketInputStream;
270 friend class nsSocketOutputStream;
272 // socket timeouts are not protected by any lock.
273 PRUint16 mTimeouts[2];
276 // mFD access methods: called with mLock held.
278 PRFileDesc *GetFD_Locked();
279 void ReleaseFD_Locked(PRFileDesc *fd);
282 // stream state changes (called outside mLock):
284 void OnInputClosed(nsresult reason)
286 // no need to post an event if called on the socket thread
287 if (PR_GetCurrentThread() == gSocketThread)
288 OnMsgInputClosed(reason);
289 else
290 PostEvent(MSG_INPUT_CLOSED, reason);
292 void OnInputPending()
294 // no need to post an event if called on the socket thread
295 if (PR_GetCurrentThread() == gSocketThread)
296 OnMsgInputPending();
297 else
298 PostEvent(MSG_INPUT_PENDING);
300 void OnOutputClosed(nsresult reason)
302 // no need to post an event if called on the socket thread
303 if (PR_GetCurrentThread() == gSocketThread)
304 OnMsgOutputClosed(reason); // XXX need to not be inside lock!
305 else
306 PostEvent(MSG_OUTPUT_CLOSED, reason);
308 void OnOutputPending()
310 // no need to post an event if called on the socket thread
311 if (PR_GetCurrentThread() == gSocketThread)
312 OnMsgOutputPending();
313 else
314 PostEvent(MSG_OUTPUT_PENDING);
317 #ifdef ENABLE_SOCKET_TRACING
318 void TraceInBuf(const char *buf, PRInt32 n);
319 void TraceOutBuf(const char *buf, PRInt32 n);
320 #endif
323 #endif // !nsSocketTransport_h__