mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1046109: Add |SocketConsumerBase| and inherit |UnixSocketConsumer| from it, r=kyle
|SocketConsumerBase| handles connection state for |UnixSocketConsumer| and its derived classes. Implementing classes must override a number of virtual methods, to handle notifications about changes to the state of the connection.
This commit is contained in:
parent
77bedcaebb
commit
cf5074b5c5
126
ipc/unixsocket/SocketBase.cpp
Normal file
126
ipc/unixsocket/SocketBase.cpp
Normal file
@ -0,0 +1,126 @@
|
||||
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "SocketBase.h"
|
||||
#include <string.h>
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
//
|
||||
// UnixSocketRawData
|
||||
//
|
||||
|
||||
UnixSocketRawData::UnixSocketRawData(size_t aSize)
|
||||
: mSize(aSize)
|
||||
, mCurrentWriteOffset(0)
|
||||
{
|
||||
mData = new uint8_t[mSize];
|
||||
}
|
||||
|
||||
UnixSocketRawData::UnixSocketRawData(const void* aData, size_t aSize)
|
||||
: mSize(aSize)
|
||||
, mCurrentWriteOffset(0)
|
||||
{
|
||||
MOZ_ASSERT(aData || !mSize);
|
||||
|
||||
mData = new uint8_t[mSize];
|
||||
memcpy(mData, aData, mSize);
|
||||
}
|
||||
|
||||
//
|
||||
// SocketConsumerBase
|
||||
//
|
||||
|
||||
SocketConsumerBase::~SocketConsumerBase()
|
||||
{
|
||||
MOZ_ASSERT(mConnectionStatus == SOCKET_DISCONNECTED);
|
||||
}
|
||||
|
||||
SocketConnectionStatus
|
||||
SocketConsumerBase::GetConnectionStatus() const
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
return mConnectionStatus;
|
||||
}
|
||||
|
||||
int
|
||||
SocketConsumerBase::GetSuggestedConnectDelayMs() const
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
return mConnectDelayMs;
|
||||
}
|
||||
|
||||
void
|
||||
SocketConsumerBase::NotifySuccess()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mConnectionStatus = SOCKET_CONNECTED;
|
||||
mConnectTimestamp = PR_IntervalNow();
|
||||
OnConnectSuccess();
|
||||
}
|
||||
|
||||
void
|
||||
SocketConsumerBase::NotifyError()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mConnectionStatus = SOCKET_DISCONNECTED;
|
||||
mConnectDelayMs = CalculateConnectDelayMs();
|
||||
OnConnectError();
|
||||
}
|
||||
|
||||
void
|
||||
SocketConsumerBase::NotifyDisconnect()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mConnectionStatus = SOCKET_DISCONNECTED;
|
||||
mConnectDelayMs = CalculateConnectDelayMs();
|
||||
OnDisconnect();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SocketConsumerBase::CalculateConnectDelayMs() const
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
uint32_t connectDelayMs = mConnectDelayMs;
|
||||
|
||||
if ((PR_IntervalNow()-mConnectTimestamp) > connectDelayMs) {
|
||||
// reset delay if connection has been opened for a while, or...
|
||||
connectDelayMs = 0;
|
||||
} else if (!connectDelayMs) {
|
||||
// ...start with a delay of ~1 sec, or...
|
||||
connectDelayMs = 1<<10;
|
||||
} else if (connectDelayMs < (1<<16)) {
|
||||
// ...otherwise increase delay by a factor of 2
|
||||
connectDelayMs <<= 1;
|
||||
}
|
||||
return connectDelayMs;
|
||||
}
|
||||
|
||||
SocketConsumerBase::SocketConsumerBase()
|
||||
: mConnectionStatus(SOCKET_DISCONNECTED)
|
||||
, mConnectTimestamp(0)
|
||||
, mConnectDelayMs(0)
|
||||
{ }
|
||||
|
||||
void
|
||||
SocketConsumerBase::SetConnectionStatus(
|
||||
SocketConnectionStatus aConnectionStatus)
|
||||
{
|
||||
mConnectionStatus = aConnectionStatus;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
135
ipc/unixsocket/SocketBase.h
Normal file
135
ipc/unixsocket/SocketBase.h
Normal file
@ -0,0 +1,135 @@
|
||||
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef mozilla_ipc_SocketBase_h
|
||||
#define mozilla_ipc_SocketBase_h
|
||||
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
//
|
||||
// UnixSocketRawData
|
||||
//
|
||||
|
||||
class UnixSocketRawData
|
||||
{
|
||||
public:
|
||||
// Number of octets in mData.
|
||||
size_t mSize;
|
||||
size_t mCurrentWriteOffset;
|
||||
nsAutoArrayPtr<uint8_t> mData;
|
||||
|
||||
/**
|
||||
* Constructor for situations where only size is known beforehand
|
||||
* (for example, when being assigned strings)
|
||||
*/
|
||||
UnixSocketRawData(size_t aSize);
|
||||
|
||||
/**
|
||||
* Constructor for situations where size and data is known
|
||||
* beforehand (for example, when being assigned strings)
|
||||
*/
|
||||
UnixSocketRawData(const void* aData, size_t aSize);
|
||||
};
|
||||
|
||||
enum SocketConnectionStatus {
|
||||
SOCKET_DISCONNECTED = 0,
|
||||
SOCKET_LISTENING = 1,
|
||||
SOCKET_CONNECTING = 2,
|
||||
SOCKET_CONNECTED = 3
|
||||
};
|
||||
|
||||
//
|
||||
// SocketConsumerBase
|
||||
//
|
||||
|
||||
class SocketConsumerBase
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SocketConsumerBase)
|
||||
|
||||
virtual ~SocketConsumerBase();
|
||||
|
||||
SocketConnectionStatus GetConnectionStatus() const;
|
||||
|
||||
int GetSuggestedConnectDelayMs() const;
|
||||
|
||||
/**
|
||||
* Queues the internal representation of socket for deletion. Can be called
|
||||
* from main thread.
|
||||
*/
|
||||
virtual void CloseSocket() = 0;
|
||||
|
||||
/**
|
||||
* Function to be called whenever data is received. This is only called on the
|
||||
* main thread.
|
||||
*
|
||||
* @param aMessage Data received from the socket.
|
||||
*/
|
||||
virtual void ReceiveSocketData(nsAutoPtr<UnixSocketRawData>& aMessage) = 0;
|
||||
|
||||
/**
|
||||
* Queue data to be sent to the socket on the IO thread. Can only be called on
|
||||
* originating thread.
|
||||
*
|
||||
* @param aMessage Data to be sent to socket
|
||||
*
|
||||
* @return true if data is queued, false otherwise (i.e. not connected)
|
||||
*/
|
||||
virtual bool SendSocketData(UnixSocketRawData* aMessage) = 0;
|
||||
|
||||
/**
|
||||
* Callback for socket connect/accept success. Called after connect/accept has
|
||||
* finished. Will be run on main thread, before any reads take place.
|
||||
*/
|
||||
virtual void OnConnectSuccess() = 0;
|
||||
|
||||
/**
|
||||
* Callback for socket connect/accept error. Will be run on main thread.
|
||||
*/
|
||||
virtual void OnConnectError() = 0;
|
||||
|
||||
/**
|
||||
* Callback for socket disconnect. Will be run on main thread.
|
||||
*/
|
||||
virtual void OnDisconnect() = 0;
|
||||
|
||||
/**
|
||||
* Called by implementation to notify consumer of success.
|
||||
*/
|
||||
void NotifySuccess();
|
||||
|
||||
/**
|
||||
* Called by implementation to notify consumer of error.
|
||||
*/
|
||||
void NotifyError();
|
||||
|
||||
/**
|
||||
* Called by implementation to notify consumer of disconnect.
|
||||
*/
|
||||
void NotifyDisconnect();
|
||||
|
||||
protected:
|
||||
SocketConsumerBase();
|
||||
|
||||
void SetConnectionStatus(SocketConnectionStatus aConnectionStatus);
|
||||
|
||||
private:
|
||||
uint32_t CalculateConnectDelayMs() const;
|
||||
|
||||
SocketConnectionStatus mConnectionStatus;
|
||||
PRIntervalTime mConnectTimestamp;
|
||||
uint32_t mConnectDelayMs;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -19,6 +19,10 @@ static const size_t MAX_READ_SIZE = 1 << 16;
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
//
|
||||
// UnixSocketImpl
|
||||
//
|
||||
|
||||
class UnixSocketImpl : public UnixSocketWatcher
|
||||
{
|
||||
public:
|
||||
@ -740,16 +744,16 @@ UnixSocketImpl::OnSocketCanSendWithoutBlocking()
|
||||
}
|
||||
}
|
||||
|
||||
UnixSocketConsumer::UnixSocketConsumer() : mImpl(nullptr)
|
||||
, mConnectionStatus(SOCKET_DISCONNECTED)
|
||||
, mConnectTimestamp(0)
|
||||
, mConnectDelayMs(0)
|
||||
{
|
||||
}
|
||||
//
|
||||
// UnixSocketConsumer
|
||||
//
|
||||
|
||||
UnixSocketConsumer::UnixSocketConsumer()
|
||||
: mImpl(nullptr)
|
||||
{ }
|
||||
|
||||
UnixSocketConsumer::~UnixSocketConsumer()
|
||||
{
|
||||
MOZ_ASSERT(mConnectionStatus == SOCKET_DISCONNECTED);
|
||||
MOZ_ASSERT(!mImpl);
|
||||
}
|
||||
|
||||
@ -813,40 +817,13 @@ void
|
||||
UnixSocketConsumer::GetSocketAddr(nsAString& aAddrStr)
|
||||
{
|
||||
aAddrStr.Truncate();
|
||||
if (!mImpl || mConnectionStatus != SOCKET_CONNECTED) {
|
||||
if (!mImpl || GetConnectionStatus() != SOCKET_CONNECTED) {
|
||||
NS_WARNING("No socket currently open!");
|
||||
return;
|
||||
}
|
||||
mImpl->GetSocketAddr(aAddrStr);
|
||||
}
|
||||
|
||||
void
|
||||
UnixSocketConsumer::NotifySuccess()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mConnectionStatus = SOCKET_CONNECTED;
|
||||
mConnectTimestamp = PR_IntervalNow();
|
||||
OnConnectSuccess();
|
||||
}
|
||||
|
||||
void
|
||||
UnixSocketConsumer::NotifyError()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mConnectionStatus = SOCKET_DISCONNECTED;
|
||||
mConnectDelayMs = CalculateConnectDelayMs();
|
||||
OnConnectError();
|
||||
}
|
||||
|
||||
void
|
||||
UnixSocketConsumer::NotifyDisconnect()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mConnectionStatus = SOCKET_DISCONNECTED;
|
||||
mConnectDelayMs = CalculateConnectDelayMs();
|
||||
OnDisconnect();
|
||||
}
|
||||
|
||||
bool
|
||||
UnixSocketConsumer::ConnectSocket(UnixSocketConnector* aConnector,
|
||||
const char* aAddress,
|
||||
@ -865,7 +842,7 @@ UnixSocketConsumer::ConnectSocket(UnixSocketConnector* aConnector,
|
||||
nsCString addr(aAddress);
|
||||
MessageLoop* ioLoop = XRE_GetIOMessageLoop();
|
||||
mImpl = new UnixSocketImpl(ioLoop, this, connector.forget(), addr);
|
||||
mConnectionStatus = SOCKET_CONNECTING;
|
||||
SetConnectionStatus(SOCKET_CONNECTING);
|
||||
if (aDelayMs > 0) {
|
||||
SocketDelayedConnectTask* connectTask = new SocketDelayedConnectTask(mImpl);
|
||||
mImpl->SetDelayedConnectTask(connectTask);
|
||||
@ -891,31 +868,11 @@ UnixSocketConsumer::ListenSocket(UnixSocketConnector* aConnector)
|
||||
|
||||
mImpl = new UnixSocketImpl(XRE_GetIOMessageLoop(), this, connector.forget(),
|
||||
EmptyCString());
|
||||
mConnectionStatus = SOCKET_LISTENING;
|
||||
SetConnectionStatus(SOCKET_LISTENING);
|
||||
XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
|
||||
new SocketListenTask(mImpl));
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
UnixSocketConsumer::CalculateConnectDelayMs() const
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
uint32_t connectDelayMs = mConnectDelayMs;
|
||||
|
||||
if ((PR_IntervalNow()-mConnectTimestamp) > connectDelayMs) {
|
||||
// reset delay if connection has been opened for a while, or...
|
||||
connectDelayMs = 0;
|
||||
} else if (!connectDelayMs) {
|
||||
// ...start with a delay of ~1 sec, or...
|
||||
connectDelayMs = 1<<10;
|
||||
} else if (connectDelayMs < (1<<16)) {
|
||||
// ...otherwise increase delay by a factor of 2
|
||||
connectDelayMs <<= 1;
|
||||
}
|
||||
return connectDelayMs;
|
||||
}
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace mozilla
|
||||
|
@ -7,50 +7,17 @@
|
||||
#ifndef mozilla_ipc_UnixSocket_h
|
||||
#define mozilla_ipc_UnixSocket_h
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/ipc/UnixSocketWatcher.h"
|
||||
#include "mozilla/ipc/SocketBase.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
class UnixSocketRawData
|
||||
{
|
||||
public:
|
||||
// Number of octets in mData.
|
||||
size_t mSize;
|
||||
size_t mCurrentWriteOffset;
|
||||
nsAutoArrayPtr<uint8_t> mData;
|
||||
|
||||
/**
|
||||
* Constructor for situations where only size is known beforehand
|
||||
* (for example, when being assigned strings)
|
||||
*/
|
||||
UnixSocketRawData(size_t aSize) :
|
||||
mSize(aSize),
|
||||
mCurrentWriteOffset(0)
|
||||
{
|
||||
mData = new uint8_t[mSize];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for situations where size and data is known
|
||||
* beforehand (for example, when being assigned strings)
|
||||
*/
|
||||
UnixSocketRawData(const void* aData, size_t aSize)
|
||||
: mSize(aSize),
|
||||
mCurrentWriteOffset(0)
|
||||
{
|
||||
MOZ_ASSERT(aData || !mSize);
|
||||
mData = new uint8_t[mSize];
|
||||
memcpy(mData, aData, mSize);
|
||||
}
|
||||
};
|
||||
|
||||
class UnixSocketImpl;
|
||||
|
||||
/**
|
||||
@ -128,43 +95,14 @@ public:
|
||||
|
||||
};
|
||||
|
||||
enum SocketConnectionStatus {
|
||||
SOCKET_DISCONNECTED = 0,
|
||||
SOCKET_LISTENING = 1,
|
||||
SOCKET_CONNECTING = 2,
|
||||
SOCKET_CONNECTED = 3
|
||||
};
|
||||
|
||||
class UnixSocketConsumer
|
||||
class UnixSocketConsumer : public SocketConsumerBase
|
||||
{
|
||||
protected:
|
||||
virtual ~UnixSocketConsumer();
|
||||
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(UnixSocketConsumer)
|
||||
|
||||
UnixSocketConsumer();
|
||||
|
||||
SocketConnectionStatus GetConnectionStatus() const
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return mConnectionStatus;
|
||||
}
|
||||
|
||||
int GetSuggestedConnectDelayMs() const
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return mConnectDelayMs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to be called whenever data is received. This is only called on the
|
||||
* main thread.
|
||||
*
|
||||
* @param aMessage Data received from the socket.
|
||||
*/
|
||||
virtual void ReceiveSocketData(nsAutoPtr<UnixSocketRawData>& aMessage) = 0;
|
||||
|
||||
/**
|
||||
* Queue data to be sent to the socket on the IO thread. Can only be called on
|
||||
* originating thread.
|
||||
@ -216,49 +154,13 @@ public:
|
||||
*/
|
||||
void CloseSocket();
|
||||
|
||||
/**
|
||||
* Callback for socket connect/accept success. Called after connect/accept has
|
||||
* finished. Will be run on main thread, before any reads take place.
|
||||
*/
|
||||
virtual void OnConnectSuccess() = 0;
|
||||
|
||||
/**
|
||||
* Callback for socket connect/accept error. Will be run on main thread.
|
||||
*/
|
||||
virtual void OnConnectError() = 0;
|
||||
|
||||
/**
|
||||
* Callback for socket disconnect. Will be run on main thread.
|
||||
*/
|
||||
virtual void OnDisconnect() = 0;
|
||||
|
||||
/**
|
||||
* Called by implementation to notify consumer of success.
|
||||
*/
|
||||
void NotifySuccess();
|
||||
|
||||
/**
|
||||
* Called by implementation to notify consumer of error.
|
||||
*/
|
||||
void NotifyError();
|
||||
|
||||
/**
|
||||
* Called by implementation to notify consumer of disconnect.
|
||||
*/
|
||||
void NotifyDisconnect();
|
||||
|
||||
/**
|
||||
* Get the current sockaddr for the socket
|
||||
*/
|
||||
void GetSocketAddr(nsAString& aAddrStr);
|
||||
|
||||
private:
|
||||
uint32_t CalculateConnectDelayMs() const;
|
||||
|
||||
UnixSocketImpl* mImpl;
|
||||
SocketConnectionStatus mConnectionStatus;
|
||||
PRIntervalTime mConnectTimestamp;
|
||||
uint32_t mConnectDelayMs;
|
||||
};
|
||||
|
||||
} // namespace ipc
|
||||
|
@ -5,11 +5,13 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
EXPORTS.mozilla.ipc += [
|
||||
'UnixSocket.h',
|
||||
'SocketBase.h',
|
||||
'UnixSocket.h'
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
'UnixSocket.cpp',
|
||||
'SocketBase.cpp',
|
||||
'UnixSocket.cpp'
|
||||
]
|
||||
|
||||
FAIL_ON_WARNINGS = True
|
||||
|
Loading…
Reference in New Issue
Block a user