Skip to content

Instantly share code, notes, and snippets.

@dmitryvk
Created December 28, 2018 11:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dmitryvk/30d4a3ce117104adafc5138efaceef3c to your computer and use it in GitHub Desktop.
Save dmitryvk/30d4a3ce117104adafc5138efaceef3c to your computer and use it in GitHub Desktop.
Reduced reproduction of data race inside Mono's System.Web.Caching.Cache
namespace ConsoleApplication10
{
using System;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Web.Caching;
internal class Program
{
public static void Main()
{
var cache = new Cache();
var threads = new Action<Cache>[] { Adder, CheckGetKeyLastChange, CheckGetKeyLastChange, CheckGetKeyLastChange }
.Select(x => new Thread(() => x(cache)) {IsBackground = true})
.ToList();
foreach (var t in threads)
{
t.Start();
}
foreach (var t in threads)
{
t.Join();
}
}
private const int KeysCount = 30000; // 2x of HIGH_WATERMARK
static void Adder(Cache cache)
{
try
{
while (true)
{
for (var i = 0; i < KeysCount; ++i)
{
cache.Add(i.ToString(), i, null, DateTime.MaxValue, TimeSpan.Zero, CacheItemPriority.Default, null);
}
Console.Write("+");
}
}
catch (Exception exception)
{
Console.WriteLine(exception);
Environment.Exit(123);
}
}
// Note: Cache.GetKeyLastChange is internal method; but it is called from several places and is a part of "public internal" cache API
private static MethodInfo GetKeyLastChangeMethod = typeof(Cache).GetMethod("GetKeyLastChange", BindingFlags.Instance | BindingFlags.NonPublic);
static void CheckGetKeyLastChange(Cache cache)
{
try
{
while (true)
{
for (var i = 0; i < KeysCount; ++i)
{
GetKeyLastChangeMethod.Invoke(cache, new object[] {i.ToString()});
}
Console.Write("*");
}
}
catch (Exception exception)
{
Console.WriteLine(exception);
Environment.Exit(123);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment