Skip to content

Commit dbb8893

Browse files
author
Steve Workman
committed
Bug 504553 - Patch 1 - WebSockets in Workers: Dispatch WebSocketChannel::StartWebsocketConnect to target thread, r=jduell
1 parent c0a0bd1 commit dbb8893

File tree

8 files changed

+118
-42
lines changed

8 files changed

+118
-42
lines changed

content/base/src/WebSocket.cpp

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include "WebSocket.h"
88
#include "mozilla/dom/WebSocketBinding.h"
9+
#include "mozilla/net/WebSocketChannel.h"
910

1011
#include "jsapi.h"
1112
#include "jsfriendapi.h"
@@ -41,7 +42,8 @@
4142
#include "nsContentPolicyUtils.h"
4243
#include "nsWrapperCacheInlines.h"
4344
#include "nsIObserverService.h"
44-
#include "nsIWebSocketChannel.h"
45+
46+
using namespace mozilla::net;
4547

4648
namespace mozilla {
4749
namespace dom {
@@ -1124,19 +1126,12 @@ nsresult
11241126
WebSocket::UpdateURI()
11251127
{
11261128
// Check for Redirections
1127-
nsCOMPtr<nsIURI> uri;
1128-
nsresult rv = mChannel->GetURI(getter_AddRefs(uri));
1129-
NS_ENSURE_SUCCESS(rv, rv);
1129+
nsRefPtr<BaseWebSocketChannel> channel;
1130+
channel = static_cast<BaseWebSocketChannel*>(mChannel.get());
1131+
MOZ_ASSERT(channel);
11301132

1131-
nsAutoCString spec;
1132-
rv = uri->GetSpec(spec);
1133-
NS_ENSURE_SUCCESS(rv, rv);
1134-
CopyUTF8toUTF16(spec, mEffectiveURL);
1135-
1136-
bool isWSS = false;
1137-
rv = uri->SchemeIs("wss", &isWSS);
1138-
NS_ENSURE_SUCCESS(rv, rv);
1139-
mSecure = isWSS ? true : false;
1133+
channel->GetEffectiveURL(mEffectiveURL);
1134+
mSecure = channel->IsEncrypted();
11401135

11411136
return NS_OK;
11421137
}

netwerk/protocol/websocket/BaseWebSocketChannel.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ class BaseWebSocketChannel : public nsIWebSocketChannel,
5353
NS_IMETHOD GetPingTimeout(uint32_t *aSeconds);
5454
NS_IMETHOD SetPingTimeout(uint32_t aSeconds);
5555

56+
// Off main thread URI access.
57+
virtual void GetEffectiveURL(nsAString& aEffectiveURL) const = 0;
58+
virtual bool IsEncrypted() const = 0;
59+
5660
protected:
5761
nsCOMPtr<nsIURI> mOriginalURI;
5862
nsCOMPtr<nsIURI> mURI;

netwerk/protocol/websocket/PWebSocket.ipdl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ parent:
4141

4242
child:
4343
// Forwarded notifications corresponding to the nsIWebSocketListener interface
44-
OnStart(nsCString aProtocol, nsCString aExtensions);
44+
OnStart(nsCString aProtocol, nsCString aExtensions,
45+
nsString aEffectiveURL, bool aEncrypted);
4546
OnStop(nsresult aStatusCode);
4647
OnMessageAvailable(nsCString aMsg);
4748
OnBinaryMessageAvailable(nsCString aMsg);

netwerk/protocol/websocket/WebSocketChannel.cpp

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -208,8 +208,6 @@ class FailDelayManager
208208

209209
void Add(nsCString &address, int32_t port)
210210
{
211-
NS_ABORT_IF_FALSE(NS_IsMainThread(), "not main thread");
212-
213211
if (mDelaysDisabled)
214212
return;
215213

@@ -222,8 +220,6 @@ class FailDelayManager
222220
FailDelay* Lookup(nsCString &address, int32_t port,
223221
uint32_t *outIndex = nullptr)
224222
{
225-
NS_ABORT_IF_FALSE(NS_IsMainThread(), "not main thread");
226-
227223
if (mDelaysDisabled)
228224
return nullptr;
229225

@@ -293,8 +289,6 @@ class FailDelayManager
293289
// battery life than using a periodic timer.
294290
void Remove(nsCString &address, int32_t port)
295291
{
296-
NS_ABORT_IF_FALSE(NS_IsMainThread(), "not main thread");
297-
298292
TimeStamp rightNow = TimeStamp::Now();
299293

300294
// iterate from end, to make deletion indexing easier
@@ -343,7 +337,6 @@ class nsWSAdmissionManager
343337
// delay/queue the connection (returns false)
344338
static void ConditionallyConnect(WebSocketChannel *ws)
345339
{
346-
NS_ABORT_IF_FALSE(NS_IsMainThread(), "not main thread");
347340
NS_ABORT_IF_FALSE(ws->mConnecting == NOT_CONNECTING, "opening state");
348341

349342
StaticMutexAutoLock lock(sLock);
@@ -368,7 +361,6 @@ class nsWSAdmissionManager
368361

369362
static void OnConnected(WebSocketChannel *aChannel)
370363
{
371-
NS_ABORT_IF_FALSE(NS_IsMainThread(), "not main thread");
372364
NS_ABORT_IF_FALSE(aChannel->mConnecting == CONNECTING_IN_PROGRESS,
373365
"Channel completed connect, but not connecting?");
374366

@@ -395,8 +387,6 @@ class nsWSAdmissionManager
395387
// w/o ever successfully creating a connection)
396388
static void OnStopSession(WebSocketChannel *aChannel, nsresult aReason)
397389
{
398-
NS_ABORT_IF_FALSE(NS_IsMainThread(), "not main thread");
399-
400390
StaticMutexAutoLock lock(sLock);
401391
if (!sManager) {
402392
return;
@@ -573,7 +563,7 @@ class CallOnMessageAvailable MOZ_FINAL : public nsIRunnable
573563

574564
NS_IMETHOD Run()
575565
{
576-
MOZ_ASSERT(NS_GetCurrentThread() == mChannel->mTargetThread);
566+
MOZ_ASSERT(mChannel->IsOnTargetThread());
577567

578568
if (mLen < 0)
579569
mChannel->mListener->OnMessageAvailable(mChannel->mContext, mData);
@@ -607,7 +597,7 @@ class CallOnStop MOZ_FINAL : public nsIRunnable
607597

608598
NS_IMETHOD Run()
609599
{
610-
MOZ_ASSERT(NS_GetCurrentThread() == mChannel->mTargetThread);
600+
MOZ_ASSERT(mChannel->IsOnTargetThread());
611601

612602
nsWSAdmissionManager::OnStopSession(mChannel, mReason);
613603

@@ -645,7 +635,7 @@ class CallOnServerClose MOZ_FINAL : public nsIRunnable
645635

646636
NS_IMETHOD Run()
647637
{
648-
MOZ_ASSERT(NS_GetCurrentThread() == mChannel->mTargetThread);
638+
MOZ_ASSERT(mChannel->IsOnTargetThread());
649639

650640
mChannel->mListener->OnServerClose(mChannel->mContext, mCode, mReason);
651641
return NS_OK;
@@ -676,7 +666,7 @@ class CallAcknowledge MOZ_FINAL : public nsIRunnable
676666

677667
NS_IMETHOD Run()
678668
{
679-
MOZ_ASSERT(NS_GetCurrentThread() == mChannel->mTargetThread);
669+
MOZ_ASSERT(mChannel->IsOnTargetThread());
680670

681671
LOG(("WebSocketChannel::CallAcknowledge: Size %u\n", mSize));
682672
mChannel->mListener->OnAcknowledge(mChannel->mContext, mSize);
@@ -1178,6 +1168,28 @@ WebSocketChannel::Shutdown()
11781168
nsWSAdmissionManager::Shutdown();
11791169
}
11801170

1171+
bool
1172+
WebSocketChannel::IsOnTargetThread()
1173+
{
1174+
MOZ_ASSERT(mTargetThread);
1175+
bool isOnTargetThread = false;
1176+
nsresult rv = mTargetThread->IsOnCurrentThread(&isOnTargetThread);
1177+
MOZ_ASSERT(NS_SUCCEEDED(rv));
1178+
return NS_FAILED(rv) ? false : isOnTargetThread;
1179+
}
1180+
1181+
void
1182+
WebSocketChannel::GetEffectiveURL(nsAString& aEffectiveURL) const
1183+
{
1184+
aEffectiveURL = mEffectiveURL;
1185+
}
1186+
1187+
bool
1188+
WebSocketChannel::IsEncrypted() const
1189+
{
1190+
return mEncrypted;
1191+
}
1192+
11811193
void
11821194
WebSocketChannel::BeginOpen()
11831195
{
@@ -2372,6 +2384,12 @@ WebSocketChannel::ApplyForAdmission()
23722384
nsresult
23732385
WebSocketChannel::StartWebsocketData()
23742386
{
2387+
if (!IsOnTargetThread()) {
2388+
return mTargetThread->Dispatch(
2389+
NS_NewRunnableMethod(this, &WebSocketChannel::StartWebsocketData),
2390+
NS_DISPATCH_NORMAL);
2391+
}
2392+
23752393
LOG(("WebSocketChannel::StartWebsocketData() %p", this));
23762394
NS_ABORT_IF_FALSE(!mDataStarted, "StartWebsocketData twice");
23772395
mDataStarted = 1;
@@ -2384,8 +2402,9 @@ WebSocketChannel::StartWebsocketData()
23842402
LOG(("WebSocketChannel::StartWebsocketData Notifying Listener %p\n",
23852403
mListener.get()));
23862404

2387-
if (mListener)
2405+
if (mListener) {
23882406
mListener->OnStart(mContext);
2407+
}
23892408

23902409
// Start keepalive ping timer, if we're using keepalive.
23912410
if (mPingInterval) {
@@ -2974,7 +2993,7 @@ nsresult
29742993
WebSocketChannel::SendMsgCommon(const nsACString *aMsg, bool aIsBinary,
29752994
uint32_t aLength, nsIInputStream *aStream)
29762995
{
2977-
NS_ABORT_IF_FALSE(NS_GetCurrentThread() == mTargetThread, "not target thread");
2996+
NS_ABORT_IF_FALSE(IsOnTargetThread(), "not target thread");
29782997

29792998
if (mRequestedClose) {
29802999
LOG(("WebSocketChannel:: Error: send when closed\n"));
@@ -3190,6 +3209,13 @@ WebSocketChannel::OnStartRequest(nsIRequest *aRequest,
31903209
if (NS_FAILED(rv))
31913210
return rv;
31923211

3212+
// Update mEffectiveURL for off main thread URI access.
3213+
nsCOMPtr<nsIURI> uri = mURI ? mURI : mOriginalURI;
3214+
nsAutoCString spec;
3215+
rv = uri->GetSpec(spec);
3216+
MOZ_ASSERT(NS_SUCCEEDED(rv));
3217+
CopyUTF8toUTF16(spec, mEffectiveURL);
3218+
31933219
mGotUpgradeOK = 1;
31943220
if (mRecvdHttpUpgradeTransport)
31953221
return StartWebsocketData();

netwerk/protocol/websocket/WebSocketChannel.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "nsIProtocolProxyCallback.h"
1919
#include "nsIChannelEventSink.h"
2020
#include "nsIHttpChannelInternal.h"
21+
#include "nsIStringStream.h"
2122
#include "BaseWebSocketChannel.h"
2223

2324
#ifdef MOZ_WIDGET_GONK
@@ -96,6 +97,11 @@ class WebSocketChannel : public BaseWebSocketChannel,
9697

9798
WebSocketChannel();
9899
static void Shutdown();
100+
bool IsOnTargetThread();
101+
102+
// Off main thread URI access.
103+
void GetEffectiveURL(nsAString& aEffectiveURL) const MOZ_OVERRIDE;
104+
bool IsEncrypted() const MOZ_OVERRIDE;
99105

100106
enum {
101107
// Non Control Frames
@@ -185,6 +191,7 @@ class WebSocketChannel : public BaseWebSocketChannel,
185191

186192
// Used for off main thread access to the URI string.
187193
nsCString mHost;
194+
nsString mEffectiveURL;
188195

189196
nsCOMPtr<nsISocketTransport> mTransport;
190197
nsCOMPtr<nsIAsyncInputStream> mSocketIn;

netwerk/protocol/websocket/WebSocketChannelChild.cpp

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,13 @@ NS_INTERFACE_MAP_BEGIN(WebSocketChannelChild)
4949
NS_INTERFACE_MAP_ENTRY(nsIThreadRetargetableRequest)
5050
NS_INTERFACE_MAP_END
5151

52-
WebSocketChannelChild::WebSocketChannelChild(bool aSecure)
52+
WebSocketChannelChild::WebSocketChannelChild(bool aEncrypted)
5353
: mIPCOpen(false)
5454
{
5555
NS_ABORT_IF_FALSE(NS_IsMainThread(), "not main thread");
5656

5757
LOG(("WebSocketChannelChild::WebSocketChannelChild() %p\n", this));
58-
BaseWebSocketChannel::mEncrypted = aSecure;
58+
mEncrypted = aEncrypted;
5959
mEventQ = new ChannelEventQueue(static_cast<nsIWebSocketChannel*>(this));
6060
}
6161

@@ -80,6 +80,18 @@ WebSocketChannelChild::ReleaseIPDLReference()
8080
Release();
8181
}
8282

83+
void
84+
WebSocketChannelChild::GetEffectiveURL(nsAString& aEffectiveURL) const
85+
{
86+
aEffectiveURL = mEffectiveURL;
87+
}
88+
89+
bool
90+
WebSocketChannelChild::IsEncrypted() const
91+
{
92+
return mEncrypted;
93+
}
94+
8395
class WrappedChannelEvent : public nsRunnable
8496
{
8597
public:
@@ -113,43 +125,57 @@ class StartEvent : public ChannelEvent
113125
public:
114126
StartEvent(WebSocketChannelChild* aChild,
115127
const nsCString& aProtocol,
116-
const nsCString& aExtensions)
128+
const nsCString& aExtensions,
129+
const nsString& aEffectiveURL,
130+
bool aEncrypted)
117131
: mChild(aChild)
118132
, mProtocol(aProtocol)
119133
, mExtensions(aExtensions)
134+
, mEffectiveURL(aEffectiveURL)
135+
, mEncrypted(aEncrypted)
120136
{}
121137

122138
void Run()
123139
{
124-
mChild->OnStart(mProtocol, mExtensions);
140+
mChild->OnStart(mProtocol, mExtensions, mEffectiveURL, mEncrypted);
125141
}
126142
private:
127143
WebSocketChannelChild* mChild;
128144
nsCString mProtocol;
129145
nsCString mExtensions;
146+
nsString mEffectiveURL;
147+
bool mEncrypted;
130148
};
131149

132150
bool
133151
WebSocketChannelChild::RecvOnStart(const nsCString& aProtocol,
134-
const nsCString& aExtensions)
152+
const nsCString& aExtensions,
153+
const nsString& aEffectiveURL,
154+
const bool& aEncrypted)
135155
{
136156
if (mEventQ->ShouldEnqueue()) {
137-
mEventQ->Enqueue(new StartEvent(this, aProtocol, aExtensions));
157+
mEventQ->Enqueue(new StartEvent(this, aProtocol, aExtensions,
158+
aEffectiveURL, aEncrypted));
138159
} else if (mTargetThread) {
139-
DispatchToTargetThread(new StartEvent(this, aProtocol, aExtensions));
160+
DispatchToTargetThread(new StartEvent(this, aProtocol, aExtensions,
161+
aEffectiveURL, aEncrypted));
140162
} else {
141-
OnStart(aProtocol, aExtensions);
163+
OnStart(aProtocol, aExtensions, aEffectiveURL, aEncrypted);
142164
}
143165
return true;
144166
}
145167

146168
void
147169
WebSocketChannelChild::OnStart(const nsCString& aProtocol,
148-
const nsCString& aExtensions)
170+
const nsCString& aExtensions,
171+
const nsString& aEffectiveURL,
172+
const bool& aEncrypted)
149173
{
150174
LOG(("WebSocketChannelChild::RecvOnStart() %p\n", this));
151175
SetProtocol(aProtocol);
152176
mNegotiatedExtensions = aExtensions;
177+
mEffectiveURL = aEffectiveURL;
178+
mEncrypted = aEncrypted;
153179

154180
if (mListener) {
155181
AutoEventEnqueuer ensureSerialDispatch(mEventQ);;

netwerk/protocol/websocket/WebSocketChannelChild.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,23 @@ class WebSocketChannelChild : public BaseWebSocketChannel,
4040
void AddIPDLReference();
4141
void ReleaseIPDLReference();
4242

43+
// Off main thread URI access.
44+
void GetEffectiveURL(nsAString& aEffectiveURL) const MOZ_OVERRIDE;
45+
bool IsEncrypted() const MOZ_OVERRIDE;
46+
4347
private:
4448
~WebSocketChannelChild();
4549

46-
bool RecvOnStart(const nsCString& aProtocol, const nsCString& aExtensions) MOZ_OVERRIDE;
50+
bool RecvOnStart(const nsCString& aProtocol, const nsCString& aExtensions,
51+
const nsString& aEffectiveURL, const bool& aSecure) MOZ_OVERRIDE;
4752
bool RecvOnStop(const nsresult& aStatusCode) MOZ_OVERRIDE;
4853
bool RecvOnMessageAvailable(const nsCString& aMsg) MOZ_OVERRIDE;
4954
bool RecvOnBinaryMessageAvailable(const nsCString& aMsg) MOZ_OVERRIDE;
5055
bool RecvOnAcknowledge(const uint32_t& aSize) MOZ_OVERRIDE;
5156
bool RecvOnServerClose(const uint16_t& aCode, const nsCString &aReason) MOZ_OVERRIDE;
5257

53-
void OnStart(const nsCString& aProtocol, const nsCString& aExtensions);
58+
void OnStart(const nsCString& aProtocol, const nsCString& aExtensions,
59+
const nsString& aEffectiveURL, const bool& aSecure);
5460
void OnStop(const nsresult& aStatusCode);
5561
void OnMessageAvailable(const nsCString& aMsg);
5662
void OnBinaryMessageAvailable(const nsCString& aMsg);
@@ -62,6 +68,7 @@ class WebSocketChannelChild : public BaseWebSocketChannel,
6268
bool IsOnTargetThread();
6369

6470
nsRefPtr<ChannelEventQueue> mEventQ;
71+
nsString mEffectiveURL;
6572
bool mIPCOpen;
6673

6774
friend class StartEvent;

0 commit comments

Comments
 (0)