Merge branch 'BigIntegerParse'
[mono.git] / mcs / class / corlib / System.Collections.Concurrent / ConcurrentStack.cs
index 05a5ad976163a899fba74011ad5592ee9a6d81b5..49d875e524fff02acfc01074e478054b7ad9c217 100644 (file)
@@ -1,6 +1,10 @@
 // ConcurrentStack.cs
 //
+// Authors:
+//     Marek Safar  <marek.safar@gmail.com>
+//
 // Copyright (c) 2008 Jérémie "Garuma" Laval
+// Copyright (C) 2014 Xamarin Inc (http://www.xamarin.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to deal
@@ -22,7 +26,7 @@
 //
 //
 
-#if NET_4_0 || MOBILE
+#if NET_4_0
 
 using System;
 using System.Threading;
@@ -41,27 +45,12 @@ namespace System.Collections.Concurrent
                class Node
                {
                        public T Value = default (T);
-                       public Node Next = null;
+                       public Node Next;
                }
                
-               Node head = null;
+               Node head;
                
                int count;
-
-               class NodeObjectPool : ObjectPool<Node> {
-                       protected override Node Creator ()
-                       {
-                               return new Node ();
-                       }
-               }
-               static readonly NodeObjectPool pool = new NodeObjectPool ();
-
-               static Node ZeroOut (Node node)
-               {
-                       node.Value = default(T);
-                       node.Next = null;
-                       return node;
-               }
                
                public ConcurrentStack ()
                {
@@ -69,6 +58,9 @@ namespace System.Collections.Concurrent
                
                public ConcurrentStack (IEnumerable<T> collection)
                {
+                       if (collection == null)
+                               throw new ArgumentNullException ("collection");
+
                        foreach (T item in collection) 
                                Push (item);
                }
@@ -81,7 +73,7 @@ namespace System.Collections.Concurrent
                
                public void Push (T item)
                {
-                       Node temp = pool.Take ();
+                       Node temp = new Node ();
                        temp.Value = item;
                        do {
                          temp.Next = head;
@@ -92,16 +84,21 @@ namespace System.Collections.Concurrent
 
                public void PushRange (T[] items)
                {
+                       if (items == null)
+                               throw new ArgumentNullException ("items");
+
                        PushRange (items, 0, items.Length);
                }
                
                public void PushRange (T[] items, int startIndex, int count)
                {
+                       RangeArgumentsCheck (items, startIndex, count);
+
                        Node insert = null;
                        Node first = null;
                        
                        for (int i = startIndex; i < count; i++) {
-                               Node temp = pool.Take ();
+                               Node temp = new Node ();
                                temp.Value = items[i];
                                temp.Next = insert;
                                insert = temp;
@@ -132,7 +129,6 @@ namespace System.Collections.Concurrent
                        Interlocked.Decrement (ref count);
                        
                        result = temp.Value;
-                       pool.Release (ZeroOut (temp));
 
                        return true;
                }
@@ -146,14 +142,7 @@ namespace System.Collections.Concurrent
 
                public int TryPopRange (T[] items, int startIndex, int count)
                {
-                       if (items == null)
-                               throw new ArgumentNullException ("items");
-                       if (startIndex < 0 || startIndex >= items.Length)
-                               throw new ArgumentOutOfRangeException ("startIndex");
-                       if (count < 0)
-                               throw new ArgumentOutOfRangeException ("count");
-                       if (startIndex + count > items.Length)
-                               throw new ArgumentException ("startIndex + count is greater than the length of items.");
+                       RangeArgumentsCheck (items, startIndex, count);
 
                        Node temp;
                        Node end;
@@ -161,7 +150,7 @@ namespace System.Collections.Concurrent
                        do {
                                temp = head;
                                if (temp == null)
-                                       return -1;
+                                       return 0;
                                end = temp;
                                for (int j = 0; j < count; j++) {
                                        end = end.Next;
@@ -175,9 +164,8 @@ namespace System.Collections.Concurrent
                                items[i] = temp.Value;
                                end = temp;
                                temp = temp.Next;
-                               pool.Release (ZeroOut (end));
                        }
-                       this.count -= (i - startIndex);
+                       Interlocked.Add (ref this.count, -(i - startIndex));
                        
                        return i - startIndex;
                }
@@ -224,23 +212,30 @@ namespace System.Collections.Concurrent
                
                void ICollection.CopyTo (Array array, int index)
                {
-                       T[] dest = array as T[];
-                       if (dest == null)
-                               return;
-                       CopyTo (dest, index);
+                       ICollection ic = new List<T> (this);
+                       ic.CopyTo (array, index);
                }
                
                public void CopyTo (T[] array, int index)
                {
+                       if (array == null)
+                               throw new ArgumentNullException ("array");
+                       if (index < 0)
+                               throw new ArgumentOutOfRangeException ("index");
+                       if (index > array.Length)
+                               throw new ArgumentException ("index is equals or greather than array length", "index");
+
                        IEnumerator<T> e = InternalGetEnumerator ();
                        int i = index;
                        while (e.MoveNext ()) {
+                               if (i == array.Length - index)
+                                       throw new ArgumentException ("The number of elememts in the collection exceeds the capacity of array", "array");
                                array[i++] = e.Current;
                        }
                }
                
                bool ICollection.IsSynchronized {
-                       get { return true; }
+                       get { return false; }
                }
                
                bool IProducerConsumerCollection<T>.TryTake (out T item)
@@ -248,16 +243,15 @@ namespace System.Collections.Concurrent
                        return TryPop (out item);
                }
                
-               object syncRoot = new object ();
                object ICollection.SyncRoot {
-                       get { return syncRoot; }
+                       get {
+                               throw new NotSupportedException ();
+                       }
                }
                
                public T[] ToArray ()
                {
-                       T[] dest = new T [count];
-                       CopyTo (dest, 0);
-                       return dest;
+                       return new List<T> (this).ToArray ();
                }
                
                public int Count {
@@ -271,6 +265,18 @@ namespace System.Collections.Concurrent
                                return count == 0;
                        }
                }
+
+               static void RangeArgumentsCheck (T[] items, int startIndex, int count)
+               {
+                       if (items == null)
+                               throw new ArgumentNullException ("items");
+                       if (startIndex < 0 || startIndex >= items.Length)
+                               throw new ArgumentOutOfRangeException ("startIndex");
+                       if (count < 0)
+                               throw new ArgumentOutOfRangeException ("count");
+                       if (startIndex + count > items.Length)
+                               throw new ArgumentException ("startIndex + count is greater than the length of items.");
+               }
        }
 }
 #endif