Found some more remaining traces of Microsoft's scrapyard and killed them; removed WinRT support
git-svn-id: file:///srv/devel/repo-conversion/nusu@315 d2e56fa2-650e-0410-a79f-9358c0239efd
This commit is contained in:
		
							parent
							
								
									b1b1f02e6f
								
							
						
					
					
						commit
						b6fe183994
					
				
					 12 changed files with 22 additions and 640 deletions
				
			
		|  | @ -276,10 +276,6 @@ | |||
|     <Compile Include="Source\TypeHelper.Test.cs"> | ||||
|       <DependentUpon>TypeHelper.cs</DependentUpon> | ||||
|     </Compile> | ||||
|     <Compile Include="Source\Semaphore.cs" /> | ||||
|     <Compile Include="Source\Semaphore.Test.cs"> | ||||
|       <DependentUpon>Semaphore.cs</DependentUpon> | ||||
|     </Compile> | ||||
|     <Compile Include="Source\FloatHelper.cs" /> | ||||
|     <Compile Include="Source\FloatHelper.Test.cs"> | ||||
|       <DependentUpon>FloatHelper.cs</DependentUpon> | ||||
|  | @ -309,9 +305,6 @@ | |||
|       <DependentUpon>StringSegment.cs</DependentUpon> | ||||
|     </Compile> | ||||
|     <Compile Include="Source\WeakReference.cs" /> | ||||
|     <Compile Include="Source\WeakReference.Phone7.cs"> | ||||
|       <DependentUpon>WeakReference.cs</DependentUpon> | ||||
|     </Compile> | ||||
|     <Compile Include="Source\WeakReference.Test.cs"> | ||||
|       <DependentUpon>WeakReference.cs</DependentUpon> | ||||
|     </Compile> | ||||
|  |  | |||
|  | @ -21,7 +21,7 @@ using System.Runtime.InteropServices; | |||
| // The following GUID is for the ID of the typelib if this project is exposed to COM | ||||
| [assembly: Guid("1308e4c3-a0c1-423a-aaae-61c7314777e0")] | ||||
| 
 | ||||
