/// <summary> /// Put the AdvanConnect connection back into the connection pool /// to make it available to others. /// </summary> /// <param name="advanConnect"></param> static internal void Put(AdvanConnect advanConnect) { if (advanConnect == null) // safety check { return; } ConnectionPool pool = advanConnect.connectionPool; if (advanConnect.msg != null && advanConnect.msg.isSocketConnected() == false) { // underlying connection socket to msg is damaged advanConnect.CanBePooled = false; } // if cannot be pooled if (advanConnect.CanBePooled == false || pool == null) { // Null out connectionPool reference to avoid the close() // method trying to remove the connection pool slot. // We will do it ourselves. advanConnect.connectionPool = null; // Console.WriteLine("Closing connection physically by Put"); advanConnect.close(); // close the internal connection // if connection was in the pool in the past but is now damaged if (pool != null) { pool.PutPoolSlot(null); // release the pool slot } } else { pool.PutPoolSlot(advanConnect); // put good conn back into pool } return; }
/// <summary> /// Worker thread that cleans up timed-out connections. /// </summary> static internal void ConnectionPoolWorkerThread() { bool shuttingDown = false; // Console.WriteLine("ConnectionPoolWorkerThread started"); while (true) { bool didWork = false; DateTime now = DateTime.Now; ArrayList pools = null; // Wait on the lock for the pool of pools since // the ConnectionPoolManager.Get might have it and // is declaring its intent to get a slot from one of the pools. lock (poolOfConnectionPools) { pools = new ArrayList(poolOfConnectionPools.Keys); foreach (object obj in pools) { string key = (string)obj; // connection string ConnectionPool pool = (ConnectionPool)poolOfConnectionPools[key]; // if no active slots and no connecting // and no inactive connections and too old if (pool.IsTooOld(now)) { // disconnect old, empty pool from the pool of pools poolOfConnectionPools.Remove(key); } } // Get a snapshot list of pools. Other threads might // be adding more pools to the pool of pools but we // don't care; we'll catch on the next timer iteration. // We are the only thread that removes pools so we // the snapahot will be good for this iteration. pools = new ArrayList(poolOfConnectionPools.Values); // release our lock on the pool of pools } // end lock(poolOfConnectionPools) foreach (object obj in pools) { ConnectionPool pool = (ConnectionPool)obj; // We now have a pool that we can check for inactive // physical connections that we can close physically. while (true) // loop thru the connections in the pool { AdvanConnect advanConnect = null; advanConnect = pool.GetPoolSlotExpired(shuttingDown); if (advanConnect == null) { break; } try { // Console.WriteLine("Closing connection physically"+ // " by ConnectionPoolWorkerThread"); // Close the connection. Do not hold any // locks for the pool of pools or a pool since // the I/O for the close may take a long time. advanConnect.close(); // close the connection } catch {} didWork = true; } } if (didWork) // if we did something then restart the scan { continue; } pools = null; // release the object to garbage collection if (shuttingDown) { // Console.WriteLine("ConnectionPoolWorkerThread returning"); return; } // sleep 10 seconds or until shutdown signaled shuttingDown = shuttingDownEvent.WaitOne(10000, false); // if (shuttingDown) // Console.WriteLine("ConnectionPoolWorkerThread ShuttingDown"); //Thread.Sleep(10000); // sleep 10 seconds } // end while }