Made the netlib blocking stream work correctly when netlib is running on its own thread

This commit is contained in:
rpotts%netscape.com 1998-09-19 07:02:25 +00:00
Родитель 4decdd3357
Коммит 16b3d32f8b
2 изменённых файлов: 68 добавлений и 44 удалений

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

@ -44,50 +44,30 @@ nsConnectionInfo::nsConnectionInfo(nsIURL *aURL,
pURL = aURL;
pNetStream = aStream;
pConsumer = aNotify;
NS_IF_ADDREF(pURL);
NS_IF_ADDREF(pNetStream);
NS_IF_ADDREF(pConsumer);
NS_VERIFY_THREADSAFE_INTERFACE(pURL);
NS_VERIFY_THREADSAFE_INTERFACE(pNetStream);
NS_VERIFY_THREADSAFE_INTERFACE(pConsumer);
pContainer = nsnull;
if (NULL != pURL) {
pURL->AddRef();
}
if (NULL != pNetStream) {
pNetStream->AddRef();
}
if (NULL != pConsumer) {
pConsumer->AddRef();
}
}
NS_IMPL_ISUPPORTS(nsConnectionInfo, kIConnectionInfoIID);
NS_IMPL_THREADSAFE_ISUPPORTS(nsConnectionInfo, kIConnectionInfoIID);
nsConnectionInfo::~nsConnectionInfo()
{
TRACEMSG(("nsConnectionInfo is being destroyed...\n"));
if (NULL != pURL) {
pURL->Release();
}
if (NULL != pNetStream) {
pNetStream->Close();
pNetStream->Release();
}
if (NULL != pConsumer) {
pConsumer->Release();
}
if (nsnull != pContainer) {
NS_RELEASE(pContainer);
}
pURL = NULL;
pNetStream = NULL;
pConsumer = NULL;
pContainer = nsnull;
NS_IF_RELEASE(pURL);
NS_IF_RELEASE(pNetStream);
NS_IF_RELEASE(pConsumer);
NS_IF_RELEASE(pContainer);
}
NS_IMETHODIMP
@ -135,8 +115,8 @@ nsNetlibStream::nsNetlibStream(void)
}
NS_IMPL_ADDREF(nsNetlibStream)
NS_IMPL_RELEASE(nsNetlibStream)
NS_IMPL_THREADSAFE_ADDREF(nsNetlibStream)
NS_IMPL_THREADSAFE_RELEASE(nsNetlibStream)
nsresult nsNetlibStream::QueryInterface(const nsIID &aIID, void** aInstancePtr)
{
@ -161,6 +141,17 @@ nsresult nsNetlibStream::QueryInterface(const nsIID &aIID, void** aInstancePtr)
AddRef();
return NS_OK;
}
#if defined(NS_DEBUG)
/*
* Check for the debug-only interface indicating thread-safety
*/
static NS_DEFINE_IID(kIsThreadsafeIID, NS_ISTHREADSAFE_IID);
if (aIID.Equals(kIsThreadsafeIID)) {
return NS_OK;
}
#endif /* NS_DEBUG */
return NS_NOINTERFACE;
}
@ -564,6 +555,21 @@ nsBlockingStream::~nsBlockingStream()
}
nsresult nsBlockingStream::Close()
{
LockStream();
m_bIsClosed = PR_TRUE;
#if defined(NETLIB_THREAD)
/* Wake up any waiting threads... */
PR_Notify(m_Lock);
#endif /* NETLIB_THREAD */
UnlockStream();
return NS_OK;
}
PRInt32 nsBlockingStream::GetAvailableSpace(PRInt32 *aErrorCode)
{
PRInt32 size = 0;
@ -642,6 +648,11 @@ nsresult nsBlockingStream::Write(const char *aBuf,
*aWriteCount = aLen;
m_DataLength += aLen;
#if defined(NETLIB_THREAD)
/* Wake up any waiting threads... */
PR_Notify(m_Lock);
#endif /* NETLIB_THREAD */
}
done:
@ -679,8 +690,16 @@ nsresult nsBlockingStream::Read(char *aBuf,
aBuf += aOffset;
}
/*
* There is either enough data, or some data left in the stream
* after it has been closed... So, read it and return.
*/
if ((aCount <= m_DataLength) || m_bIsClosed) {
*aReadCount = ReadBuffer(aBuf, aCount);
}
/* Not enough data is available... Must block. */
if (aCount > m_DataLength) {
else {
#if !defined(NETLIB_THREAD)
UnlockStream();
do {
NET_PollSockets();
@ -688,6 +707,12 @@ nsresult nsBlockingStream::Read(char *aBuf,
/* XXX m_bIsClosed is checked outside of the lock! */
} while ((aCount > *aReadCount) && !m_bIsClosed);
LockStream();
#else
do {
PR_Wait(m_Lock, PR_INTERVAL_NO_TIMEOUT);
*aReadCount += ReadBuffer(aBuf + *aReadCount, aCount - *aReadCount);
} while ((aCount > *aReadCount) && !m_bIsClosed);
#endif /* NETLIB_THREAD */
/*
* It is possible that the stream was closed during
* NET_PollSockets(...)... In this case, return EOF if no data
@ -696,9 +721,7 @@ nsresult nsBlockingStream::Read(char *aBuf,
if ((0 == *aReadCount) && m_bIsClosed) {
rv = NS_BASE_STREAM_EOF;
}
} else {
*aReadCount = ReadBuffer(aBuf, aCount);
}
}
}
done:

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

@ -74,10 +74,8 @@ protected:
inline void UnlockStream(void) { if (m_Lock) PR_ExitMonitor (m_Lock); }
protected:
PRBool m_bIsClosed;
private:
PRMonitor *m_Lock;
PRBool m_bIsClosed;
PRMonitor* m_Lock;
};
@ -166,6 +164,9 @@ public:
virtual PRInt32 GetAvailableSpace(PRInt32 *aErrorCode);
/* nsIBaseStream interface */
NS_IMETHOD Close(void);
/* nsIInputStream interface */
NS_IMETHOD GetLength(PRInt32 *aLength);