in ClrMemDiag/Desktop/threadpool.cs [83:182]
private IEnumerable<ulong> EnumerateManagedThreadpoolObjects()
{
_heap = _runtime.GetHeap();
ClrModule mscorlib = GetMscorlib();
if (mscorlib != null)
{
ClrType queueType = mscorlib.GetTypeByName("System.Threading.ThreadPoolGlobals");
if (queueType != null)
{
ClrStaticField workQueueField = queueType.GetStaticFieldByName("workQueue");
if (workQueueField != null)
{
foreach (var appDomain in _runtime.AppDomains)
{
object workQueueValue = workQueueField.GetValue(appDomain);
ulong workQueue = workQueueValue == null ? 0L : (ulong)workQueueValue;
ClrType workQueueType = _heap.GetObjectType(workQueue);
if (workQueue == 0 || workQueueType == null)
continue;
ulong queueHead;
ClrType queueHeadType;
do
{
if (!GetFieldObject(workQueueType, workQueue, "queueHead", out queueHeadType, out queueHead))
break;
ulong nodes;
ClrType nodesType;
if (GetFieldObject(queueHeadType, queueHead, "nodes", out nodesType, out nodes) && nodesType.IsArray)
{
int len = nodesType.GetArrayLength(nodes);
for (int i = 0; i < len; ++i)
{
ulong addr = (ulong)nodesType.GetArrayElementValue(nodes, i);
if (addr != 0)
yield return addr;
}
}
if (!GetFieldObject(queueHeadType, queueHead, "Next", out queueHeadType, out queueHead))
break;
} while (queueHead != 0);
}
}
}
queueType = mscorlib.GetTypeByName("System.Threading.ThreadPoolWorkQueue");
if (queueType != null)
{
ClrStaticField threadQueuesField = queueType.GetStaticFieldByName("allThreadQueues");
if (threadQueuesField != null)
{
foreach (ClrAppDomain domain in _runtime.AppDomains)
{
ulong? threadQueue = (ulong?)threadQueuesField.GetValue(domain);
if (!threadQueue.HasValue || threadQueue.Value == 0)
continue;
ClrType threadQueueType = _heap.GetObjectType(threadQueue.Value);
if (threadQueueType == null)
continue;
ulong outerArray = 0;
ClrType outerArrayType = null;
if (!GetFieldObject(threadQueueType, threadQueue.Value, "m_array", out outerArrayType, out outerArray) || !outerArrayType.IsArray)
continue;
int outerLen = outerArrayType.GetArrayLength(outerArray);
for (int i = 0; i < outerLen; ++i)
{
ulong entry = (ulong)outerArrayType.GetArrayElementValue(outerArray, i);
if (entry == 0)
continue;
ClrType entryType = _heap.GetObjectType(entry);
if (entryType == null)
continue;
ulong array;
ClrType arrayType;
if (!GetFieldObject(entryType, entry, "m_array", out arrayType, out array) || !arrayType.IsArray)
continue;
int len = arrayType.GetArrayLength(array);
for (int j = 0; j < len; ++j)
{
ulong addr = (ulong)arrayType.GetArrayElementValue(array, i);
if (addr != 0)
yield return addr;
}
}
}
}
}
}
}