fixes bug 142255 "RFE provide a way to prioritize connections" r=bz

This commit is contained in:
darin%meer.net 2005-01-15 07:01:20 +00:00
Родитель 85b2051071
Коммит e47a1ef6c8
8 изменённых файлов: 136 добавлений и 40 удалений

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

@ -45,7 +45,7 @@ interface nsIProxyInfo;
* using any feature exposed by this interface, be aware that this interface
* will change and you will be broken. You have been warned.
*/
[scriptable, uuid(f3764874-ed7e-4873-883c-11d67a4e3638)]
[scriptable, uuid(ae9dce68-c27c-44f1-b41d-462f5e470945)]
interface nsIHttpChannelInternal : nsISupports
{
/**
@ -77,4 +77,11 @@ interface nsIHttpChannelInternal : nsISupports
* Get the proxy info in use by the channel.
*/
readonly attribute nsIProxyInfo proxyInfo;
/**
* Get or set the relative priority for this HTTP channel. Smaller values
* have higher priority. Negative values are allowed, and the default
* priority is 0.
*/
attribute short priority;
};

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

@ -96,6 +96,7 @@ nsHttpChannel::nsHttpChannel()
, mStatus(NS_OK)
, mLogicalOffset(0)
, mCaps(0)
, mPriority(0)
, mCachedResponseHead(nsnull)
, mCacheAccess(0)
, mPostID(0)
@ -352,7 +353,7 @@ nsHttpChannel::Connect(PRBool firstTime)
rv = SetupTransaction();
if (NS_FAILED(rv)) return rv;
rv = gHttpHandler->InitiateTransaction(mTransaction);
rv = gHttpHandler->InitiateTransaction(mTransaction, mPriority);
if (NS_FAILED(rv)) return rv;
return mTransactionPump->AsyncRead(this, nsnull);
@ -3639,6 +3640,20 @@ nsHttpChannel::GetProxyInfo(nsIProxyInfo **result)
return NS_OK;
}
NS_IMETHODIMP
nsHttpChannel::GetPriority(PRInt16 *value)
{
*value = mPriority;
return NS_OK;
}
NS_IMETHODIMP
nsHttpChannel::SetPriority(PRInt16 value)
{
mPriority = value;
return NS_OK;
}
//-----------------------------------------------------------------------------
// nsHttpChannel::nsIRequestObserver
//-----------------------------------------------------------------------------
@ -4169,7 +4184,7 @@ nsHttpChannel::DoAuthRetry(nsAHttpConnection *conn)
seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
}
rv = gHttpHandler->InitiateTransaction(mTransaction);
rv = gHttpHandler->InitiateTransaction(mTransaction, mPriority);
if (NS_FAILED(rv)) return rv;
return mTransactionPump->AsyncRead(this, nsnull);

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

@ -221,6 +221,7 @@ private:
PRUint32 mStatus;
nsUint64 mLogicalOffset;
PRUint8 mCaps;
PRInt16 mPriority;
nsCString mContentTypeHint;
nsCString mContentCharsetHint;

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

@ -53,6 +53,25 @@ static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID);
//-----------------------------------------------------------------------------
static void
InsertTransactionSorted(nsVoidArray &pendingQ, nsHttpTransaction *trans)
{
// insert into queue with smallest valued number first. search in reverse
// order under the assumption that many of the existing transactions will
// have the same priority (usually 0).
for (PRInt32 i=pendingQ.Count()-1; i>=0; --i) {
nsHttpTransaction *t = (nsHttpTransaction *) pendingQ[i];
if (trans->Priority() >= t->Priority()) {
pendingQ.InsertElementAt(trans, i+1);
return;
}
}
pendingQ.InsertElementAt(trans, 0);
}
//-----------------------------------------------------------------------------
nsHttpConnectionMgr::nsHttpConnectionMgr()
: mRef(0)
, mMonitor(nsAutoMonitor::NewMonitor("nsHttpConnectionMgr"))
@ -139,7 +158,7 @@ nsHttpConnectionMgr::Shutdown()
}
nsresult
nsHttpConnectionMgr::PostEvent(nsConnEventHandler handler, nsresult status, void *param)
nsHttpConnectionMgr::PostEvent(nsConnEventHandler handler, PRInt32 iparam, void *vparam)
{
nsAutoMonitor mon(mMonitor);
@ -149,7 +168,7 @@ nsHttpConnectionMgr::PostEvent(nsConnEventHandler handler, nsresult status, void
rv = NS_ERROR_NOT_INITIALIZED;
}
else {
PLEvent *event = new nsConnEvent(this, handler, status, param);
PLEvent *event = new nsConnEvent(this, handler, iparam, vparam);
if (!event)
rv = NS_ERROR_OUT_OF_MEMORY;
else {
@ -164,12 +183,24 @@ nsHttpConnectionMgr::PostEvent(nsConnEventHandler handler, nsresult status, void
//-----------------------------------------------------------------------------
nsresult
nsHttpConnectionMgr::AddTransaction(nsHttpTransaction *trans)
nsHttpConnectionMgr::AddTransaction(nsHttpTransaction *trans, PRInt32 priority)
{
LOG(("nsHttpConnectionMgr::AddTransaction [trans=%x]\n", trans));
LOG(("nsHttpConnectionMgr::AddTransaction [trans=%x %d]\n", trans, priority));
NS_ADDREF(trans);
nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgNewTransaction, NS_OK, trans);
nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgNewTransaction, priority, trans);
if (NS_FAILED(rv))
NS_RELEASE(trans);
return rv;
}
nsresult
nsHttpConnectionMgr::RescheduleTransaction(nsHttpTransaction *trans, PRInt32 priority)
{
LOG(("nsHttpConnectionMgr::RescheduleTransaction [trans=%x %d]\n", trans, priority));
NS_ADDREF(trans);
nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgReschedTransaction, priority, trans);
if (NS_FAILED(rv))
NS_RELEASE(trans);
return rv;
@ -237,7 +268,7 @@ nsHttpConnectionMgr::ReclaimConnection(nsHttpConnection *conn)
LOG(("nsHttpConnectionMgr::ReclaimConnection [conn=%x]\n", conn));
NS_ADDREF(conn);
nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgReclaimConnection, NS_OK, conn);
nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgReclaimConnection, 0, conn);
if (NS_FAILED(rv))
NS_RELEASE(conn);
return rv;
@ -247,7 +278,7 @@ nsresult
nsHttpConnectionMgr::UpdateParam(nsParamName name, PRUint16 value)
{
PRUint32 param = (PRUint32(name) << 16) | PRUint32(value);
return PostEvent(&nsHttpConnectionMgr::OnMsgUpdateParam, NS_OK, (void *) param);
return PostEvent(&nsHttpConnectionMgr::OnMsgUpdateParam, 0, (void *) param);
}
nsresult
@ -256,7 +287,7 @@ nsHttpConnectionMgr::ProcessPendingQ(nsHttpConnectionInfo *ci)
LOG(("nsHttpConnectionMgr::ProcessPendingQ [ci=%s]\n", ci->HashKey().get()));
NS_ADDREF(ci);
nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgProcessPendingQ, NS_OK, ci);
nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgProcessPendingQ, 0, ci);
if (NS_FAILED(rv))
NS_RELEASE(ci);
return rv;
@ -693,7 +724,7 @@ nsHttpConnectionMgr::ProcessNewTransaction(nsHttpTransaction *trans)
LOG((" adding transaction to pending queue [trans=%x pending-count=%u]\n",
trans, ent->mPendingQ.Count()+1));
// put this transaction on the pending queue...
ent->mPendingQ.AppendElement(trans);
InsertTransactionSorted(ent->mPendingQ, trans);
NS_ADDREF(trans);
rv = NS_OK;
}
@ -708,7 +739,7 @@ nsHttpConnectionMgr::ProcessNewTransaction(nsHttpTransaction *trans)
//-----------------------------------------------------------------------------
void
nsHttpConnectionMgr::OnMsgShutdown(nsresult, void *)
nsHttpConnectionMgr::OnMsgShutdown(PRInt32, void *)
{
LOG(("nsHttpConnectionMgr::OnMsgShutdown\n"));
@ -720,11 +751,12 @@ nsHttpConnectionMgr::OnMsgShutdown(nsresult, void *)
}
void
nsHttpConnectionMgr::OnMsgNewTransaction(nsresult, void *param)
nsHttpConnectionMgr::OnMsgNewTransaction(PRInt32 priority, void *param)
{
LOG(("nsHttpConnectionMgr::OnMsgNewTransaction [trans=%p]\n", param));
nsHttpTransaction *trans = (nsHttpTransaction *) param;
trans->SetPriority(priority);
nsresult rv = ProcessNewTransaction(trans);
if (NS_FAILED(rv))
trans->Close(rv); // for whatever its worth
@ -732,7 +764,29 @@ nsHttpConnectionMgr::OnMsgNewTransaction(nsresult, void *param)
}
void
nsHttpConnectionMgr::OnMsgCancelTransaction(nsresult reason, void *param)
nsHttpConnectionMgr::OnMsgReschedTransaction(PRInt32 priority, void *param)
{
LOG(("nsHttpConnectionMgr::OnMsgNewTransaction [trans=%p]\n", param));
nsHttpTransaction *trans = (nsHttpTransaction *) param;
trans->SetPriority(priority);
nsHttpConnectionInfo *ci = trans->ConnectionInfo();
nsCStringKey key(ci->HashKey());
nsConnectionEntry *ent = (nsConnectionEntry *) mCT.Get(&key);
if (ent) {
PRInt32 index = ent->mPendingQ.IndexOf(trans);
if (index >= 0) {
ent->mPendingQ.RemoveElementAt(index);
InsertTransactionSorted(ent->mPendingQ, trans);
}
}
NS_RELEASE(trans);
}
void
nsHttpConnectionMgr::OnMsgCancelTransaction(PRInt32 reason, void *param)
{
LOG(("nsHttpConnectionMgr::OnMsgCancelTransaction [trans=%p]\n", param));
@ -763,7 +817,7 @@ nsHttpConnectionMgr::OnMsgCancelTransaction(nsresult reason, void *param)
}
void
nsHttpConnectionMgr::OnMsgProcessPendingQ(nsresult, void *param)
nsHttpConnectionMgr::OnMsgProcessPendingQ(PRInt32, void *param)
{
nsHttpConnectionInfo *ci = (nsHttpConnectionInfo *) param;
@ -782,7 +836,7 @@ nsHttpConnectionMgr::OnMsgProcessPendingQ(nsresult, void *param)
}
void
nsHttpConnectionMgr::OnMsgPruneDeadConnections(nsresult, void *)
nsHttpConnectionMgr::OnMsgPruneDeadConnections(PRInt32, void *)
{
LOG(("nsHttpConnectionMgr::OnMsgPruneDeadConnections\n"));
@ -791,7 +845,7 @@ nsHttpConnectionMgr::OnMsgPruneDeadConnections(nsresult, void *)
}
void
nsHttpConnectionMgr::OnMsgReclaimConnection(nsresult, void *param)
nsHttpConnectionMgr::OnMsgReclaimConnection(PRInt32, void *param)
{
LOG(("nsHttpConnectionMgr::OnMsgReclaimConnection [conn=%p]\n", param));
@ -835,7 +889,7 @@ nsHttpConnectionMgr::OnMsgReclaimConnection(nsresult, void *param)
}
void
nsHttpConnectionMgr::OnMsgUpdateParam(nsresult status, void *param)
nsHttpConnectionMgr::OnMsgUpdateParam(PRInt32, void *param)
{
PRUint16 name = (PRUint32(param) & 0xFFFF0000) >> 16;
PRUint16 value = PRUint32(param) & 0x0000FFFF;

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

@ -99,7 +99,11 @@ public:
}
// adds a transaction to the list of managed transactions.
nsresult AddTransaction(nsHttpTransaction *);
nsresult AddTransaction(nsHttpTransaction *, PRInt32 priority);
// called to reschedule the given transaction. it must already have been
// added to the connection manager via AddTransaction.
nsresult RescheduleTransaction(nsHttpTransaction *, PRInt32 priority);
// cancels a transaction w/ the given reason.
nsresult CancelTransaction(nsHttpTransaction *, nsresult reason);
@ -213,7 +217,7 @@ private:
nsresult ProcessNewTransaction(nsHttpTransaction *);
// message handlers have this signature
typedef void (nsHttpConnectionMgr:: *nsConnEventHandler)(nsresult, void *);
typedef void (nsHttpConnectionMgr:: *nsConnEventHandler)(PRInt32, void *);
// nsConnEvent
//
@ -227,11 +231,11 @@ private:
public:
nsConnEvent(nsHttpConnectionMgr *mgr,
nsConnEventHandler handler,
nsresult status,
void *param)
PRInt32 iparam,
void *vparam)
: mHandler(handler)
, mStatus(status)
, mParam(param)
, mIParam(iparam)
, mVParam(vparam)
{
NS_ADDREF(mgr);
PL_InitEvent(this, mgr, HandleEvent, DestroyEvent);
@ -242,7 +246,7 @@ private:
nsHttpConnectionMgr *mgr = (nsHttpConnectionMgr *) event->owner;
nsConnEvent *self = (nsConnEvent *) event;
nsConnEventHandler handler = self->mHandler;
(mgr->*handler)(self->mStatus, self->mParam);
(mgr->*handler)(self->mIParam, self->mVParam);
NS_RELEASE(mgr);
return nsnull;
}
@ -253,22 +257,23 @@ private:
private:
nsConnEventHandler mHandler;
nsresult mStatus;
void *mParam;
PRInt32 mIParam;
void *mVParam;
};
nsresult PostEvent(nsConnEventHandler handler,
nsresult status = NS_OK,
void *param = nsnull);
PRInt32 iparam = 0,
void *vparam = nsnull);
// message handlers
void OnMsgShutdown (nsresult status, void *param);
void OnMsgNewTransaction (nsresult status, void *param);
void OnMsgCancelTransaction (nsresult status, void *param);
void OnMsgProcessPendingQ (nsresult status, void *param);
void OnMsgPruneDeadConnections (nsresult status, void *param);
void OnMsgReclaimConnection (nsresult status, void *param);
void OnMsgUpdateParam (nsresult status, void *param);
void OnMsgShutdown (PRInt32, void *);
void OnMsgNewTransaction (PRInt32, void *);
void OnMsgReschedTransaction (PRInt32, void *);
void OnMsgCancelTransaction (PRInt32, void *);
void OnMsgProcessPendingQ (PRInt32, void *);
void OnMsgPruneDeadConnections (PRInt32, void *);
void OnMsgReclaimConnection (PRInt32, void *);
void OnMsgUpdateParam (PRInt32, void *);
// counters
PRUint16 mNumActiveConns;

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

