Bug 855453 - Move UnixSocket connect delay to main thread cancelable task; r=mrbkap

--HG--
extra : rebase_source : 1df9805896c85f0a97d42b74334a62b7b9baab68
This commit is contained in:
Kyle Machulis 2013-04-01 17:26:25 -07:00
Родитель 04b76dcb47
Коммит d7f9476df4
1 изменённых файлов: 61 добавлений и 8 удалений

Просмотреть файл

@ -50,6 +50,7 @@ public:
, mConnector(aConnector) , mConnector(aConnector)
, mShuttingDownOnIOThread(false) , mShuttingDownOnIOThread(false)
, mAddress(aAddress) , mAddress(aAddress)
, mDelayedConnectTask(nullptr)
{ {
} }
@ -111,6 +112,28 @@ public:
this); this);
} }
void SetDelayedConnectTask(CancelableTask* aTask)
{
MOZ_ASSERT(NS_IsMainThread());
mDelayedConnectTask = aTask;
}
void ClearDelayedConnectTask()
{
MOZ_ASSERT(NS_IsMainThread());
mDelayedConnectTask = nullptr;
}
void CancelDelayedConnectTask()
{
MOZ_ASSERT(NS_IsMainThread());
if (!mDelayedConnectTask) {
return;
}
mDelayedConnectTask->Cancel();
ClearDelayedConnectTask();
}
/** /**
* Connect to a socket * Connect to a socket
*/ */
@ -135,8 +158,7 @@ public:
void GetSocketAddr(nsAString& aAddrStr) void GetSocketAddr(nsAString& aAddrStr)
{ {
if (!mConnector) if (!mConnector) {
{
NS_WARNING("No connector to get socket address from!"); NS_WARNING("No connector to get socket address from!");
aAddrStr.Truncate(); aAddrStr.Truncate();
return; return;
@ -219,6 +241,11 @@ private:
* Address struct of the socket currently in use * Address struct of the socket currently in use
*/ */
sockaddr_any mAddr; sockaddr_any mAddr;
/**
* Task member for delayed connect task. Should only be access on main thread.
*/
CancelableTask* mDelayedConnectTask;
}; };
template<class T> template<class T>
@ -294,7 +321,7 @@ public:
NS_IMETHOD Run() NS_IMETHOD Run()
{ {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
if(mImpl->IsShutdownOnMainThread()) { if (mImpl->IsShutdownOnMainThread()) {
NS_WARNING("mConsumer is null, aborting receive!"); NS_WARNING("mConsumer is null, aborting receive!");
// Since we've already explicitly closed and the close happened before // Since we've already explicitly closed and the close happened before
// this, this isn't really an error. Since we've warned, return OK. // this, this isn't really an error. Since we've warned, return OK.
@ -404,6 +431,30 @@ void SocketConnectTask::Run()
mImpl->Connect(); mImpl->Connect();
} }
class SocketDelayedConnectTask : public CancelableTask {
virtual void Run();
UnixSocketImpl* mImpl;
public:
SocketDelayedConnectTask(UnixSocketImpl* aImpl) : mImpl(aImpl) { }
virtual void Cancel()
{
MOZ_ASSERT(NS_IsMainThread());
mImpl = nullptr;
}
};
void SocketDelayedConnectTask::Run()
{
MOZ_ASSERT(NS_IsMainThread());
if (!mImpl || mImpl->IsShutdownOnMainThread()) {
return;
}
mImpl->ClearDelayedConnectTask();
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new SocketConnectTask(mImpl));
}
class ShutdownSocketTask : public Task { class ShutdownSocketTask : public Task {
virtual void Run(); virtual void Run();
@ -446,8 +497,7 @@ UnixSocketImpl::Accept()
return; return;
} }
if (mFd.get() < 0) if (mFd.get() < 0) {
{
mFd = mConnector->Create(); mFd = mConnector->Create();
if (mFd.get() < 0) { if (mFd.get() < 0) {
return; return;
@ -486,8 +536,7 @@ UnixSocketImpl::Connect()
return; return;
} }
if(mFd.get() < 0) if (mFd.get() < 0) {
{
mFd = mConnector->Create(); mFd = mConnector->Create();
if (mFd.get() < 0) { if (mFd.get() < 0) {
return; return;
@ -601,6 +650,8 @@ UnixSocketConsumer::CloseSocket()
return; return;
} }
mImpl->CancelDelayedConnectTask();
// From this point on, we consider mImpl as being deleted. // From this point on, we consider mImpl as being deleted.
// We sever the relationship here so any future calls to listen or connect // We sever the relationship here so any future calls to listen or connect
// will create a new implementation. // will create a new implementation.
@ -799,7 +850,9 @@ UnixSocketConsumer::ConnectSocket(UnixSocketConnector* aConnector,
MessageLoop* ioLoop = XRE_GetIOMessageLoop(); MessageLoop* ioLoop = XRE_GetIOMessageLoop();
mConnectionStatus = SOCKET_CONNECTING; mConnectionStatus = SOCKET_CONNECTING;
if (aDelayMs > 0) { if (aDelayMs > 0) {
ioLoop->PostDelayedTask(FROM_HERE, new SocketConnectTask(mImpl), aDelayMs); SocketDelayedConnectTask* connectTask = new SocketDelayedConnectTask(mImpl);
mImpl->SetDelayedConnectTask(connectTask);
MessageLoop::current()->PostDelayedTask(FROM_HERE, connectTask, aDelayMs);
} else { } else {
ioLoop->PostTask(FROM_HERE, new SocketConnectTask(mImpl)); ioLoop->PostTask(FROM_HERE, new SocketConnectTask(mImpl));
} }