Vanara/UnitTests/PInvoke/Kernel32/InterlockedApiTests.cs

85 lines
2.6 KiB
C#

using NUnit.Framework;
using System;
using System.Runtime.InteropServices;
using System.Text;
using Vanara.Extensions;
using Vanara.InteropServices;
using static Vanara.PInvoke.AdvApi32;
using static Vanara.PInvoke.Kernel32;
namespace Vanara.PInvoke.Tests
{
[TestFixture]
public class InterlockedApiTests
{
[StructLayout(LayoutKind.Sequential, Size = 32)]
private struct PROGRAM_ITEM
{
public SLIST_ENTRY ItemEntry;
public uint Signature;
}
[Test]
public unsafe void InterlockedTest()
{
const uint max = 10;
// Initialize the list header to a MEMORY_ALLOCATION_ALIGNMENT boundary.
InitializeSListHead(out var listHead);
// Insert 10 items into the list.
for (var Count = 1U; Count <= max; Count += 1)
{
var pProgramItem = new PROGRAM_ITEM { Signature = Count }.MarshalToPtr(Marshal.AllocHGlobal, out _);
InterlockedPushEntrySList(listHead, pProgramItem);
}
Assert.That(QueryDepthSList(listHead), Is.EqualTo(max));
// Remove 10 items from the list and display the signature.
for (var Count = max; Count >= 1; Count -= 1)
{
var pListEntry = InterlockedPopEntrySList(listHead);
var programItem = pListEntry.ToNullableStructure<PROGRAM_ITEM>();
if (!programItem.HasValue)
Assert.Fail("NULL from InterlockedPopEntrySList");
Assert.That(Count, Is.EqualTo(programItem.Value.Signature));
Marshal.FreeHGlobal(pListEntry);
}
// Flush the list and verify that the items are gone.
Assert.That(InterlockedFlushSList(listHead), Is.EqualTo(IntPtr.Zero));
Assert.That(InterlockedPopEntrySList(listHead), Is.EqualTo(IntPtr.Zero));
}
[Test]
public unsafe void InterlockedTest2()
{
const uint max = 10;
// Initialize the list header to a MEMORY_ALLOCATION_ALIGNMENT boundary.
InitializeSListHead(out var listHead);
// Create 10 item list in memory.
var items = new IntPtr[max];
for (var Count = 0U; Count < max; Count += 1)
{
items[Count] = new PROGRAM_ITEM { ItemEntry = new SLIST_ENTRY { Next = Count == 0 ? IntPtr.Zero : items[Count - 1] }, Signature = Count + 1 }.MarshalToPtr(Marshal.AllocHGlobal, out _);
}
// Add list and check
Assert.That(InterlockedPushListSListEx(listHead, items[0], items[max - 1], max), Is.EqualTo(IntPtr.Zero));
Assert.That(QueryDepthSList(listHead), Is.EqualTo(max));
// Flush the list and verify that the items are gone.
Assert.That(InterlockedFlushSList(listHead), Is.EqualTo(items[0]));
Assert.That(InterlockedPopEntrySList(listHead), Is.EqualTo(IntPtr.Zero));
// Free items
for (var Count = 0U; Count < max; Count += 1)
Marshal.FreeHGlobal(items[Count]);
}
}
}