diff options
author | Jiyoung Yun <jy910.yun@samsung.com> | 2016-11-23 19:09:09 +0900 |
---|---|---|
committer | Jiyoung Yun <jy910.yun@samsung.com> | 2016-11-23 19:09:09 +0900 |
commit | 4b4aad7217d3292650e77eec2cf4c198ea9c3b4b (patch) | |
tree | 98110734c91668dfdbb126fcc0e15ddbd93738ca /tests/src/GC/Scenarios/FinalizeTimeout/FinalizeTimeout.cs | |
parent | fa45f57ed55137c75ac870356a1b8f76c84b229c (diff) | |
download | coreclr-4b4aad7217d3292650e77eec2cf4c198ea9c3b4b.tar.gz coreclr-4b4aad7217d3292650e77eec2cf4c198ea9c3b4b.tar.bz2 coreclr-4b4aad7217d3292650e77eec2cf4c198ea9c3b4b.zip |
Imported Upstream version 1.1.0upstream/1.1.0
Diffstat (limited to 'tests/src/GC/Scenarios/FinalizeTimeout/FinalizeTimeout.cs')
-rw-r--r-- | tests/src/GC/Scenarios/FinalizeTimeout/FinalizeTimeout.cs | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/tests/src/GC/Scenarios/FinalizeTimeout/FinalizeTimeout.cs b/tests/src/GC/Scenarios/FinalizeTimeout/FinalizeTimeout.cs new file mode 100644 index 0000000000..0fda8172e4 --- /dev/null +++ b/tests/src/GC/Scenarios/FinalizeTimeout/FinalizeTimeout.cs @@ -0,0 +1,77 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +using System; +using System.Threading; + +public class FinalizeTimeout +{ + public static int Main(string[] args) + { + Console.WriteLine("Main start"); + + // Run the finalizer at least once to have its code be jitted + BlockingFinalizerOnShutdown finalizableObject; + do + { + finalizableObject = new BlockingFinalizerOnShutdown(); + } while (!BlockingFinalizerOnShutdown.finalizerCompletedOnce); + + // Start a bunch of threads that allocate continuously, to increase the chance that when Main returns, one of the + // threads will be blocked for shutdown while holding one of the GC locks + for (int i = 0; i < Environment.ProcessorCount; ++i) + { + var t = new Thread(ThreadMain); + t.IsBackground = true; + t.Start(); + } + + // Wait a second to give the threads a chance to actually start running + Thread.Sleep(1000); + + Console.WriteLine("Main end"); + + // Create another finalizable object, and immediately return from Main to have finalization occur during shutdown + finalizableObject = new BlockingFinalizerOnShutdown() { isLastObject = true }; + return 100; + } + + private static void ThreadMain() + { + byte[] b; + while (true) + b = new byte[1024]; + } + + private class BlockingFinalizerOnShutdown + { + public static bool finalizerCompletedOnce = false; + public bool isLastObject = false; + + ~BlockingFinalizerOnShutdown() + { + if (finalizerCompletedOnce && !isLastObject) + return; + + Console.WriteLine("Finalizer start"); + + // Allocate in the finalizer for long enough to try allocation after one of the background threads blocks for + // shutdown while holding one of the GC locks, to deadlock the finalizer. The main thread should eventually time + // out waiting for the finalizer thread to complete, and the process should exit cleanly. + TimeSpan timeout = isLastObject ? TimeSpan.FromMilliseconds(500) : TimeSpan.Zero; + TimeSpan elapsed = TimeSpan.Zero; + var start = DateTime.Now; + int i = -1; + object o; + do + { + o = new object(); + } while ((++i & 0xff) != 0 || (elapsed = DateTime.Now - start) < timeout); + + Console.WriteLine("Finalizer end"); + finalizerCompletedOnce = true; + } + } +} |