Back to index

lightning-sunbird  0.9+nobinonly
Classes | Public Types | Public Member Functions | Private Types | Private Member Functions | Static Private Member Functions | Private Attributes | Friends
nsHttpConnectionMgr Class Reference

#include <nsHttpConnectionMgr.h>

Collaboration diagram for nsHttpConnectionMgr:
Collaboration graph
[legend]

List of all members.

Classes

struct  nsConnectionEntry
class  nsConnectionHandle
class  nsConnEvent

Public Types

enum  nsParamName {
  MAX_CONNECTIONS, MAX_CONNECTIONS_PER_HOST, MAX_CONNECTIONS_PER_PROXY, MAX_PERSISTENT_CONNECTIONS_PER_HOST,
  MAX_PERSISTENT_CONNECTIONS_PER_PROXY, MAX_REQUEST_DELAY, MAX_PIPELINED_REQUESTS
}

Public Member Functions

 nsHttpConnectionMgr ()
nsresult Init (PRUint16 maxConnections, PRUint16 maxConnectionsPerHost, PRUint16 maxConnectionsPerProxy, PRUint16 maxPersistentConnectionsPerHost, PRUint16 maxPersistentConnectionsPerProxy, PRUint16 maxRequestDelay, PRUint16 maxPipelinedRequests)
nsresult Shutdown ()
nsrefcnt AddRef ()
nsrefcnt Release ()
nsresult AddTransaction (nsHttpTransaction *, PRInt32 priority)
nsresult RescheduleTransaction (nsHttpTransaction *, PRInt32 priority)
nsresult CancelTransaction (nsHttpTransaction *, nsresult reason)
nsresult PruneDeadConnections ()
nsresult GetSocketThreadEventTarget (nsIEventTarget **)
nsresult ReclaimConnection (nsHttpConnection *conn)
nsresult UpdateParam (nsParamName name, PRUint16 value)
void AddTransactionToPipeline (nsHttpPipeline *)
nsresult ProcessPendingQ (nsHttpConnectionInfo *)

Private Types

typedef void(nsHttpConnectionMgr::* nsConnEventHandler )(PRInt32, void *)

Private Member Functions

virtual ~nsHttpConnectionMgr ()
PRBool ProcessPendingQForEntry (nsConnectionEntry *)
PRBool AtActiveConnectionLimit (nsConnectionEntry *, PRUint8 caps)
void GetConnection (nsConnectionEntry *, PRUint8 caps, nsHttpConnection **)
nsresult DispatchTransaction (nsConnectionEntry *, nsAHttpTransaction *, PRUint8 caps, nsHttpConnection *)
PRBool BuildPipeline (nsConnectionEntry *, nsAHttpTransaction *, nsHttpPipeline **)
nsresult ProcessNewTransaction (nsHttpTransaction *)
nsresult PostEvent (nsConnEventHandler handler, PRInt32 iparam=0, void *vparam=nsnull)
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 *)

Static Private Member Functions

static PRIntn PR_CALLBACK ProcessOneTransactionCB (nsHashKey *, void *, void *)
static PRIntn PR_CALLBACK PurgeOneIdleConnectionCB (nsHashKey *, void *, void *)
static PRIntn PR_CALLBACK PruneDeadConnectionsCB (nsHashKey *, void *, void *)
static PRIntn PR_CALLBACK ShutdownPassCB (nsHashKey *, void *, void *)

Private Attributes

PRInt32 mRef
PRMonitormMonitor
nsCOMPtr< nsIEventTargetmSTEventTarget
PRUint16 mMaxConns
PRUint16 mMaxConnsPerHost
PRUint16 mMaxConnsPerProxy
PRUint16 mMaxPersistConnsPerHost
PRUint16 mMaxPersistConnsPerProxy
PRUint16 mMaxRequestDelay
PRUint16 mMaxPipelinedRequests
PRUint16 mNumActiveConns
PRUint16 mNumIdleConns
nsHashtable mCT

Friends

class nsConnEvent

Detailed Description

Definition at line 54 of file nsHttpConnectionMgr.h.


Member Typedef Documentation

typedef void(nsHttpConnectionMgr:: * nsHttpConnectionMgr::nsConnEventHandler)(PRInt32, void *) [private]

Definition at line 220 of file nsHttpConnectionMgr.h.


Member Enumeration Documentation

Enumerator:
MAX_CONNECTIONS 
MAX_CONNECTIONS_PER_HOST 
MAX_CONNECTIONS_PER_PROXY 
MAX_PERSISTENT_CONNECTIONS_PER_HOST 
MAX_PERSISTENT_CONNECTIONS_PER_PROXY 
MAX_REQUEST_DELAY 
MAX_PIPELINED_REQUESTS 

Definition at line 59 of file nsHttpConnectionMgr.h.


Constructor & Destructor Documentation

Definition at line 75 of file nsHttpConnectionMgr.cpp.

    : mRef(0)
    , mMonitor(nsAutoMonitor::NewMonitor("nsHttpConnectionMgr"))
    , mMaxConns(0)
    , mMaxConnsPerHost(0)
    , mMaxConnsPerProxy(0)
    , mMaxPersistConnsPerHost(0)
    , mMaxPersistConnsPerProxy(0)
    , mNumActiveConns(0)
    , mNumIdleConns(0)
{
    LOG(("Creating nsHttpConnectionMgr @%x\n", this));
}

Definition at line 89 of file nsHttpConnectionMgr.cpp.

{
    LOG(("Destroying nsHttpConnectionMgr @%x\n", this));
 
    if (mMonitor)
        nsAutoMonitor::DestroyMonitor(mMonitor);
}

Member Function Documentation

Definition at line 88 of file nsHttpConnectionMgr.h.

    {
        return PR_AtomicIncrement(&mRef);
    }

Here is the call graph for this function:

Definition at line 186 of file nsHttpConnectionMgr.cpp.

{
    LOG(("nsHttpConnectionMgr::AddTransaction [trans=%x %d]\n", trans, priority));

    NS_ADDREF(trans);
    nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgNewTransaction, priority, trans);
    if (NS_FAILED(rv))
        NS_RELEASE(trans);
    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 236 of file nsHttpConnectionMgr.cpp.

{
    LOG(("nsHttpConnectionMgr::AddTransactionToPipeline [pipeline=%x]\n", pipeline));

    NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread");

    nsHttpConnectionInfo *ci = nsnull;
    pipeline->GetConnectionInfo(&ci);
    if (ci) {
        nsCStringKey key(ci->HashKey());
        nsConnectionEntry *ent = (nsConnectionEntry *) mCT.Get(&key);
        if (ent) {
            // search for another request to pipeline...
            PRInt32 i, count = ent->mPendingQ.Count();
            for (i=0; i<count; ++i) {
                nsHttpTransaction *trans = (nsHttpTransaction *) ent->mPendingQ[i];
                if (trans->Caps() & NS_HTTP_ALLOW_PIPELINING) {
                    pipeline->AddTransaction(trans);

                    // remove transaction from pending queue
                    ent->mPendingQ.RemoveElementAt(i);
                    NS_RELEASE(trans);
                    break;
                }
            }
        }
    }
}

Here is the call graph for this function:

Definition at line 470 of file nsHttpConnectionMgr.cpp.

