зеркало из https://github.com/mozilla/pjs.git
fix for #38929, when building the subscribe dialog, don't block the ui thread.
using nsTimer to do this. need to fix some performance problems, but that's covered in other bugs.
This commit is contained in:
Родитель
a4557044f4
Коммит
1891dcfbee
|
@ -47,6 +47,7 @@ EXTRA_DSO_LDOPTS = \
|
|||
-L$(DIST)/bin \
|
||||
-L$(DIST)/lib \
|
||||
$(EXTRA_DSO_LIBS) \
|
||||
$(MOZ_TIMER_LIBS) \
|
||||
$(MOZ_JS_LIBS) \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(NULL)
|
||||
|
|
|
@ -45,6 +45,7 @@ LLIBS= \
|
|||
$(DIST)\lib\msgnews_s.lib \
|
||||
$(LIBNSPR) \
|
||||
$(DIST)\lib\rdfutil_s.lib \
|
||||
$(DIST)\lib\timer_s.lib \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)/config/rules.mak>
|
||||
|
|
|
@ -93,7 +93,8 @@
|
|||
#define PREF_NEWS_CANCEL_CONFIRM "news.cancel.confirm"
|
||||
#define PREF_NEWS_CANCEL_ALERT_ON_SUCCESS "news.cancel.alert_on_success"
|
||||
#define DEFAULT_NEWS_CHUNK_SIZE -1
|
||||
#define READ_NEWS_LIST_COUNT_MAX 4 /* number of groups to process at a time when reading the list from the server */
|
||||
#define READ_NEWS_LIST_COUNT_MAX 20 /* number of groups to process at a time when reading the list from the server */
|
||||
#define READ_NEWS_LIST_TIMEOUT 50 /* uSec to wait until doing more */
|
||||
|
||||
// ***jt -- the following were pirated from xpcom/io/nsByteBufferInputStream
|
||||
// which is not currently in the build system
|
||||
|
@ -151,7 +152,6 @@ static NS_DEFINE_CID(kCMsgAccountManagerCID, NS_MSGACCOUNTMANAGER_CID);
|
|||
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
|
||||
static NS_DEFINE_CID(kPrefServiceCID,NS_PREF_CID);
|
||||
static NS_DEFINE_CID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
|
||||
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
||||
|
||||
typedef struct _cancelInfoEntry {
|
||||
char *from;
|
||||
|
@ -448,6 +448,7 @@ NS_IMPL_RELEASE_INHERITED(nsNNTPProtocol, nsMsgProtocol)
|
|||
|
||||
NS_INTERFACE_MAP_BEGIN(nsNNTPProtocol)
|
||||
NS_INTERFACE_MAP_ENTRY(nsINNTPProtocol)
|
||||
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsMsgProtocol)
|
||||
|
||||
nsNNTPProtocol::nsNNTPProtocol(nsIURI * aURL, nsIMsgWindow *aMsgWindow)
|
||||
|
@ -490,6 +491,10 @@ nsNNTPProtocol::~nsNNTPProtocol()
|
|||
if (m_lineStreamBuffer) {
|
||||
delete m_lineStreamBuffer;
|
||||
}
|
||||
if (mUpdateTimer) {
|
||||
mUpdateTimer->Cancel();
|
||||
mUpdateTimer = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNNTPProtocol::Initialize(nsIURI * aURL, nsIMsgWindow *aMsgWindow)
|
||||
|
@ -1008,6 +1013,15 @@ NS_IMETHODIMP nsNNTPProtocol::OnStopRequest(nsIChannel * aChannel, nsISupports *
|
|||
|
||||
// okay, we've been told that the send is done and the connection is going away. So
|
||||
// we need to release all of our state
|
||||
|
||||
#if 0
|
||||
// cancel any outstanding udpate timer
|
||||
if (mUpdateTimer) {
|
||||
mUpdateTimer->Cancel();
|
||||
mUpdateTimer = nsnull;
|
||||
}
|
||||
#endif
|
||||
|
||||
return CloseSocket();
|
||||
}
|
||||
|
||||
|
@ -2912,86 +2926,45 @@ PRInt32 nsNNTPProtocol::ReadNewsList(nsIInputStream * inputStream, PRUint32 leng
|
|||
|
||||
if (m_readNewsListCount == READ_NEWS_LIST_COUNT_MAX) {
|
||||
m_readNewsListCount = 0;
|
||||
rv = PostReadNewsListEvent(this, inputStream, HandleReadNewsListEvent);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_ASSERTION(0,"failed to post ReadNewsListEvent");
|
||||
}
|
||||
else {
|
||||
m_nextState = NEWS_FINISHED;
|
||||
}
|
||||
if (mUpdateTimer) {
|
||||
mUpdateTimer->Cancel();
|
||||
mUpdateTimer = nsnull;
|
||||
}
|
||||
rv = NS_NewTimer(getter_AddRefs(mUpdateTimer));
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to create timer");
|
||||
if (NS_FAILED(rv)) return -1;
|
||||
|
||||
mInputStream = inputStream;
|
||||
|
||||
const PRUint32 kUpdateTimerDelay = READ_NEWS_LIST_TIMEOUT;
|
||||
rv = mUpdateTimer->Init(NS_STATIC_CAST(nsITimerCallback*,this), kUpdateTimerDelay);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to init timer");
|
||||
if (NS_FAILED(rv)) return -1;
|
||||
|
||||
m_nextState = NEWS_FINISHED;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
return -1;
|
||||
}
|
||||
if (NS_FAILED(rv)) return -1;
|
||||
return(status);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNNTPProtocol::PostReadNewsListEvent(nsNNTPProtocol * aNNTPProtocol, nsIInputStream *aInputStream, PLHandleEventProc aHandler)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIEventQueueService> svc = do_GetService(kEventQueueServiceCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (!svc) return NS_ERROR_UNEXPECTED;
|
||||
|
||||
nsCOMPtr<nsIEventQueue> queue;
|
||||
rv = svc->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(queue));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (!queue) return NS_ERROR_UNEXPECTED;
|
||||
|
||||
ReadNewsListEvent* event = new ReadNewsListEvent;
|
||||
if (!event) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
PL_InitEvent(NS_REINTERPRET_CAST(PLEvent*, event),
|
||||
nsnull,
|
||||
aHandler,
|
||||
DestroyReadNewsListEvent);
|
||||
|
||||
event->mNNTPProtocol = aNNTPProtocol;
|
||||
NS_ADDREF(event->mNNTPProtocol);
|
||||
|
||||
event->mInputStream = aInputStream;
|
||||
NS_ADDREF(event->mInputStream);
|
||||
|
||||
rv = queue->EnterMonitor();
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
(void) queue->PostEvent(NS_REINTERPRET_CAST(PLEvent*, event));
|
||||
(void) queue->ExitMonitor();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If we get here, something bad happened. Clean up.
|
||||
NS_RELEASE(event->mNNTPProtocol);
|
||||
NS_RELEASE(event->mInputStream);
|
||||
delete event;
|
||||
return rv;
|
||||
}
|
||||
|
||||
void*
|
||||
nsNNTPProtocol::HandleReadNewsListEvent(PLEvent* aEvent)
|
||||
{
|
||||
ReadNewsListEvent* event = NS_REINTERPRET_CAST(ReadNewsListEvent*, aEvent);
|
||||
nsNNTPProtocol* aNNTPProtocol = event->mNNTPProtocol;
|
||||
|
||||
aNNTPProtocol->m_nextState = NNTP_READ_LIST;
|
||||
aNNTPProtocol->ProcessProtocolState(nsnull, event->mInputStream, 0,0);
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
nsNNTPProtocol::DestroyReadNewsListEvent(PLEvent* aEvent)
|
||||
nsNNTPProtocol::Notify(nsITimer *timer)
|
||||
{
|
||||
ReadNewsListEvent* event = NS_REINTERPRET_CAST(ReadNewsListEvent*, aEvent);
|
||||
NS_RELEASE(event->mNNTPProtocol);
|
||||
NS_RELEASE(event->mInputStream);
|
||||
delete event;
|
||||
NS_ASSERTION(timer == mUpdateTimer.get(), "Hey, this ain't my timer!");
|
||||
mUpdateTimer = nsnull; // release my hold
|
||||
TimerCallback();
|
||||
}
|
||||
|
||||
void nsNNTPProtocol::TimerCallback()
|
||||
{
|
||||
m_nextState = NNTP_READ_LIST;
|
||||
ProcessProtocolState(nsnull, mInputStream, 0,0);
|
||||
#if 0
|
||||
mInputStream = null;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/* start the xover command
|
||||
*/
|
||||
|
|
|
@ -26,8 +26,6 @@
|
|||
#include "nsMsgProtocol.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIEventQueue.h"
|
||||
#include "nsIEventQueueService.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsIBufferInputStream.h"
|
||||
|
@ -48,6 +46,9 @@
|
|||
#include "nsSpecialSystemDirectory.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsITimerCallback.h"
|
||||
|
||||
// this is only needed as long as our libmime hack is in place
|
||||
#include "prio.h"
|
||||
|
||||
|
@ -146,11 +147,15 @@ NEWS_FREE,
|
|||
NEWS_FINISHED
|
||||
} StatesEnum;
|
||||
|
||||
class nsNNTPProtocol : public nsINNTPProtocol, public nsMsgProtocol
|
||||
class nsNNTPProtocol : public nsINNTPProtocol, public nsITimerCallback, public nsMsgProtocol
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSINNTPPROTOCOL
|
||||
|
||||
// nsITimerCallback interfaces
|
||||
NS_IMETHOD_(void) Notify(nsITimer *timer);
|
||||
|
||||
// Creating a protocol instance requires the URL
|
||||
// need to call Initialize after we do a new of nsNNTPProtocol
|
||||
nsNNTPProtocol(nsIURI * aURL, nsIMsgWindow *aMsgWindow);
|
||||
|
@ -391,18 +396,9 @@ private:
|
|||
void SetProgressBarPercent(PRUint32 aProgress, PRUint32 aProgressMax);
|
||||
void SetProgressStatus(char * message);
|
||||
nsresult InitializeNewsFolderFromUri(const char *uri);
|
||||
|
||||
protected:
|
||||
struct ReadNewsListEvent {
|
||||
PLEvent mEvent;
|
||||
nsNNTPProtocol * mNNTPProtocol;
|
||||
nsIInputStream * mInputStream;
|
||||
};
|
||||
static nsresult
|
||||
PostReadNewsListEvent(nsNNTPProtocol* aNNTPProtocol, nsIInputStream * aInputStream, PLHandleEventProc aHandler);
|
||||
|
||||
static void* HandleReadNewsListEvent(PLEvent* aEvent);
|
||||
static void DestroyReadNewsListEvent(PLEvent* aEvent);
|
||||
void TimerCallback();
|
||||
nsCOMPtr <nsIInputStream> mInputStream;
|
||||
nsCOMPtr <nsITimer> mUpdateTimer;
|
||||
};
|
||||
|
||||
NS_BEGIN_EXTERN_C
|
||||
|
|
Загрузка…
Ссылка в новой задаче