| #if !(WINDOWS_PHONE || XBOX360) && UNITTEST | ||||
| #if UNITTEST | ||||
| // This is required to NMock can derive its proxies from interfaces in | ||||
| // the internal unit test classes | ||||
| [assembly: InternalsVisibleTo(NMock.Constants.InternalsVisibleToDynamicProxy)] | ||||
|  |  | |||
|  | @ -49,11 +49,7 @@ namespace Nuclex.Support { | |||
|   public static class AffineThreadPool { | ||||
| 
 | ||||
|     /// <summary>Number of CPU cores available on the system</summary> | ||||
| #if XBOX360 | ||||
|     public static readonly int Processors = 4; | ||||
| #else | ||||
|     public static readonly int Processors = Environment.ProcessorCount; | ||||
| #endif | ||||
| 
 | ||||
|     /// <summary>Delegate used by the thread pool to report unhandled exceptions</summary> | ||||
|     /// <param name="exception">Exception that has not been handled</param> | ||||
|  | @ -88,25 +84,16 @@ namespace Nuclex.Support { | |||
|       // as we may run into situations where multiple operations need to be atomic. | ||||
|       // We keep track of the threads we've created just for good measure; not actually | ||||
|       // needed for any core functionality. | ||||
| #if XBOX360 || WINDOWS_PHONE | ||||
|       workAvailable = new Semaphore(); | ||||
| #else | ||||
|       workAvailable = new System.Threading.Semaphore(0, int.MaxValue); | ||||
| #endif | ||||
|       userWorkItems = new Queue<UserWorkItem>(Processors * 4); | ||||
|       workerThreads = new List<Thread>(Processors); | ||||
|       inUseThreads = 0; | ||||
| 
 | ||||
| #if XBOX360 | ||||
|       // We can only use these hardware thread indices on the XBox 360 | ||||
|       hardwareThreads = new Queue<int>(new int[] { 5, 4, 3, 1 }); | ||||
| #else | ||||
|       // We can use all cores on a PC, starting from index 1 | ||||
|       hardwareThreads = new Queue<int>(Processors); | ||||
|       for(int core = Processors; core >= 1; --core) { | ||||
|         hardwareThreads.Enqueue(core); | ||||
|       } | ||||
| #endif | ||||
| 
 | ||||
|       // Create all of the worker threads | ||||
|       for(int index = 0; index < Processors; index++) { | ||||
|  | @ -211,12 +198,7 @@ namespace Nuclex.Support { | |||
|         hardwareThreadIndex = hardwareThreads.Dequeue(); | ||||
|       } | ||||
| 
 | ||||
| #if XBOX360 | ||||
|       // On the XBox 360, the only way to get a thread to run on another core is to | ||||
|       // explicitly move it to that core. MSDN states that SetProcessorAffinity() should | ||||
|       // be called from the thread whose affinity is being changed. | ||||
|       Thread.CurrentThread.SetProcessorAffinity(new int[] { hardwareThreadIndex }); | ||||
| #elif WINDOWS | ||||
| #if WINDOWS | ||||
|       if(Environment.OSVersion.Platform == PlatformID.Win32NT) { | ||||
|         // Prevent this managed thread from impersonating another system thread. | ||||
|         // In .NET, managed threads can supposedly be moved to different system threads | ||||
|  | @ -303,11 +285,7 @@ namespace Nuclex.Support { | |||
|     /// <summary> | ||||
|     ///   Used to let the threads in the thread pool wait for new work to appear. | ||||
|     /// </summary> | ||||
| #if XBOX360 || WINDOWS_PHONE | ||||
|     private static Semaphore workAvailable; | ||||
| #else | ||||
|     private static System.Threading.Semaphore workAvailable; | ||||
| #endif | ||||
|     /// <summary>List of all worker threads at the disposal of the thread pool.</summary> | ||||
|     private static List<Thread> workerThreads; | ||||
|     /// <summary>Number of threads currently active.</summary> | ||||
|  |  | |||
|  | @ -161,11 +161,7 @@ namespace Nuclex.Support.Cloning { | |||
|     /// <returns>A clone of the original instance</returns> | ||||
|     private static object shallowCloneComplexFieldBased(object original) { | ||||
|       Type originalType = original.GetType(); | ||||
| #if (XBOX360 || WINDOWS_PHONE) | ||||
|       object clone = Activator.CreateInstance(originalType); | ||||
| #else | ||||
|       object clone = FormatterServices.GetUninitializedObject(originalType); | ||||
| #endif | ||||
| 
 | ||||
|       FieldInfo[] fieldInfos = originalType.GetFieldInfosIncludingBaseClasses( | ||||
|         BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | ||||
|  | @ -243,11 +239,7 @@ namespace Nuclex.Support.Cloning { | |||
|     /// <returns>A clone of the original instance</returns> | ||||
|     private static object deepCloneComplexFieldBased(object original) { | ||||
|       Type originalType = original.GetType(); | ||||
| #if (XBOX360 || WINDOWS_PHONE) | ||||
|       object clone = Activator.CreateInstance(originalType); | ||||
| #else | ||||
|       object clone = FormatterServices.GetUninitializedObject(originalType); | ||||
| #endif | ||||
| 
 | ||||
|       FieldInfo[] fieldInfos = originalType.GetFieldInfosIncludingBaseClasses( | ||||
|         BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | ||||
|  |  | |||
|  | @ -18,8 +18,6 @@ License along with this library | |||
| */ | ||||
| #endregion | ||||
| 
 | ||||
| #if !(XBOX360 || WINDOWS_PHONE) | ||||
| 
 | ||||
| using System; | ||||
| using System.IO; | ||||
| using System.Reflection; | ||||
|  | @ -328,5 +326,3 @@ namespace Nuclex.Support.Cloning { | |||
|   } | ||||
| 
 | ||||
| } // namespace Nuclex.Support.Cloning | ||||
| 
 | ||||
| #endif // !(XBOX360 || WINDOWS_PHONE) | ||||
|  |  | |||
|  | @ -1,3 +1,23 @@ | |||
| #region CPL License | ||||
| /* | ||||
| Nuclex Framework | ||||
| Copyright (C) 2002-2014 Nuclex Development Labs | ||||
| 
 | ||||
| This library is free software; you can redistribute it and/or | ||||
| modify it under the terms of the IBM Common Public License as | ||||
| published by the IBM Corporation; either version 1.0 of the | ||||
| License, or (at your option) any later version. | ||||
| 
 | ||||
| This library is distributed in the hope that it will be useful, | ||||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
| IBM Common Public License for more details. | ||||
| 
 | ||||
| You should have received a copy of the IBM Common Public | ||||
| License along with this library | ||||
| */ | ||||
| #endregion | ||||
| 
 | ||||
| #if !NO_CONCURRENT_COLLECTIONS | ||||
| 
 | ||||
| using System; | ||||
|  | @ -13,11 +33,7 @@ namespace Nuclex.Support { | |||
|   public abstract class ParallelBackgroundWorker<TTask> : IDisposable { | ||||
| 
 | ||||
|     /// <summary>Number of CPU cores available on the system</summary> | ||||
| #if XBOX360 | ||||
|     public static readonly int Processors = 4; | ||||
| #else | ||||
|     public static readonly int Processors = Environment.ProcessorCount; | ||||
| #endif | ||||
| 
 | ||||
|     /// <summary> | ||||
|     ///   Timeout after which Dispose() will stop waiting for unfinished tasks and | ||||
|  |  | |||
|  | @ -1,127 +0,0 @@ | |||
| #region CPL License | ||||
| /* | ||||
| Nuclex Framework | ||||
| Copyright (C) 2002-2014 Nuclex Development Labs | ||||
| 
 | ||||
| This library is free software; you can redistribute it and/or | ||||
| modify it under the terms of the IBM Common Public License as | ||||
| published by the IBM Corporation; either version 1.0 of the | ||||
| License, or (at your option) any later version. | ||||
| 
 | ||||
| This library is distributed in the hope that it will be useful, | ||||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
| IBM Common Public License for more details. | ||||
| 
 | ||||
| You should have received a copy of the IBM Common Public | ||||
| License along with this library | ||||
| */ | ||||
| #endregion | ||||
| 
 | ||||
| #if UNITTEST | ||||
| 
 | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Threading; | ||||
| 
 | ||||
| using NUnit.Framework; | ||||
| 
 | ||||
| namespace Nuclex.Support { | ||||
| 
 | ||||
|   /// <summary>Unit Test for the Semaphore class</summary> | ||||
|   [ | ||||
|     TestFixture, | ||||
|     Obsolete("Not obsolete, prevents warning when unit-testing custom Semaphore on Windows") | ||||
|   ] | ||||
|   internal class SemaphoreTest { | ||||
| 
 | ||||
|     /// <summary> | ||||
|     ///   Test whether a semaphore can be initialized with reverse counting | ||||
|     /// </summary> | ||||
|     [Test] | ||||
|     public void TestReverseCountingConstructor() { | ||||
|       using(Semaphore semaphore = new Semaphore()) { | ||||
|         Assert.IsNotNull(semaphore); // nonsense, avoids compiler warning | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     ///   Test whether a semaphore can be initialized with a maximum user count | ||||
|     /// </summary> | ||||
|     [Test] | ||||
|     public void TestLimitConstructor() { | ||||
|       using(Semaphore semaphore = new Semaphore(16)) { | ||||
|         Assert.IsNotNull(semaphore); // nonsense, avoids compiler warning | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     ///   Test whether a semaphore can be initialized with an initial user | ||||
|     ///   count and a maximum user count | ||||
|     /// </summary> | ||||
|     [Test] | ||||
|     public void TestFullConstructor() { | ||||
|       using(Semaphore semaphore = new Semaphore(8, 16)) { | ||||
|         Assert.IsNotNull(semaphore); // nonsense, avoids compiler warning | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     ///   Verifies that the right exception is thrown if a semaphore is initialized | ||||
|     ///   with a larger number of initial users than the maximum number of users. | ||||
|     /// </summary> | ||||
|     [Test] | ||||
|     public void TestThrowOnMoreInitialUsersThanMaximumUsers() { | ||||
|       Assert.Throws<ArgumentOutOfRangeException>( | ||||
|         delegate() { | ||||
|           Semaphore semaphore = new Semaphore(2, 1); | ||||
|           semaphore.Close(); | ||||
|         } | ||||
|       ); | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     ///   Verifies that the semaphore can time out if the resource does not become | ||||
|     ///   available within the time limit specified by the user | ||||
|     /// </summary> | ||||
|     [Test] | ||||
|     public void TestWaitTimeout() { | ||||
|       using(Semaphore semaphore = new Semaphore(1)) { | ||||
|         Assert.IsTrue(semaphore.WaitOne(1000)); | ||||
|         Assert.IsFalse(semaphore.WaitOne(0)); | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     ///   Verifies that the semaphore can time out if the resource does not become | ||||
|     ///   available within the time limit specified by the user, if the time limit | ||||
|     ///   is specified using the TimeSpan class | ||||
|     /// </summary> | ||||
|     [Test] | ||||
|     public void TestWaitTimeoutWithTimeSpan() { | ||||
|       using(Semaphore semaphore = new Semaphore(1)) { | ||||
|         Assert.IsTrue(semaphore.WaitOne(TimeSpan.FromSeconds(1))); | ||||
|         Assert.IsFalse(semaphore.WaitOne(TimeSpan.FromSeconds(0))); | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     ///   Tests whether an exception is thrown if the WaitOne() method is called | ||||
|     ///   with a time span that is too large for the underlying synchronization API | ||||
|     /// </summary> | ||||
|     [Test] | ||||
|     public void TestThrowOnWaitWithTooLargeTimeSpan() { | ||||
|       using(Semaphore semaphore = new Semaphore(1)) { | ||||
|         Assert.Throws<ArgumentOutOfRangeException>( | ||||
|           delegate() { | ||||
|             semaphore.WaitOne(TimeSpan.FromMilliseconds(1L << 32)); | ||||
|           } | ||||
|         ); | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|   } | ||||
| 
 | ||||
| } // namespace Nuclex.Support | ||||
| 
 | ||||
| #endif // UNITTEST | ||||
|  | @ -1,248 +0,0 @@ | |||
| #region CPL License | ||||
| /* | ||||
| Nuclex Framework | ||||
| Copyright (C) 2002-2014 Nuclex Development Labs | ||||
| 
 | ||||
| This library is free software; you can redistribute it and/or | ||||
| modify it under the terms of the IBM Common Public License as | ||||
| published by the IBM Corporation; either version 1.0 of the | ||||
| License, or (at your option) any later version. | ||||
| 
 | ||||
| This library is distributed in the hope that it will be useful, | ||||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
| IBM Common Public License for more details. | ||||
| 
 | ||||
| You should have received a copy of the IBM Common Public | ||||
| License along with this library | ||||
| */ | ||||
| #endregion | ||||
| 
 | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Threading; | ||||
| 
 | ||||
| namespace Nuclex.Support { | ||||
| 
 | ||||
|   /// <summary>A reverse counting semaphore</summary> | ||||
|   /// <remarks> | ||||
|   ///   <para> | ||||
|   ///     This semaphore counts in reverse, which means you can Release() the semaphore | ||||
|   ///     as often as you'd like a thread calling WaitOne() to be let through. You | ||||
|   ///     can use it in the traditional sense and have any Thread calling WaitOne() | ||||
|   ///     make sure to call Release() afterwards, or you can, for example, Release() it | ||||
|   ///     whenever work becomes available and let threads take work from the Semaphore | ||||
|   ///     by calling WaitOne() alone. | ||||
|   ///   </para> | ||||
|   ///   <para> | ||||
|   ///     Implementation notes (ignore this if you just want to use the Semaphore) | ||||
|   ///   </para> | ||||
|   ///   <para> | ||||
|   ///     We could design a semaphore that uses an auto reset event, where the thread | ||||
|   ///     that gets to pass immediately sets the event again if the semaphore isn't full | ||||
|   ///     yet to let another thread pass. | ||||
|   ///   </para> | ||||
|   ///   <para> | ||||
|   ///     However, this would mean that when a semaphore receives a large number of | ||||
|   ///     wait requests, assuming it would allow, for example, 25 users at once, the | ||||
|   ///     thread scheduler would see only 1 thread become eligible for execution. Then | ||||
|   ///     that thread would unlock the next and so on. In short, we wait 25 times | ||||
|   ///     for the thread scheduler to wake up a thread until all users get through. | ||||
|   ///   </para> | ||||
|   ///   <para> | ||||
|   ///     So we chose a ManualResetEvent, which will wake up more threads than | ||||
|   ///     neccessary and possibly cause a period of intense competition for getting | ||||
|   ///     a lock on the resource, but will make the thread scheduler see all threads | ||||
|   ///     become eligible for execution. | ||||
|   ///   </para> | ||||
|   /// </remarks> | ||||
| #if WINDOWS | ||||
|   [Obsolete("Prefer the normal semaphore on Windows builds.")] | ||||
|   internal class Semaphore : WaitHandle { | ||||
| #else | ||||
|   public class Semaphore : WaitHandle { | ||||
| #endif | ||||
| 
 | ||||
|     /// <summary>Initializes a new semaphore</summary> | ||||
|     public Semaphore() { | ||||
|       createEvent(); | ||||
|     } | ||||
| 
 | ||||
|     /// <summary>Initializes a new semaphore</summary> | ||||
|     /// <param name="count"> | ||||
|     ///   Number of users that can access the resource at the same time | ||||
|     /// </param> | ||||
|     public Semaphore(int count) { | ||||
|       this.free = count; | ||||
| 
 | ||||
|       createEvent(); | ||||
|     } | ||||
| 
 | ||||
|     /// <summary>Initializes a new semaphore</summary> | ||||
|     /// <param name="initialCount"> | ||||
|     ///   Initial number of users accessing the resource  | ||||
|     /// </param> | ||||
|     /// <param name="maximumCount"> | ||||
|     ///   Maximum numbr of users that can access the resource at the same time | ||||
|     /// </param> | ||||
|     public Semaphore(int initialCount, int maximumCount) { | ||||
|       if(initialCount > maximumCount) { | ||||
|         throw new ArgumentOutOfRangeException( | ||||
|           "initialCount", "Initial count must not be larger than the maximum count" | ||||
|         ); | ||||
|       } | ||||
| 
 | ||||
|       this.free = maximumCount - initialCount; | ||||
|       createEvent(); | ||||
|     } | ||||
| 
 | ||||
|     /// <summary>Immediately releases all resources owned by the instance</summary> | ||||
|     /// <param name="explicitDisposing"> | ||||
|     ///   Whether Dispose() has been called explictly | ||||
|     /// </param> | ||||
|     protected override void Dispose(bool explicitDisposing) { | ||||
|       if(this.manualResetEvent != null) { | ||||
|         base.SafeWaitHandle = null; | ||||
| 
 | ||||
|         this.manualResetEvent.Close(); | ||||
|         this.manualResetEvent = null; | ||||
|       } | ||||
| 
 | ||||
|       base.Dispose(explicitDisposing); | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     ///   Waits for the resource to become available and locks it | ||||
|     /// </summary> | ||||
|     /// <param name="millisecondsTimeout"> | ||||
|     ///   Number of milliseconds to wait at most before giving up | ||||
|     /// </param> | ||||
|     /// <param name="exitContext"> | ||||
|     ///   True to exit the synchronization domain for the context before the wait (if | ||||
|     ///   in a synchronized context), and reacquire it afterward; otherwise, false. | ||||
|     /// </param> | ||||
|     /// <returns> | ||||
|     ///   True if the resource was available and is now locked, false if | ||||
|     ///   the timeout has been reached. | ||||
|     /// </returns> | ||||
| #if NO_EXITCONTEXT | ||||
|     public override bool WaitOne(int millisecondsTimeout) { | ||||
| #else | ||||
|     public override bool WaitOne(int millisecondsTimeout, bool exitContext) { | ||||
| #endif | ||||
|       for (; ; ) { | ||||
| 
 | ||||
|         // Lock the resource - even if it is full. We will correct out mistake later | ||||
|         // if we overcomitted the resource. | ||||
|         int newFree = Interlocked.Decrement(ref this.free); | ||||
| 
 | ||||
|         // If we got the resource, let the thread pass without further processing. | ||||
|         if(newFree >= 0) { | ||||
|           if(newFree > 0) { | ||||
|             this.manualResetEvent.Set(); | ||||
|           } | ||||
| 
 | ||||
|           return true; | ||||
|         } | ||||
| 
 | ||||
|         // We overcomitted the resource, count it down again. We know that, at least | ||||
|         // moments ago, the resource was busy, so block the event. | ||||
|         this.manualResetEvent.Reset(); | ||||
|         Thread.MemoryBarrier(); | ||||
|         newFree = Interlocked.Increment(ref this.free); | ||||
| 
 | ||||
|         // Unless we have been preempted by a Release(), we now have to wait for the | ||||
|         // resource to become available. | ||||
|         if(newFree >= 0) { | ||||
| #if NO_EXITCONTEXT | ||||
|           if(!this.manualResetEvent.WaitOne(millisecondsTimeout)) { | ||||
| #else | ||||
|           if(!this.manualResetEvent.WaitOne(millisecondsTimeout, exitContext)) { | ||||
| #endif | ||||
|             return false; | ||||
|           } | ||||
|         } | ||||
| 
 | ||||
|       } // for(; ; ) | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     ///   Waits for the resource to become available and locks it | ||||
|     /// </summary> | ||||
|     /// <returns> | ||||
|     ///   True if the resource was available and is now locked, false if | ||||
|     ///   the timeout has been reached. | ||||
|     /// </returns> | ||||
|     public override bool WaitOne() { | ||||
| #if NO_EXITCONTEXT | ||||
|       return WaitOne(-1); | ||||
| #else | ||||
|       return WaitOne(-1, false); | ||||
| #endif | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     ///   Waits for the resource to become available and locks it | ||||
|     /// </summary> | ||||
|     /// <param name="timeout"> | ||||
|     ///   Time span to wait for the lock before giving up | ||||
|     /// </param> | ||||
|     /// <param name="exitContext"> | ||||
|     ///   True to exit the synchronization domain for the context before the wait (if | ||||
|     ///   in a synchronized context), and reacquire it afterward; otherwise, false. | ||||
|     /// </param> | ||||
|     /// <returns> | ||||
|     ///   True if the resource was available and is now locked, false if | ||||
|     ///   the timeout has been reached. | ||||
|     /// </returns> | ||||
| #if NO_EXITCONTEXT | ||||
|     public override bool WaitOne(TimeSpan timeout) { | ||||
| #else | ||||
|     public override bool WaitOne(TimeSpan timeout, bool exitContext) { | ||||
| #endif | ||||
|       long totalMilliseconds = (long)timeout.TotalMilliseconds; | ||||
|       if((totalMilliseconds < -1) || (totalMilliseconds > int.MaxValue)) { | ||||
|         throw new ArgumentOutOfRangeException( | ||||
|           "timeout", "Timeout must be either -1 or positive and less than 2^31" | ||||
|         ); | ||||
|       } | ||||
| 
 | ||||
| #if NO_EXITCONTEXT | ||||
|       return WaitOne((int)totalMilliseconds); | ||||
| #else | ||||
|       return WaitOne((int)totalMilliseconds, exitContext); | ||||
| #endif | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     ///   Releases a lock on the resource. Note that for a reverse counting semaphore, | ||||
|     ///   it is legal to Release() the resource before locking it. | ||||
|     /// </summary> | ||||
|     public void Release() { | ||||
| 
 | ||||
|       // Release one lock on the resource | ||||
|       Interlocked.Increment(ref this.free); | ||||
| 
 | ||||
|       // Wake up any threads waiting for the resource to become available | ||||
|       this.manualResetEvent.Set(); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     /// <summary>Creates the event used to make threads wait for the resource</summary> | ||||
|     private void createEvent() { | ||||
|       this.manualResetEvent = new ManualResetEvent(false); | ||||
|       base.SafeWaitHandle = this.manualResetEvent.SafeWaitHandle; | ||||
|     } | ||||
| 
 | ||||
|     /// <summary>Event used to make threads wait if the semaphore is full</summary> | ||||
|     private ManualResetEvent manualResetEvent; | ||||
|     /// <summary>Number of users currently accessing the resource</summary> | ||||
|     /// <remarks> | ||||
|     ///   Since this is a reverse counting semaphore, it will be negative if | ||||
|     ///   the resource is available and 0 if the semaphore is full. | ||||
|     /// </remarks> | ||||
|     private int free; | ||||
| 
 | ||||
|   } | ||||
| 
 | ||||
| } // namespace Nuclex.Support | ||||
|  | @ -332,14 +332,8 @@ namespace Nuclex.Support { | |||
|     /// <param name="builder">String builder the number will be appended to</param> | ||||
|     /// <param name="remaining">Remaining digits that will be recursively processed</param> | ||||
|     private static void recursiveAppend(StringBuilder builder, int remaining) { | ||||
| #if !(XBOX360 || WINDOWS_PHONE) | ||||
|       int digit; | ||||
|       int tenth = Math.DivRem(remaining, 10, out digit); | ||||
| #else | ||||
|       int digit = remaining % 10; | ||||
|       int tenth = remaining / 10; | ||||
| #endif | ||||
| 
 | ||||
|       if(tenth > 0) { | ||||
|         recursiveAppend(builder, tenth); | ||||
|       } | ||||
|  | @ -351,14 +345,8 @@ namespace Nuclex.Support { | |||
|     /// <param name="builder">String builder the number will be appended to</param> | ||||
|     /// <param name="remaining">Remaining digits that will be recursively processed</param> | ||||
|     private static void recursiveAppend(StringBuilder builder, long remaining) { | ||||
| #if !(XBOX360 || WINDOWS_PHONE) | ||||
|       long digit; | ||||
|       long tenth = Math.DivRem(remaining, 10, out digit); | ||||
| #else | ||||
|       long digit = remaining % 10; | ||||
|       long tenth = remaining / 10; | ||||
| #endif | ||||
| 
 | ||||
|       if(tenth > 0) { | ||||
|         recursiveAppend(builder, tenth); | ||||
|       } | ||||
|  |  | |||
|  | @ -58,65 +58,6 @@ namespace Nuclex.Support { | |||
| 
 | ||||
|     #endregion // class MemberInfoComparer | ||||
| 
 | ||||
| #if WINRT | ||||
| 
 | ||||
|     /// <summary> | ||||
|     ///   Returns all the fields of a type, including those defined in the type's base classes | ||||
|     /// </summary> | ||||
|     /// <param name="type">Type whose fields will be returned</param> | ||||
|     /// <param name="bindingFlags">Binding flags to use when querying the fields</param> | ||||
|     /// <returns>All of the type's fields, including its base types</returns> | ||||
|     public static FieldInfo[] GetFieldInfosIncludingBaseClasses(this Type type) { | ||||
|       var fieldInfoSet = new HashSet<FieldInfo>(fieldInfos, FieldInfoComparer.Default); | ||||
| 
 | ||||
|       while(type != typeof(object)) { | ||||
|         TypeInfo typeInfo = type.GetTypeInfo(); | ||||
| 
 | ||||
|         foreach(FieldInfo fieldInfo in typeInfo.DeclaredFields) { | ||||
|           fieldInfoSet.Add(fieldInfo); | ||||
|         } | ||||
| 
 | ||||
|         type = typeInfo.BaseType; | ||||
|       } | ||||
| 
 | ||||
|       FieldInfo[] fieldInfos = new FieldInfo[fieldInfoSet.Count]; | ||||
|       fieldInfoSet.CopyTo(fieldInfos, 0); | ||||
|       return fieldInfos; | ||||
|     } | ||||
| 
 | ||||
| #elif !(XBOX360 || WINDOWS_PHONE) | ||||
| 
 | ||||
|     /// <summary> | ||||
|     ///   Returns all the fields of a type, including those defined in the type's base classes | ||||
|     /// </summary> | ||||
|     /// <param name="type">Type whose fields will be returned</param> | ||||
|     /// <param name="bindingFlags">Binding flags to use when querying the fields</param> | ||||
|     /// <returns>All of the type's fields, including its base types</returns> | ||||
|     public static FieldInfo[] GetFieldInfosIncludingBaseClasses( | ||||
|       this Type type, BindingFlags bindingFlags | ||||
|     ) { | ||||
|       FieldInfo[] fieldInfos = type.GetFields(bindingFlags); | ||||
| 
 | ||||
|       // If this class doesn't have a base, don't waste any time | ||||
|       if(type.BaseType != typeof(object)) { | ||||
|         var fieldInfoSet = new HashSet<FieldInfo>(fieldInfos, FieldInfoComparer.Default); | ||||
|         while(type.BaseType != typeof(object)) { | ||||
|           type = type.BaseType; | ||||
|           fieldInfos = type.GetFields(bindingFlags); | ||||
|           for(int index = 0; index < fieldInfos.Length; ++index) { | ||||
|             fieldInfoSet.Add(fieldInfos[index]); | ||||
|           } | ||||
|         } | ||||
| 
 | ||||
|         fieldInfos = new FieldInfo[fieldInfoSet.Count]; | ||||
|         fieldInfoSet.CopyTo(fieldInfos); | ||||
|       } | ||||
| 
 | ||||
|       return fieldInfos; | ||||
|     } | ||||
| 
 | ||||
| #else // !(XBOX360 || WINDOWS_PHONE) | ||||
| 
 | ||||
|     /// <summary> | ||||
|     ///   Returns all the fields of a type, including those defined in the type's base classes | ||||
|     /// </summary> | ||||
|  | @ -164,25 +105,6 @@ namespace Nuclex.Support { | |||
|       } | ||||
|     } | ||||
| 
 | ||||
| #endif // !(XBOX360 || WINDOWS_PHONE) | ||||
| 
 | ||||
| #if WINRT | ||||
| 
 | ||||
|     /// <summary>Determines whether the given type has a default constructor</summary> | ||||
|     /// <param name="type">Type which is to be checked</param> | ||||
|     /// <returns>True if the type has a default constructor</returns> | ||||
|     public static bool HasDefaultConstructor(this Type type) { | ||||
|       foreach(ConstructorInfo constructorInfo in type.GetTypeInfo().DeclaredConstructors) { | ||||
|         if(constructorInfo.IsPublic && (constructorInfo.GetParameters().Length == 0)) { | ||||
|           return true; | ||||
|         } | ||||
|       } | ||||
| 
 | ||||
|       return false; | ||||
|     } | ||||
| 
 | ||||
| #else | ||||
| 
 | ||||
|     /// <summary>Determines whether the given type has a default constructor</summary> | ||||
|     /// <param name="type">Type which is to be checked</param> | ||||
|     /// <returns>True if the type has a default constructor</returns> | ||||
|  | @ -199,8 +121,6 @@ namespace Nuclex.Support { | |||
|       return false; | ||||
|     } | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
|     /// <summary>Determines whether the type has the specified attribute</summary> | ||||
|     /// <typeparam name="TAttribute">Attribute the type will be checked for</typeparam> | ||||
|     /// <param name="type"> | ||||
|  | @ -211,20 +131,6 @@ namespace Nuclex.Support { | |||
|       return type.HasAttribute(typeof(TAttribute)); | ||||
|     } | ||||
| 
 | ||||
| #if WINRT | ||||
| 
 | ||||
|     /// <summary>Determines whether the type has the specified attribute</summary> | ||||
|     /// <param name="type"> | ||||
|     ///   Type that will be checked for presence of the specified attribute | ||||
|     /// </param> | ||||
|     /// <param name="attributeType">Attribute the type will be checked for</typeparam> | ||||
|     /// <returns>True if the type has the specified attribute, otherwise false</returns> | ||||
|     public static bool HasAttribute(this Type type, Type attributeType) { | ||||
|       return (type.GetTypeInfo().GetCustomAttribute(attributeType) != null); | ||||
|     } | ||||
| 
 | ||||
| #else | ||||
| 
 | ||||
|     /// <summary>Determines whether the type has the specified attribute</summary> | ||||
|     /// <param name="type"> | ||||
|     ///   Type that will be checked for presence of the specified attribute | ||||
|  | @ -236,8 +142,6 @@ namespace Nuclex.Support { | |||
|       return (attributes != null) && (attributes.Length > 0); | ||||
|     } | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
|   } | ||||
| 
 | ||||
| } // namespace Nuclex.Support | ||||
|  |  | |||
|  | @ -1,106 +0,0 @@ | |||
| #region CPL License | ||||
| /* | ||||
| Nuclex Framework | ||||
| Copyright (C) 2002-2014 Nuclex Development Labs | ||||
| 
 | ||||
| This library is free software; you can redistribute it and/or | ||||
| modify it under the terms of the IBM Common Public License as | ||||
| published by the IBM Corporation; either version 1.0 of the | ||||
| License, or (at your option) any later version. | ||||
| 
 | ||||
| This library is distributed in the hope that it will be useful, | ||||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
| IBM Common Public License for more details. | ||||
| 
 | ||||
| You should have received a copy of the IBM Common Public | ||||
| License along with this library | ||||
| */ | ||||
| #endregion | ||||
| 
 | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| 
 | ||||
| namespace Nuclex.Support { | ||||
| 
 | ||||
| #if WINDOWS_PHONE | ||||
| 
 | ||||
|   /// <summary> | ||||
|   ///   Type-safe weak reference, referencing an object while still allowing | ||||
|   ///   that object to be garbage collected. | ||||
|   /// </summary> | ||||
|   public class WeakReference<ReferencedType> | ||||
|     where ReferencedType : class { | ||||
| 
 | ||||
|     /// <summary> | ||||
|     ///   Initializes a new instance of the WeakReference class, referencing | ||||
|     ///   the specified object. | ||||
|     /// </summary> | ||||
|     /// <param name="target">The object to track or null.</param> | ||||
|     public WeakReference(ReferencedType target) { | ||||
|       this.weakReference = new WeakReference(target); | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     ///   Initializes a new instance of the WeakReference class, referencing | ||||
|     ///   the specified object optionally using resurrection tracking. | ||||
|     /// </summary> | ||||
|     /// <param name="target">An object to track.</param> | ||||
|     /// <param name="trackResurrection"> | ||||
|     ///   Indicates when to stop tracking the object. If true, the object is tracked | ||||
|     ///   after finalization; if false, the object is only tracked until finalization. | ||||
|     /// </param> | ||||
|     public WeakReference(ReferencedType target, bool trackResurrection) { | ||||
|       this.weakReference = new WeakReference(target, trackResurrection); | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     ///   Implicitly converts a typed WeakReference into a non-typesafe WeakReference | ||||
|     /// </summary> | ||||
|     /// <param name="self">The types WeakReference that will be converted</param> | ||||
|     /// <returns>The non-typesafe WeakReference</returns> | ||||
|     public static implicit operator WeakReference(WeakReference<ReferencedType> self) { | ||||
|       return self.weakReference; | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     ///   Gets or sets the object (the target) referenced by the current WeakReference | ||||
|     ///   object. | ||||
|     /// </summary> | ||||
|     /// <remarks> | ||||
|     ///   Is null if the object referenced by the current System.WeakReference object | ||||
|     ///   has been garbage collected; otherwise, a reference to the object referenced | ||||
|     ///   by the current System.WeakReference object. | ||||
|     /// </remarks> | ||||
|     /// <exception cref="System.InvalidOperationException"> | ||||
|     ///   The reference to the target object is invalid. This can occur if the current | ||||
|     ///   System.WeakReference object has been finalized | ||||
|     /// </exception> | ||||
|     public ReferencedType Target { | ||||
|       get { return this.weakReference.Target as ReferencedType; } | ||||
|       set { this.weakReference.Target = value; } | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     ///   whether the object referenced by the WeakReference has been garbage collected | ||||
|     /// </summary> | ||||
|     public virtual bool IsAlive { | ||||
|       get { return this.weakReference.IsAlive; } | ||||
|     } | ||||
| 
 | ||||
|     /// <summary> | ||||
|     ///   Whether the object referenced by the WeakReference is tracked after it is finalized | ||||
|     /// </summary> | ||||
|     public virtual bool TrackResurrection { | ||||
|       get { return this.weakReference.TrackResurrection; } | ||||
|     } | ||||
| 
 | ||||
|     /// <summary>The non-typesafe WeakReference being wrapped</summary> | ||||
|     private WeakReference weakReference; | ||||
| 
 | ||||
|   } | ||||
| 
 | ||||
| #endif // WINDOWS_PHONE | ||||
| 
 | ||||
| } // namespace Nuclex.Support | ||||
| 
 | ||||
|  | @ -24,8 +24,6 @@ using System.Runtime.Serialization; | |||
| 
 | ||||
| namespace Nuclex.Support { | ||||
| 
 | ||||
| #if !WINDOWS_PHONE | ||||
| 
 | ||||
|   /// <summary> | ||||
|   ///   Type-safe weak reference, referencing an object while still allowing | ||||
|   ///   that object to be garbage collected. | ||||
|  | @ -98,6 +96,4 @@ namespace Nuclex.Support { | |||
| 
 | ||||
|   } | ||||
| 
 | ||||
| #endif // !WINDOWS_PHONE | ||||
| 
 | ||||
| } // namespace Nuclex.Support | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue