Bug 1747346: SocketTransport2 cleanup r=necko-reviewers,dragana,kershaw

Differential Revision: https://phabricator.services.mozilla.com/D134592
This commit is contained in:
Randell Jesup 2022-01-05 05:04:53 +00:00
parent 7a125de74c
commit 6eab79ab46
3 changed files with 68 additions and 40 deletions

View File

@ -826,7 +826,6 @@ nsresult nsSocketTransport::InitWithName(const char* name, size_t length) {
nsresult nsSocketTransport::InitWithConnectedSocket(PRFileDesc* fd,
const NetAddr* addr) {
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
NS_ASSERTION(!mFD.IsInitialized(), "already initialized");
char buf[kNetAddrMaxCStrBufSize];
addr->ToStringBuffer(buf, sizeof(buf));
@ -851,7 +850,7 @@ nsresult nsSocketTransport::InitWithConnectedSocket(PRFileDesc* fd,
{
MutexAutoLock lock(mLock);
NS_ASSERTION(!mFD.IsInitialized(), "already initialized");
mFD = fd;
mFDref = 1;
mFDconnected = true;
@ -924,6 +923,7 @@ nsresult nsSocketTransport::ResolveHost() {
this, SocketHost().get(), SocketPort(),
mConnectionFlags & nsSocketTransport::BYPASS_CACHE ? " bypass cache" : "",
mProxyTransparentResolvesHost));
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
nsresult rv;
@ -1195,6 +1195,7 @@ nsresult nsSocketTransport::BuildSocket(PRFileDesc*& fd, bool& proxyTransparent,
nsresult nsSocketTransport::InitiateSocket() {
SOCKET_LOG(("nsSocketTransport::InitiateSocket [this=%p]\n", this));
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
nsresult rv;
bool isLocal;
@ -1282,10 +1283,13 @@ nsresult nsSocketTransport::InitiateSocket() {
//
// if we already have a connected socket, then just attach and return.
//
if (mFD.IsInitialized()) {
rv = mSocketTransportService->AttachSocket(mFD, this);
if (NS_SUCCEEDED(rv)) mAttached = true;
return rv;
{
MutexAutoLock lock(mLock);
if (mFD.IsInitialized()) {
rv = mSocketTransportService->AttachSocket(mFD, this);
if (NS_SUCCEEDED(rv)) mAttached = true;
return rv;
}
}
//
@ -1393,19 +1397,21 @@ nsresult nsSocketTransport::InitiateSocket() {
PR_SetSocketOption(fd, &opt);
#endif
// inform socket transport about this newly created socket...
rv = mSocketTransportService->AttachSocket(fd, this);
if (NS_FAILED(rv)) {
CloseSocket(fd,
mSocketTransportService->IsTelemetryEnabledAndNotSleepPhase());
return rv;
}
mAttached = true;
// up to here, mFD will only be accessed by us
// assign mFD so that we can properly handle OnSocketDetached before we've
// established a connection.
{
MutexAutoLock lock(mLock);
// inform socket transport about this newly created socket...
rv = mSocketTransportService->AttachSocket(fd, this);
if (NS_FAILED(rv)) {
CloseSocket(
fd, mSocketTransportService->IsTelemetryEnabledAndNotSleepPhase());
return rv;
}
mAttached = true;
mFD = fd;
mFDref = 1;
mFDconnected = false;
@ -1615,8 +1621,12 @@ bool nsSocketTransport::RecoverFromError() {
nsresult rv;
// OK to check this outside mLock
NS_ASSERTION(!mFDconnected, "socket should not be connected");
#ifdef DEBUG
{
MutexAutoLock lock(mLock);
NS_ASSERTION(!mFDconnected, "socket should not be connected");
}
#endif
// all connection failures need to be reported to DNS so that the next
// time we will use a different address if available.
@ -1904,6 +1914,7 @@ void nsSocketTransport::ReleaseFD_Locked(PRFileDesc* fd) {
void nsSocketTransport::OnSocketEvent(uint32_t type, nsresult status,
nsISupports* param) {
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
SOCKET_LOG(
("nsSocketTransport::OnSocketEvent [this=%p type=%u status=%" PRIx32
" param=%p]\n",
@ -2039,6 +2050,7 @@ void nsSocketTransport::OnSocketEvent(uint32_t type, nsresult status,
// socket handler impl
void nsSocketTransport::OnSocketReady(PRFileDesc* fd, int16_t outFlags) {
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
SOCKET_LOG1(("nsSocketTransport::OnSocketReady [this=%p outFlags=%hd]\n",
this, outFlags));
@ -2539,6 +2551,7 @@ nsSocketTransport::Bind(NetAddr* aLocalAddr) {
NS_ENSURE_ARG(aLocalAddr);
MutexAutoLock lock(mLock);
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
if (mAttached) {
return NS_ERROR_FAILURE;
}

View File

@ -345,11 +345,13 @@ class nsSocketTransport final : public nsASocketHandler,
bool RecoverFromError();
void OnMsgInputPending() {
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
if (mState == STATE_TRANSFERRING) {
mPollFlags |= (PR_POLL_READ | PR_POLL_EXCEPT);
}
}
void OnMsgOutputPending() {
MOZ_ASSERT(OnSocketThread(), "not on socket thread");
if (mState == STATE_TRANSFERRING) {
mPollFlags |= (PR_POLL_WRITE | PR_POLL_EXCEPT);
}

View File

@ -10,6 +10,7 @@
#include "nsIAsyncInputStream.h"
#include "mozilla/net/DNS.h"
#include "prerror.h"
#include "../../base/nsSocketTransportService2.h"
#include "nsComponentManagerUtils.h"
#include "nsServiceManagerUtils.h"
@ -121,46 +122,58 @@ TEST(TestBind, MainTest)
// Client side
//
uint32_t bindingPort = 20000;
nsCOMPtr<nsISocketTransportService> sts =
nsCOMPtr<nsISocketTransportService> service =
do_GetService("@mozilla.org/network/socket-transport-service;1", &rv);
ASSERT_TRUE(NS_SUCCEEDED(rv));
nsCOMPtr<nsIInputStream> inputStream;
RefPtr<ClientInputCallback> clientCallback;
auto* sts = gSocketTransportService;
ASSERT_TRUE(sts);
for (int32_t tried = 0; tried < 100; tried++) {
nsCOMPtr<nsISocketTransport> client;
rv = sts->CreateTransport(nsTArray<nsCString>(), "127.0.0.1"_ns, serverPort,
nullptr, nullptr, getter_AddRefs(client));
ASSERT_TRUE(NS_SUCCEEDED(rv));
sts->Dispatch(
NS_NewRunnableFunction(
"test",
[&]() {
nsCOMPtr<nsISocketTransport> client;
rv = service->CreateTransport(nsTArray<nsCString>(),
"127.0.0.1"_ns, serverPort, nullptr,
nullptr, getter_AddRefs(client));
ASSERT_TRUE(NS_SUCCEEDED(rv));
// Bind to a port. It's possible that we are binding to a port that is
// currently in use. If we failed to bind, we try next port.
NetAddr bindingAddr;
bindingAddr.inet.family = AF_INET;
bindingAddr.inet.ip = 0;
bindingAddr.inet.port = PR_htons(bindingPort);
rv = client->Bind(&bindingAddr);
ASSERT_TRUE(NS_SUCCEEDED(rv));
// Bind to a port. It's possible that we are binding to a port
// that is currently in use. If we failed to bind, we try next
// port.
NetAddr bindingAddr;
bindingAddr.inet.family = AF_INET;
bindingAddr.inet.ip = 0;
bindingAddr.inet.port = PR_htons(bindingPort);
rv = client->Bind(&bindingAddr);
ASSERT_TRUE(NS_SUCCEEDED(rv));
// Open IO streams, to make client SocketTransport connect to server.
clientCallback = new ClientInputCallback(waiter);
rv = client->OpenInputStream(nsITransport::OPEN_UNBUFFERED, 0, 0,
getter_AddRefs(inputStream));
ASSERT_TRUE(NS_SUCCEEDED(rv));
// Open IO streams, to make client SocketTransport connect to
// server.
clientCallback = new ClientInputCallback(waiter);
rv = client->OpenInputStream(nsITransport::OPEN_UNBUFFERED, 0, 0,
getter_AddRefs(inputStream));
ASSERT_TRUE(NS_SUCCEEDED(rv));
nsCOMPtr<nsIAsyncInputStream> asyncInputStream =
do_QueryInterface(inputStream);
rv = asyncInputStream->AsyncWait(clientCallback, 0, 0, nullptr);
nsCOMPtr<nsIAsyncInputStream> asyncInputStream =
do_QueryInterface(inputStream);
rv = asyncInputStream->AsyncWait(clientCallback, 0, 0, nullptr);
}),
NS_DISPATCH_SYNC);
// Wait for server's response or callback of input stream.
waiter->Wait(1);
if (clientCallback->mFailed) {
// if client received error, we likely have bound a port that is in use.
// we can try another port.
// if client received error, we likely have bound a port that is
// in use. we can try another port.
bindingPort++;
} else {
// We are unlocked by server side, leave the loop and check result.
// We are unlocked by server side, leave the loop and check
// result.
break;
}
}