blob: e39999e6dc5dc21bae0276dc99ef1b9d3f43ad80 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
namespace Lucene.Net.Randomized
{
public static class ThreadGroupExtensions
{
private static readonly object globalLock = new object();
public static ThreadGroup GetThreadGroup(this Thread thread)
{
if (thread.IsAlive)
{
lock (ThreadGroup.GroupLock)
{
foreach (var group in ThreadGroup.Groups)
{
group.Prune();
foreach (var weak in group)
{
if (thread == (Thread)weak.Target)
return group;
}
}
ThreadGroup.Root.Add(thread);
return ThreadGroup.Root;
}
}
return null;
}
}
public class ThreadGroup : IEnumerable<WeakReference>, IDisposable
{
private List<WeakReference> threads;
private static object s_groupLock = new Object();
internal static object GroupLock
{
get
{
if (s_groupLock == null)
s_groupLock = new Object();
return s_groupLock;
}
}
internal static List<ThreadGroup> Groups { get; set; }
static ThreadGroup()
{
Groups = new List<ThreadGroup>();
Root = new ThreadGroup("Root");
}
public static ThreadGroup Root { get; set; }
public string Name { get; protected set; }
public ThreadGroup Parent { get; protected set; }
public ThreadGroup(string name)
: this(name, null)
{
}
public ThreadGroup(string name, ThreadGroup parent)
{
this.Parent = parent;
this.Name = name;
this.threads = new List<WeakReference>();
lock (GroupLock)
{
Groups.Add(this);
}
}
internal void Add(Thread instance)
{
var threadRef = new WeakReference(instance);
this.threads.Add(threadRef);
}
internal void Prune()
{
var copy = this.threads.ToList();
foreach (var item in copy)
{
if (!item.IsAlive)
this.threads.Remove(item);
}
}
public IEnumerator<WeakReference> GetEnumerator()
{
return this.threads.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.threads.GetEnumerator();
}
public void Dispose()
{
lock (GroupLock)
{
Groups.Remove(this);
}
}
}
}