5e0a23e2b5af355b77a406b99171713ce3d9c200
[mono.git] / mcs / class / System / System.Net / WebConnectionGroup.cs
1 //
2 // System.Net.WebConnectionGroup
3 //
4 // Authors:
5 //      Gonzalo Paniagua Javier (gonzalo@ximian.com)
6 //
7 // (C) 2003 Ximian, Inc (http://www.ximian.com)
8 //
9
10 using System;
11 using System.Collections;
12 using System.Configuration;
13 using System.Net.Configuration;
14 using System.Net.Sockets;
15
16 namespace System.Net
17 {
18         class WebConnectionGroup
19         {
20                 ServicePoint sPoint;
21                 string name;
22                 ArrayList connections;
23                 static ConnectionManagementData manager;
24                 const string configKey = "system.net/connectionManagement";
25                 int maxConnections;
26                 Random rnd;
27
28                 static WebConnectionGroup ()
29                 {
30                         manager = (ConnectionManagementData) ConfigurationSettings.GetConfig (configKey);
31                 }
32
33                 public WebConnectionGroup (ServicePoint sPoint, string name)
34                 {
35                         this.sPoint = sPoint;
36                         this.name = name;
37                         connections = new ArrayList (1);
38                         maxConnections = (int) manager.GetMaxConnections (sPoint.Address.Host);
39                 }
40
41                 public WebConnection GetConnection (string name)
42                 {
43                         WebConnection cnc = null;
44                         lock (connections) {
45                                 WeakReference cncRef = null;
46
47                                 // Remove disposed connections
48                                 int end = connections.Count;
49                                 ArrayList removed = null;
50                                 for (int i = 0; i < end; i++) {
51                                         cncRef = (WeakReference) connections [i];
52                                         cnc = cncRef.Target as WebConnection;
53                                         if (cnc == null) {
54                                                 if (removed == null)
55                                                         removed = new ArrayList (1);
56
57                                                 removed.Add (i);
58                                         }
59                                 }
60
61                                 if (removed != null) {
62                                         for (int i = removed.Count - 1; i >= 0; i--)
63                                                 connections.RemoveAt ((int) removed [i]);
64                                 }
65
66                                 cnc = CreateOrReuseConnection ();
67                         }
68
69                         return cnc;
70                 }
71
72                 WebConnection CreateOrReuseConnection ()
73                 {
74                         // lock is up there.
75                         WebConnection cnc;
76                         WeakReference cncRef;
77
78                         int count = connections.Count;
79                         if (maxConnections > count) {
80                                 cnc = new WebConnection (this, sPoint);
81                                 connections.Add (new WeakReference (cnc));
82                                 return cnc;
83                         }
84
85                         if (rnd == null)
86                                 rnd = new Random ();
87
88                         foreach (WeakReference wr in connections) {
89                                 cnc = wr.Target as WebConnection;
90                                 if (cnc.Busy)
91                                         continue;
92
93                                 return cnc;
94                         }
95
96                         int idx = (count > 1) ? rnd.Next (0, count - 1) : 0;
97                         cncRef = (WeakReference) connections [idx];
98                         cnc = cncRef.Target as WebConnection;
99                         if (cnc == null) {
100                                 cnc = new WebConnection (this, sPoint);
101                                 connections.RemoveAt (idx);
102                                 connections.Add (new WeakReference (cnc));
103                         }
104                         return cnc;
105                 }
106
107                 public string Name {
108                         get { return name; }
109                 }
110                 
111         }
112 }
113