SqlConnectionPool.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. //
  2. // System.Data.SqlClient.SqlConnectionPool.cs
  3. //
  4. // Author:
  5. // Tim Coleman ([email protected])
  6. //
  7. // Copyright (C) 2002 Tim Coleman
  8. //
  9. using Mono.Data.Tds.Protocol;
  10. using System;
  11. using System.Collections;
  12. using System.Threading;
  13. namespace System.Data.SqlClient {
  14. internal class SqlConnectionPool : MarshalByRefObject, IList, ICollection, IEnumerable
  15. {
  16. #region Fields
  17. ArrayList list = new ArrayList ();
  18. int maxSize;
  19. int minSize;
  20. int packetSize;
  21. int port;
  22. int timeout;
  23. string dataSource;
  24. #endregion // Fields
  25. #region Constructors
  26. public SqlConnectionPool (string dataSource, int port, int packetSize, int timeout, int minSize, int maxSize)
  27. {
  28. this.dataSource = dataSource;
  29. this.port = port;
  30. this.packetSize = packetSize;
  31. this.timeout = timeout;
  32. this.minSize = minSize;
  33. this.maxSize = maxSize;
  34. }
  35. #endregion // Constructors
  36. #region Properties
  37. public ITds this[int index] {
  38. get { return (ITds) list[index]; }
  39. }
  40. object IList.this[int index] {
  41. get { return this[index]; }
  42. set { throw new InvalidOperationException (); }
  43. }
  44. public int Count {
  45. get { return list.Count; }
  46. }
  47. public bool IsFixedSize {
  48. get { return false; }
  49. }
  50. public bool IsReadOnly {
  51. get { return true; }
  52. }
  53. public bool IsSynchronized {
  54. get { return false; }
  55. }
  56. public int MaxSize {
  57. get { return maxSize; }
  58. }
  59. public int MinSize {
  60. get { return minSize; }
  61. }
  62. public object SyncRoot {
  63. get { throw new InvalidOperationException (); }
  64. }
  65. #endregion // Properties
  66. #region Methods
  67. public int Add (object o)
  68. {
  69. return list.Add ((Tds) o);
  70. }
  71. public void Clear ()
  72. {
  73. list.Clear ();
  74. }
  75. public bool Contains (object o)
  76. {
  77. return list.Contains ((Tds) o);
  78. }
  79. public void CopyTo (Array array, int index)
  80. {
  81. list.CopyTo (array, index);
  82. }
  83. public IEnumerator GetEnumerator ()
  84. {
  85. return list.GetEnumerator ();
  86. }
  87. [MonoTODO ("Handle pool exhaustion.")]
  88. public ITds AllocateConnection ()
  89. {
  90. // make sure we have the minimum count (really only useful the first time)
  91. lock (list) {
  92. for (int i = Count; i < minSize; i += 1)
  93. Add (new Tds70 (dataSource, port, packetSize, timeout));
  94. }
  95. // Try to obtain a lock
  96. foreach (object o in list)
  97. if (Monitor.TryEnter (o))
  98. return (ITds) o;
  99. if (Count < maxSize) {
  100. Tds tds = new Tds70 (dataSource, port, packetSize, timeout);
  101. Monitor.Enter (tds);
  102. Add (tds);
  103. return tds;
  104. }
  105. // else we have to wait for one to be available
  106. return null;
  107. }
  108. public void ReleaseConnection (ITds tds)
  109. {
  110. // Check if connection is still valid
  111. try
  112. {
  113. // Send dummy statement to check connection
  114. tds.Execute("select 1");
  115. }
  116. catch
  117. {
  118. // Remove invalid connection
  119. list.Remove(tds);
  120. }
  121. finally
  122. {
  123. // Release lock
  124. Monitor.Exit (tds);
  125. }
  126. }
  127. public int IndexOf (object o)
  128. {
  129. return list.IndexOf ((Tds) o);
  130. }
  131. public void Insert (int index, object o)
  132. {
  133. list.Insert (index, (Tds) o);
  134. }
  135. public void Remove (object o)
  136. {
  137. list.Remove ((Tds) o);
  138. }
  139. public void RemoveAt (int index)
  140. {
  141. list.RemoveAt (index);
  142. }
  143. #endregion // Methods
  144. }
  145. }