@ -130,9 +130,16 @@ public:
// Called to kick-off a new transaction, by default the transaction
// will be put on the pending transaction queue if it cannot be
// initiated at this time. Callable from any thread.
nsresult InitiateTransaction(nsHttpTransaction *trans)
nsresult InitiateTransaction(nsHttpTransaction *trans, PRInt32 priority)
{
return mConnMgr->AddTransaction(trans);
return mConnMgr->AddTransaction(trans, priority);
}
// Called to change the priority of an existing transaction that has
// already been initiated.
nsresult RescheduleTransaction(nsHttpTransaction *trans, PRInt32 priority)
{
return mConnMgr->RescheduleTransaction(trans, priority);
}
// Called to cancel a transaction, which may or may not be assigned to

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

@ -124,6 +124,7 @@ nsHttpTransaction::nsHttpTransaction()
, mContentLength(-1)
, mContentRead(0)
, mChunkedDecoder(nsnull)
, mPriority(0)
, mStatus(NS_OK)
, mRestartCount(0)
, mCaps(0)
@ -565,7 +566,7 @@ nsHttpTransaction::Restart()
mSecurityInfo = 0;
NS_IF_RELEASE(mConnection);
return gHttpHandler->InitiateTransaction(this);
return gHttpHandler->InitiateTransaction(this, mPriority);
}
void

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

@ -132,6 +132,10 @@ public:
void SetSSLConnectFailed() { mSSLConnectFailed = PR_TRUE; }
PRBool SSLConnectFailed() { return mSSLConnectFailed; }
// These methods may only be used by the connection manager.
void SetPriority(PRInt32 priority) { mPriority = priority; }
PRInt32 Priority() { return mPriority; }
private:
nsresult Restart();
void ParseLine(char *line);
@ -181,6 +185,8 @@ private:
nsresult mStatus;
PRInt16 mPriority;
PRUint16 mRestartCount; // the number of times this transaction has been restarted
PRUint8 mCaps;