mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-16 22:04:36 +00:00
Added synchronization to socket transport APIs... Added access methods for getting the PRCList from a transport...
This commit is contained in:
parent
fe34d14c41
commit
3b7139d78f
@ -103,11 +103,12 @@ nsSocketTransport::nsSocketTransport()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
|
||||
PR_INIT_CLIST(this);
|
||||
PR_INIT_CLIST(&mListLink);
|
||||
|
||||
mHostName = nsnull;
|
||||
mPort = 0;
|
||||
mSocketFD = nsnull;
|
||||
mLock = nsnull;
|
||||
|
||||
mCurrentState = eSocketState_Created;
|
||||
mOperation = eSocketOperation_None;
|
||||
@ -160,6 +161,11 @@ nsSocketTransport::~nsSocketTransport()
|
||||
PR_Close(mSocketFD);
|
||||
mSocketFD = nsnull;
|
||||
}
|
||||
|
||||
if (mLock) {
|
||||
PR_DestroyLock(mLock);
|
||||
mLock = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -184,6 +190,16 @@ nsresult nsSocketTransport::Init(nsSocketTransportService* aService,
|
||||
rv = NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
//
|
||||
// Create the lock used for synchronizing access to the transport instance.
|
||||
//
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mLock = PR_NewLock();
|
||||
if (!mLock) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -193,6 +209,12 @@ nsresult nsSocketTransport::Process(PRInt16 aSelectFlags)
|
||||
nsresult rv = NS_OK;
|
||||
PRBool done = PR_FALSE;
|
||||
|
||||
//
|
||||
// Enter the socket transport lock...
|
||||
// This lock protects access to socket transport member data...
|
||||
//
|
||||
Lock();
|
||||
|
||||
while (!done)
|
||||
{
|
||||
switch (mCurrentState) {
|
||||
@ -300,16 +322,22 @@ nsresult nsSocketTransport::Process(PRInt16 aSelectFlags)
|
||||
//
|
||||
aSelectFlags = 0;
|
||||
}
|
||||
|
||||
|
||||
// Leave the socket transport lock...
|
||||
Unlock();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
//-----
|
||||
//
|
||||
// doResolveHost:
|
||||
// doResolveHost:
|
||||
//
|
||||
// Return Codes:
|
||||
// This method is called while holding the SocketTransport lock. It is
|
||||
// always called on the socket transport thread...
|
||||
//
|
||||
// Return Codes:
|
||||
// NS_OK
|
||||
// NS_ERROR_HOST_NOT_FOUND
|
||||
// NS_ERROR_FAILURE
|
||||
@ -355,9 +383,12 @@ nsresult nsSocketTransport::doResolveHost(void)
|
||||
|
||||
//-----
|
||||
//
|
||||
// doConnection:
|
||||
// doConnection:
|
||||
//
|
||||
// Return values:
|
||||
// This method is called while holding the SocketTransport lock. It is
|
||||
// always called on the socket transport thread...
|
||||
//
|
||||
// Return values:
|
||||
// NS_OK
|
||||
// NS_BASE_STREAM_WOULD_BLOCK
|
||||
//
|
||||
@ -448,7 +479,10 @@ nsresult nsSocketTransport::doConnection(PRInt16 aSelectFlags)
|
||||
rv = NS_ERROR_CONNECTION_REFUSED;
|
||||
}
|
||||
//
|
||||
// The connection was successful...
|
||||
// The connection was successful...
|
||||
//
|
||||
// PR_Poll(...) returns PR_POLL_WRITE to indicate that the connection is
|
||||
// established...
|
||||
//
|
||||
else if (PR_POLL_WRITE & aSelectFlags) {
|
||||
rv = NS_OK;
|
||||
@ -461,9 +495,12 @@ nsresult nsSocketTransport::doConnection(PRInt16 aSelectFlags)
|
||||
|
||||
//-----
|
||||
//
|
||||
// doRead:
|
||||
// doRead:
|
||||
//
|
||||
// Return values:
|
||||
// This method is called while holding the SocketTransport lock. It is
|
||||
// always called on the socket transport thread...
|
||||
//
|
||||
// Return values:
|
||||
// NS_OK
|
||||
// NS_BASE_STREAM_WOULD_BLOCK
|
||||
//
|
||||
@ -564,9 +601,12 @@ nsresult nsSocketTransport::doRead(PRInt16 aSelectFlags)
|
||||
|
||||
//-----
|
||||
//
|
||||
// doWrite:
|
||||
// doWrite:
|
||||
//
|
||||
// Return values:
|
||||
// This method is called while holding the SocketTransport lock. It is
|
||||
// always called on the socket transport thread...
|
||||
//
|
||||
// Return values:
|
||||
// NS_OK
|
||||
// NS_BASE_STREAM_WOULD_BLOCK
|
||||
//
|
||||
@ -696,20 +736,27 @@ nsSocketTransport::AsyncRead(nsISupports* aContext,
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// Enter the socket transport lock...
|
||||
Lock();
|
||||
|
||||
// If a read is already in progress then fail...
|
||||
if (mReadListener) {
|
||||
rv = NS_ERROR_IN_PROGRESS;
|
||||
}
|
||||
|
||||
// Create a new input stream for reading data into...
|
||||
if (NS_SUCCEEDED(rv) && !mReadStream) {
|
||||
rv = NS_NewByteBufferInputStream(&mReadStream, PR_FALSE,
|
||||
MAX_IO_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Store the context used for this read...
|
||||
NS_IF_RELEASE(mReadContext);
|
||||
mReadContext = aContext;
|
||||
NS_IF_ADDREF(mReadContext);
|
||||
|
||||
// Create a marshalling stream listener to receive notifications...
|
||||
rv = NS_NewAsyncStreamListener(&mReadListener, aAppEventQueue, aListener);
|
||||
}
|
||||
|
||||
@ -719,6 +766,9 @@ nsSocketTransport::AsyncRead(nsISupports* aContext,
|
||||
rv = mService->AddToWorkQ(this);
|
||||
}
|
||||
|
||||
// Leave the socket transport lock...
|
||||
Unlock();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -731,6 +781,10 @@ nsSocketTransport::AsyncWrite(nsIInputStream* aFromStream,
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// Enter the socket transport lock...
|
||||
Lock();
|
||||
|
||||
// If a write is already in progress then fail...
|
||||
if (mWriteStream) {
|
||||
rv = NS_ERROR_IN_PROGRESS;
|
||||
}
|
||||
@ -743,8 +797,11 @@ nsSocketTransport::AsyncWrite(nsIInputStream* aFromStream,
|
||||
mWriteContext = aContext;
|
||||
NS_IF_ADDREF(mWriteContext);
|
||||
|
||||
// Create a marshalling stream observer to receive notifications...
|
||||
NS_IF_RELEASE(mWriteObserver);
|
||||
rv = NS_NewAsyncStreamObserver(&mWriteObserver, aAppEventQueue, aObserver);
|
||||
if (aObserver) {
|
||||
rv = NS_NewAsyncStreamObserver(&mWriteObserver, aAppEventQueue, aObserver);
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
@ -752,6 +809,9 @@ nsSocketTransport::AsyncWrite(nsIInputStream* aFromStream,
|
||||
rv = mService->AddToWorkQ(this);
|
||||
}
|
||||
|
||||
// Leave the socket transport lock...
|
||||
Unlock();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -52,8 +52,7 @@ enum nsSocketOperation {
|
||||
|
||||
class nsSocketTransportService;
|
||||
|
||||
class nsSocketTransport : public PRCList,
|
||||
public nsITransport
|
||||
class nsSocketTransport : public nsITransport
|
||||
{
|
||||
public:
|
||||
// nsISupports methods:
|
||||
@ -95,7 +94,18 @@ public:
|
||||
PRFileDesc* GetSocket(void) { return mSocketFD; }
|
||||
PRInt16 GetSelectFlags(void) { return mSelectFlags; }
|
||||
|
||||
PRCList* GetListNode(void) { return &mListLink; }
|
||||
static nsSocketTransport* GetInstance(PRCList* qp) { return (nsSocketTransport*)((char*)qp - offsetof(nsSocketTransport, mListLink)); }
|
||||
|
||||
protected:
|
||||
// Inline helpers...
|
||||
void Lock (void) { NS_ASSERTION(mLock, "Lock null."); PR_Lock(mLock); }
|
||||
void Unlock(void) { NS_ASSERTION(mLock, "Lock null."); PR_Unlock(mLock); }
|
||||
|
||||
protected:
|
||||
PRCList mListLink;
|
||||
|
||||
PRLock* mLock;
|
||||
nsSocketState mCurrentState;
|
||||
nsSocketOperation mOperation;
|
||||
|
||||
|
@ -147,15 +147,17 @@ nsresult nsSocketTransportService::AddToWorkQ(nsSocketTransport* aTransport)
|
||||
PRStatus status;
|
||||
PRBool bFireEvent = PR_FALSE;
|
||||
nsresult rv = NS_OK;
|
||||
PRCList* qp;
|
||||
|
||||
Lock();
|
||||
//
|
||||
// Only add the transport if it is *not* already on the list...
|
||||
//
|
||||
if (PR_CLIST_IS_EMPTY(aTransport)) {
|
||||
qp = aTransport->GetListNode();
|
||||
if (PR_CLIST_IS_EMPTY(qp)) {
|
||||
NS_ADDREF(aTransport);
|
||||
bFireEvent = PR_CLIST_IS_EMPTY(&mWorkQ);
|
||||
PR_APPEND_LINK(aTransport, &mWorkQ);
|
||||
PR_APPEND_LINK(qp, &mWorkQ);
|
||||
}
|
||||
Unlock();
|
||||
//
|
||||
@ -176,6 +178,7 @@ nsresult nsSocketTransportService::AddToWorkQ(nsSocketTransport* aTransport)
|
||||
nsresult nsSocketTransportService::ProcessWorkQ(void)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
PRCList* qp;
|
||||
|
||||
//
|
||||
// Only process pending operations while there is space available in the
|
||||
@ -190,8 +193,10 @@ nsresult nsSocketTransportService::ProcessWorkQ(void)
|
||||
nsSocketTransport* transport;
|
||||
|
||||
// Get the next item off of the workQ...
|
||||
transport = (nsSocketTransport*)PR_LIST_HEAD(&mWorkQ);
|
||||
PR_REMOVE_AND_INIT_LINK(transport);
|
||||
qp = PR_LIST_HEAD(&mWorkQ);
|
||||
|
||||
transport = nsSocketTransport::GetInstance(qp);
|
||||
PR_REMOVE_AND_INIT_LINK(qp);
|
||||
|
||||
// Try to perform the operation...
|
||||
//
|
||||
|
Loading…
x
Reference in New Issue
Block a user