{
    nsHttpConnectionInfo *ci = ent->mConnInfo;

    LOG(("nsHttpConnectionMgr::AtActiveConnectionLimit [ci=%s caps=%x]\n",
        ci->HashKey().get(), caps));

    // use >= just to be safe
    if (mNumActiveConns >= mMaxConns) {
        LOG(("  num active conns == max conns\n"));
        return PR_TRUE;
    }

    nsHttpConnection *conn;
    PRInt32 i, totalCount, persistCount = 0;
    
    totalCount = ent->mActiveConns.Count();

    // count the number of persistent connections
    for (i=0; i<totalCount; ++i) {
        conn = (nsHttpConnection *) ent->mActiveConns[i];
        if (conn->IsKeepAlive()) // XXX make sure this is thread-safe
            persistCount++;
    }

    LOG(("   total=%d, persist=%d\n", totalCount, persistCount));

    PRUint16 maxConns;
    PRUint16 maxPersistConns;

    if (ci->UsingHttpProxy() && !ci->UsingSSL()) {
        maxConns = mMaxConnsPerProxy;
        maxPersistConns = mMaxPersistConnsPerProxy;
    }
    else {
        maxConns = mMaxConnsPerHost;
        maxPersistConns = mMaxPersistConnsPerHost;
    }

    // use >= just to be safe
    return (totalCount >= maxConns) || ( (caps & NS_HTTP_ALLOW_KEEPALIVE) &&
                                         (persistCount >= maxPersistConns) );
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 625 of file nsHttpConnectionMgr.cpp.

{
    if (mMaxPipelinedRequests < 2)
        return PR_FALSE;

    nsHttpPipeline *pipeline = nsnull;
    nsHttpTransaction *trans;

    PRInt32 i = 0, numAdded = 0;
    while (i < ent->mPendingQ.Count()) {
        trans = (nsHttpTransaction *) ent->mPendingQ[i];
        if (trans->Caps() & NS_HTTP_ALLOW_PIPELINING) {
            if (numAdded == 0) {
                pipeline = new nsHttpPipeline;
                if (!pipeline)
                    return PR_FALSE;
                pipeline->AddTransaction(firstTrans);
                numAdded = 1;
            }
            pipeline->AddTransaction(trans);

            // remove transaction from pending queue
            ent->mPendingQ.RemoveElementAt(i);
            NS_RELEASE(trans);

            if (++numAdded == mMaxPipelinedRequests)
                break;
        }
        else
            ++i; // skip to next pending transaction
    }

    if (numAdded == 0)
        return PR_FALSE;

    LOG(("  pipelined %u transactions\n", numAdded));
    NS_ADDREF(*result = pipeline);
    return PR_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 210 of file nsHttpConnectionMgr.cpp.

{
    LOG(("nsHttpConnectionMgr::CancelTransaction [trans=%x reason=%x]\n", trans, reason));

    NS_ADDREF(trans);
    nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgCancelTransaction, reason, trans);
    if (NS_FAILED(rv))
        NS_RELEASE(trans);
    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 573 of file nsHttpConnectionMgr.cpp.

{
    LOG(("nsHttpConnectionMgr::DispatchTransaction [ci=%s trans=%x caps=%x conn=%x]\n",
        ent->mConnInfo->HashKey().get(), trans, caps, conn));

    nsConnectionHandle *handle = new nsConnectionHandle(conn);
    if (!handle)
        return NS_ERROR_OUT_OF_MEMORY;
    NS_ADDREF(handle);

    nsHttpPipeline *pipeline = nsnull;
    if (conn->SupportsPipelining() && (caps & NS_HTTP_ALLOW_PIPELINING)) {
        LOG(("  looking to build pipeline...\n"));
        if (BuildPipeline(ent, trans, &pipeline))
            trans = pipeline;
    }

    // hold an owning ref to this connection
    ent->mActiveConns.AppendElement(conn);
    mNumActiveConns++;
    NS_ADDREF(conn);

    // give the transaction the indirect reference to the connection.
    trans->SetConnection(handle);

    nsresult rv = conn->Activate(trans, caps);

    if (NS_FAILED(rv)) {
        LOG(("  conn->Activate failed [rv=%x]\n", rv));
        ent->mActiveConns.RemoveElement(conn);
        mNumActiveConns--;
        // sever back references to connection, and do so without triggering
        // a call to ReclaimConnection ;-)
        trans->SetConnection(nsnull);
        NS_RELEASE(handle->mConn);
        // destroy the connection
        NS_RELEASE(conn);
    }

    // if we were unable to activate the pipeline, then this will destroy
    // the pipeline, which will cause each the transactions owned by the 
    // pipeline to be restarted.
    NS_IF_RELEASE(pipeline);

    NS_RELEASE(handle);
    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 515 of file nsHttpConnectionMgr.cpp.

{
    LOG(("nsHttpConnectionMgr::GetConnection [ci=%s caps=%x]\n",
        ent->mConnInfo->HashKey().get(), PRUint32(caps)));

    *result = nsnull;

    if (AtActiveConnectionLimit(ent, caps)) {
        LOG(("  at active connection limit!\n"));
        return;
    }

    nsHttpConnection *conn = nsnull;

    if (caps & NS_HTTP_ALLOW_KEEPALIVE) {
        // search the idle connection list
        while (!conn && (ent->mIdleConns.Count() > 0)) {
            conn = (nsHttpConnection *) ent->mIdleConns[0];
            // we check if the connection can be reused before even checking if
            // it is a "matching" connection.
            if (!conn->CanReuse()) {
                LOG(("   dropping stale connection: [conn=%x]\n", conn));
                conn->Close(NS_ERROR_ABORT);
                NS_RELEASE(conn);
            }
            else
                LOG(("   reusing connection [conn=%x]\n", conn));
            ent->mIdleConns.RemoveElementAt(0);
            mNumIdleConns--;
        }
    }

    if (!conn) {
        conn = new nsHttpConnection();
        if (!conn)
            return;
        NS_ADDREF(conn);

        nsresult rv = conn->Init(ent->mConnInfo, mMaxRequestDelay);
        if (NS_FAILED(rv)) {
            NS_RELEASE(conn);
            return;
        }
        
        // We created a new connection that will become active, purge the
        // oldest idle connection if we've reached the upper limit.
        if (mNumIdleConns + mNumActiveConns + 1 > mMaxConns)
            mCT.Enumerate(PurgeOneIdleConnectionCB, this);

        // XXX this just purges a random idle connection.  we should instead
        // enumerate the entire hash table to find the eldest idle connection.
    }

    *result = conn;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 228 of file nsHttpConnectionMgr.cpp.

{
    nsAutoMonitor mon(mMonitor);
    NS_IF_ADDREF(*target = mSTEventTarget);
    return NS_OK;
}

Here is the caller graph for this function:

nsresult nsHttpConnectionMgr::Init ( PRUint16  maxConnections,
PRUint16  maxConnectionsPerHost,
PRUint16  maxConnectionsPerProxy,
PRUint16  maxPersistentConnectionsPerHost,
PRUint16  maxPersistentConnectionsPerProxy,
PRUint16  maxRequestDelay,
PRUint16  maxPipelinedRequests 
)

Definition at line 98 of file nsHttpConnectionMgr.cpp.

{
    LOG(("nsHttpConnectionMgr::Init\n"));

    nsresult rv;
    nsCOMPtr<nsIEventTarget> sts = do_GetService(kSocketTransportServiceCID, &rv);
    if NS_FAILED(rv) return rv;

    nsAutoMonitor mon(mMonitor);

    // do nothing if already initialized
    if (mSTEventTarget)
        return NS_OK;

    // no need to do any special synchronization here since there cannot be
    // any activity on the socket thread (because Shutdown is synchronous).
    mMaxConns = maxConns;
    mMaxConnsPerHost = maxConnsPerHost;
    mMaxConnsPerProxy = maxConnsPerProxy;
    mMaxPersistConnsPerHost = maxPersistConnsPerHost;
    mMaxPersistConnsPerProxy = maxPersistConnsPerProxy;
    mMaxRequestDelay = maxRequestDelay;
    mMaxPipelinedRequests = maxPipelinedRequests;

    mSTEventTarget = sts;
    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsHttpConnectionMgr::OnMsgCancelTransaction ( PRInt32  reason,
void param 
) [private]

Definition at line 789 of file nsHttpConnectionMgr.cpp.

{
    LOG(("nsHttpConnectionMgr::OnMsgCancelTransaction [trans=%p]\n", param));

    nsHttpTransaction *trans = (nsHttpTransaction *) param;
    //
    // if the transaction owns a connection and the transaction is not done,
    // then ask the connection to close the transaction.  otherwise, close the
    // transaction directly (removing it from the pending queue first).
    //
    nsAHttpConnection *conn = trans->Connection();
    if (conn && !trans->IsDone())
        conn->CloseTransaction(trans, reason);
    else {
        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);
                nsHttpTransaction *temp = trans;
                NS_RELEASE(temp); // b/c NS_RELEASE nulls its argument!
            }
        }
        trans->Close(reason);
    }
    NS_RELEASE(trans);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsHttpConnectionMgr::OnMsgNewTransaction ( PRInt32  priority,
void param 
) [private]

Definition at line 754 of file nsHttpConnectionMgr.cpp.

{
    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
    NS_RELEASE(trans);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 820 of file nsHttpConnectionMgr.cpp.

{
    nsHttpConnectionInfo *ci = (nsHttpConnectionInfo *) param;

    LOG(("nsHttpConnectionMgr::OnMsgProcessPendingQ [ci=%s]\n", ci->HashKey().get()));

    // start by processing the queue identified by the given connection info.
    nsCStringKey key(ci->HashKey());
    nsConnectionEntry *ent = (nsConnectionEntry *) mCT.Get(&key);
    if (!(ent && ProcessPendingQForEntry(ent))) {
        // if we reach here, it means that we couldn't dispatch a transaction
        // for the specified connection info.  walk the connection table...
        mCT.Enumerate(ProcessOneTransactionCB, this);
    }

    NS_RELEASE(ci);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 839 of file nsHttpConnectionMgr.cpp.

{
    LOG(("nsHttpConnectionMgr::OnMsgPruneDeadConnections\n"));

    if (mNumIdleConns > 0) 
        mCT.Enumerate(PruneDeadConnectionsCB, this);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 848 of file nsHttpConnectionMgr.cpp.

{
    LOG(("nsHttpConnectionMgr::OnMsgReclaimConnection [conn=%p]\n", param));

    nsHttpConnection *conn = (nsHttpConnection *) param;

    // 
    // 1) remove the connection from the active list
    // 2) if keep-alive, add connection to idle list
    // 3) post event to process the pending transaction queue
    //

    nsHttpConnectionInfo *ci = conn->ConnectionInfo();
    NS_ADDREF(ci);

    nsCStringKey key(ci->HashKey());
    nsConnectionEntry *ent = (nsConnectionEntry *) mCT.Get(&key);

    NS_ASSERTION(ent, "no connection entry");
    if (ent) {
        ent->mActiveConns.RemoveElement(conn);
        mNumActiveConns--;
        if (conn->CanReuse()) {
            LOG(("  adding connection to idle list\n"));
            // hold onto this connection in the idle list.  we push it to
            // the end of the list so as to ensure that we'll visit older
            // connections first before getting to this one.
            ent->mIdleConns.AppendElement(conn);
            mNumIdleConns++;
        }
        else {
            LOG(("  connection cannot be reused; closing connection\n"));
            // make sure the connection is closed and release our reference.
            conn->Close(NS_ERROR_ABORT);
            nsHttpConnection *temp = conn;
            NS_RELEASE(temp);
        }
    }
 
    OnMsgProcessPendingQ(NS_OK, ci); // releases |ci|
    NS_RELEASE(conn);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsHttpConnectionMgr::OnMsgReschedTransaction ( PRInt32  priority,
void param 
) [private]

Definition at line 767 of file nsHttpConnectionMgr.cpp.

{
    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);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 742 of file nsHttpConnectionMgr.cpp.

{
    LOG(("nsHttpConnectionMgr::OnMsgShutdown\n"));

    mCT.Reset(ShutdownPassCB, this);

    // signal shutdown complete
    nsAutoMonitor mon(mMonitor);
    mon.Notify();
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsHttpConnectionMgr::OnMsgUpdateParam ( PRInt32  ,
void param 
) [private]

Definition at line 892 of file nsHttpConnectionMgr.cpp.

Here is the caller graph for this function:

nsresult nsHttpConnectionMgr::PostEvent ( nsConnEventHandler  handler,
PRInt32  iparam = 0,
void vparam = nsnull 
) [private]

Definition at line 161 of file nsHttpConnectionMgr.cpp.

{
    nsAutoMonitor mon(mMonitor);

    nsresult rv;
    if (!mSTEventTarget) {
        NS_WARNING("cannot post event if not initialized");
        rv = NS_ERROR_NOT_INITIALIZED;
    }
    else {
        PLEvent *event = new nsConnEvent(this, handler, iparam, vparam);
        if (!event)
            rv = NS_ERROR_OUT_OF_MEMORY;
        else {
            rv = mSTEventTarget->PostEvent(event);
            if (NS_FAILED(rv))
                PL_DestroyEvent(event);
        }
    }
    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 668 of file nsHttpConnectionMgr.cpp.

{
    // since "adds" and "cancels" are processed asynchronously and because
    // various events might trigger an "add" directly on the socket thread,
    // we must take care to avoid dispatching a transaction that has already
    // been canceled (see bug 190001).
    if (NS_FAILED(trans->Status())) {
        LOG(("  transaction was canceled... dropping event!\n"));
        return NS_OK;
    }

    PRUint8 caps = trans->Caps();
    nsHttpConnectionInfo *ci = trans->ConnectionInfo();
    NS_ASSERTION(ci, "no connection info");

    nsCStringKey key(ci->HashKey());
    nsConnectionEntry *ent = (nsConnectionEntry *) mCT.Get(&key);
    if (!ent) {
        ent = new nsConnectionEntry(ci);
        if (!ent)
            return NS_ERROR_OUT_OF_MEMORY;
        mCT.Put(&key, ent);
    }

    nsHttpConnection *conn;

    // check if the transaction already has a sticky reference to a connection.
    // if so, then we can just use it directly.  XXX check if alive??
    // XXX add a TakeConnection method or something to make this clearer!
    nsConnectionHandle *handle = (nsConnectionHandle *) trans->Connection();
    if (handle) {
        NS_ASSERTION(caps & NS_HTTP_STICKY_CONNECTION, "unexpected caps");
        NS_ASSERTION(handle->mConn, "no connection");

        // steal reference from connection handle.
        // XXX prevent SetConnection(nsnull) from calling ReclaimConnection
        conn = handle->mConn;
        handle->mConn = nsnull;

        // destroy connection handle.
        trans->SetConnection(nsnull);

        // remove sticky connection from active connection list; we'll add it
        // right back in DispatchTransaction.
        if (ent->mActiveConns.RemoveElement(conn))
            mNumActiveConns--;
        else {
            NS_ERROR("sticky connection not found in active list");
            return NS_ERROR_UNEXPECTED;
        }
    }
    else
        GetConnection(ent, caps, &conn);

    nsresult rv;
    if (!conn) {
        LOG(("  adding transaction to pending queue [trans=%x pending-count=%u]\n",
            trans, ent->mPendingQ.Count()+1));
        // put this transaction on the pending queue...
        InsertTransactionSorted(ent->mPendingQ, trans);
        NS_ADDREF(trans);
        rv = NS_OK;
    }
    else {
        rv = DispatchTransaction(ent, trans, caps, conn);
        NS_RELEASE(conn);
    }

    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRIntn PR_CALLBACK nsHttpConnectionMgr::ProcessOneTransactionCB ( nsHashKey *  key,
void data,
void closure 
) [static, private]

Definition at line 300 of file nsHttpConnectionMgr.cpp.

{
    nsHttpConnectionMgr *self = (nsHttpConnectionMgr *) closure;
    nsConnectionEntry *ent = (nsConnectionEntry *) data;

    if (self->ProcessPendingQForEntry(ent))
        return kHashEnumerateStop;

    return kHashEnumerateNext;
}

Here is the caller graph for this function:

Definition at line 285 of file nsHttpConnectionMgr.cpp.

{
    LOG(("nsHttpConnectionMgr::ProcessPendingQ [ci=%s]\n", ci->HashKey().get()));

    NS_ADDREF(ci);
    nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgProcessPendingQ, 0, ci);
    if (NS_FAILED(rv))
        NS_RELEASE(ci);
    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 425 of file nsHttpConnectionMgr.cpp.

{
    LOG(("nsHttpConnectionMgr::ProcessPendingQForEntry [ci=%s]\n",
        ent->mConnInfo->HashKey().get()));

    PRInt32 i, count = ent->mPendingQ.Count();
    if (count > 0) {
        LOG(("  pending-count=%u\n", count));
        nsHttpTransaction *trans = nsnull;
        nsHttpConnection *conn = nsnull;
        for (i=0; i<count; ++i) {
            trans = (nsHttpTransaction *) ent->mPendingQ[i];
            GetConnection(ent, trans->Caps(), &conn);
            if (conn)
                break;
        }
        if (conn) {
            LOG(("  dispatching pending transaction...\n"));

            // remove pending transaction
            ent->mPendingQ.RemoveElementAt(i);

            nsresult rv = DispatchTransaction(ent, trans, trans->Caps(), conn);
            if (NS_SUCCEEDED(rv))
                NS_RELEASE(trans);
            else {
                LOG(("  DispatchTransaction failed [rv=%x]\n", rv));
                // on failure, just put the transaction back
                ent->mPendingQ.InsertElementAt(trans, i);
                // might be something wrong with the connection... close it.
                conn->Close(rv);
            }

            NS_RELEASE(conn);
            return PR_TRUE;
        }
    }
    return PR_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 222 of file nsHttpConnectionMgr.cpp.

Here is the call graph for this function:

PRIntn PR_CALLBACK nsHttpConnectionMgr::PruneDeadConnectionsCB ( nsHashKey *  key,
void data,
void closure 
) [static, private]

Definition at line 330 of file nsHttpConnectionMgr.cpp.

{
    nsHttpConnectionMgr *self = (nsHttpConnectionMgr *) closure;
    nsConnectionEntry *ent = (nsConnectionEntry *) data;

    LOG(("  pruning [ci=%s]\n", ent->mConnInfo->HashKey().get()));

    PRInt32 count = ent->mIdleConns.Count();
    if (count > 0) {
        for (PRInt32 i=count-1; i>=0; --i) {
            nsHttpConnection *conn = (nsHttpConnection *) ent->mIdleConns[i];
            if (!conn->CanReuse()) {
                ent->mIdleConns.RemoveElementAt(i);
                conn->Close(NS_ERROR_ABORT);
                NS_RELEASE(conn);
                self->mNumIdleConns--;
            }
        }
    }

#ifdef DEBUG
    count = ent->mActiveConns.Count();
    if (count > 0) {
        for (PRInt32 i=count-1; i>=0; --i) {
            nsHttpConnection *conn = (nsHttpConnection *) ent->mActiveConns[i];
            LOG(("    active conn [%x] with trans [%x]\n", conn, conn->Transaction()));
        }
    }
#endif

    // if this entry is empty, then we can remove it.
    if (ent->mIdleConns.Count()   == 0 &&
        ent->mActiveConns.Count() == 0 &&
        ent->mPendingQ.Count()    == 0) {
        LOG(("    removing empty connection entry\n"));
        delete ent;
        return kHashEnumerateRemove;
    }

    // else, use this opportunity to compact our arrays...
    ent->mIdleConns.Compact();
    ent->mActiveConns.Compact();
    ent->mPendingQ.Compact();

    return kHashEnumerateNext;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRIntn PR_CALLBACK nsHttpConnectionMgr::PurgeOneIdleConnectionCB ( nsHashKey *  key,
void data,
void closure 
) [static, private]

Definition at line 312 of file nsHttpConnectionMgr.cpp.

{
    nsHttpConnectionMgr *self = (nsHttpConnectionMgr *) closure;
    nsConnectionEntry *ent = (nsConnectionEntry *) data;

    if (ent->mIdleConns.Count() > 0) {
        nsHttpConnection *conn = (nsHttpConnection *) ent->mIdleConns[0];
        ent->mIdleConns.RemoveElementAt(0);
        conn->Close(NS_ERROR_ABORT);
        NS_RELEASE(conn);
        self->mNumIdleConns--;
        return kHashEnumerateStop;
    }

    return kHashEnumerateNext;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 266 of file nsHttpConnectionMgr.cpp.

{
    LOG(("nsHttpConnectionMgr::ReclaimConnection [conn=%x]\n", conn));

    NS_ADDREF(conn);
    nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgReclaimConnection, 0, conn);
    if (NS_FAILED(rv))
        NS_RELEASE(conn);
    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 93 of file nsHttpConnectionMgr.h.

    {
        nsrefcnt n = PR_AtomicDecrement(&mRef);
        if (n == 0)
            delete this;
        return n;
    }

Here is the call graph for this function:

Definition at line 198 of file nsHttpConnectionMgr.cpp.

{
    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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 133 of file nsHttpConnectionMgr.cpp.

{
    LOG(("nsHttpConnectionMgr::Shutdown\n"));

    nsAutoMonitor mon(mMonitor);

    // do nothing if already shutdown
    if (!mSTEventTarget)
        return NS_OK;

    nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgShutdown);

    // release our reference to the STS to prevent further events
    // from being posted.  this is how we indicate that we are
    // shutting down.
    mSTEventTarget = 0;

    if (NS_FAILED(rv)) {
        NS_WARNING("unable to post SHUTDOWN message\n");
        return rv;
    }

    // wait for shutdown event to complete
    mon.Wait();
    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRIntn PR_CALLBACK nsHttpConnectionMgr::ShutdownPassCB ( nsHashKey *  key,
void data,
void closure 
) [static, private]

Definition at line 378 of file nsHttpConnectionMgr.cpp.

{
    nsHttpConnectionMgr *self = (nsHttpConnectionMgr *) closure;
    nsConnectionEntry *ent = (nsConnectionEntry *) data;

    nsHttpTransaction *trans;
    nsHttpConnection *conn;

    // close all active connections
    while (ent->mActiveConns.Count()) {
        conn = (nsHttpConnection *) ent->mActiveConns[0];

        ent->mActiveConns.RemoveElementAt(0);
        self->mNumActiveConns--;

        conn->Close(NS_ERROR_ABORT);
        NS_RELEASE(conn);
    }

    // close all idle connections
    while (ent->mIdleConns.Count()) {
        conn = (nsHttpConnection *) ent->mIdleConns[0];

        ent->mIdleConns.RemoveElementAt(0);
        self->mNumIdleConns--;

        conn->Close(NS_ERROR_ABORT);
        NS_RELEASE(conn);
    }

    // close all pending transactions
    while (ent->mPendingQ.Count()) {
        trans = (nsHttpTransaction *) ent->mPendingQ[0];

        ent->mPendingQ.RemoveElementAt(0);

        trans->Close(NS_ERROR_ABORT);
        NS_RELEASE(trans);
    }

    delete ent;
    return kHashEnumerateRemove;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 278 of file nsHttpConnectionMgr.cpp.

{
    PRUint32 param = (PRUint32(name) << 16) | PRUint32(value);
    return PostEvent(&nsHttpConnectionMgr::OnMsgUpdateParam, 0, (void *) param);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Friends And Related Function Documentation

friend class nsConnEvent [friend]

Definition at line 227 of file nsHttpConnectionMgr.h.


Member Data Documentation

nsHashtable nsHttpConnectionMgr::mCT [private]

Definition at line 288 of file nsHttpConnectionMgr.h.

Definition at line 194 of file nsHttpConnectionMgr.h.

Definition at line 195 of file nsHttpConnectionMgr.h.

Definition at line 196 of file nsHttpConnectionMgr.h.

Definition at line 197 of file nsHttpConnectionMgr.h.

Definition at line 198 of file nsHttpConnectionMgr.h.

Definition at line 200 of file nsHttpConnectionMgr.h.

Definition at line 199 of file nsHttpConnectionMgr.h.

Definition at line 190 of file nsHttpConnectionMgr.h.

Definition at line 279 of file nsHttpConnectionMgr.h.

Definition at line 280 of file nsHttpConnectionMgr.h.

Definition at line 189 of file nsHttpConnectionMgr.h.

Definition at line 191 of file nsHttpConnectionMgr.h.


The documentation for this class was generated from the following files: