Esempio n. 1
0
        public void ConditionVariableTest2()
        {
            InitializeSRWLock(out var cond_rwlock);
            InitializeConditionVariable(out var start_condition);
            var wake_all = false;
            var cnt      = 0;

            try
            {
                var ghThreads = new SafeHTHREAD[5];
                for (int i = 0; i < ghThreads.Length; i++)
                {
                    ghThreads[i] = CreateThread(null, 0, ThreadProc, default, 0, out _);
Esempio n. 2
0
        public void Dispose()
        {
            ChatEndpoint  = null;
            RenderClient  = null;
            CaptureClient = null;
            AudioClient   = null;

            if (ChatThread is not null)
            {
                ChatThread.Dispose();
                ChatThread = default;
            }
            if (ShutdownEvent is not null)
            {
                ShutdownEvent.Dispose();
                ShutdownEvent = null;
            }
            if (AudioSamplesReadyEvent is not null)
            {
                AudioSamplesReadyEvent.Dispose();
                AudioSamplesReadyEvent = null;
            }
        }
Esempio n. 3
0
        public void ConditionVariableTest()
        {
            const int BUFFER_SIZE            = 10;
            const int PRODUCER_SLEEP_TIME_MS = 50;
            const int CONSUMER_SLEEP_TIME_MS = 200;

            var  Buffer = new int[BUFFER_SIZE];
            int  LastItemProduced = 0;
            uint QueueSize = 0, QueueStartOffset = 0, TotalItemsProduced = 0, TotalItemsConsumed = 0;
            var  StopRequested = false;
            var  rand          = new Random();

            InitializeConditionVariable(out var BufferNotEmpty);
            InitializeConditionVariable(out var BufferNotFull);
            InitializeCriticalSection(out var BufferLock);

            using (SafeHTHREAD hProducer1 = CreateThread(null, 0, ProducerThreadProc, (IntPtr)1L, 0, out _),
                   hConsumer1 = CreateThread(null, 0, ConsumerThreadProc, (IntPtr)1L, 0, out _),
                   hConsumer2 = CreateThread(null, 0, ConsumerThreadProc, (IntPtr)2L, 0, out _))
            {
                SleepEx(5000, false);

                EnterCriticalSection(ref BufferLock);
                StopRequested = true;
                LeaveCriticalSection(ref BufferLock);

                WakeAllConditionVariable(ref BufferNotFull);
                WakeAllConditionVariable(ref BufferNotEmpty);

                WaitForMultipleObjects(new[] { hProducer1, hConsumer1, hConsumer2 }, true, INFINITE);

                TestContext.WriteLine("TotalItemsProduced: {0}, TotalItemsConsumed: {1}", TotalItemsProduced, TotalItemsConsumed);
            }

            uint ProducerThreadProc(IntPtr p)
            {
                var ProducerId = p.ToInt64();

                while (true)
                {
                    // Produce a new item.
                    Sleep((uint)rand.Next(PRODUCER_SLEEP_TIME_MS));

                    var Item = InterlockedIncrement(ref LastItemProduced);

                    EnterCriticalSection(ref BufferLock);

                    while (QueueSize == BUFFER_SIZE && !StopRequested)
                    {
                        // Buffer is full - sleep so consumers can get items.
                        SleepConditionVariableCS(ref BufferNotFull, ref BufferLock, INFINITE);
                    }

                    if (StopRequested)
                    {
                        LeaveCriticalSection(ref BufferLock);
                        break;
                    }

                    // Insert the item at the end of the queue and increment size.
                    Buffer[(QueueStartOffset + QueueSize) % BUFFER_SIZE] = Item;
                    QueueSize++;
                    TotalItemsProduced++;

                    System.Diagnostics.Debug.Write($"Producer {ProducerId}: item {Item}, queue size {QueueSize}\r\n");

                    LeaveCriticalSection(ref BufferLock);

                    // If a consumer is waiting, wake it.
                    WakeConditionVariable(ref BufferNotEmpty);
                }

                System.Diagnostics.Debug.Write($"Producer {ProducerId} exiting\r\n");
                return(0);
            }

            uint ConsumerThreadProc(IntPtr p)
            {
                var ConsumerId = p.ToInt64();

                while (true)
                {
                    EnterCriticalSection(ref BufferLock);

                    while (QueueSize == 0 && !StopRequested)
                    {
                        // Buffer is empty - sleep so producers can create items.
                        SleepConditionVariableCS(ref BufferNotEmpty, ref BufferLock, INFINITE);
                    }

                    if (StopRequested && QueueSize == 0)
                    {
                        LeaveCriticalSection(ref BufferLock);
                        break;
                    }

                    // Consume the first available item.
                    var Item = Buffer[QueueStartOffset];

                    QueueSize--;
                    QueueStartOffset++;
                    TotalItemsConsumed++;

                    if (QueueStartOffset == BUFFER_SIZE)
                    {
                        QueueStartOffset = 0;
                    }

                    System.Diagnostics.Debug.Write($"Consumer {ConsumerId}: item {Item}, queue size {QueueSize}\r\n");

                    LeaveCriticalSection(ref BufferLock);

                    // If a producer is waiting, wake it.

                    WakeConditionVariable(ref BufferNotFull);

                    // Simulate processing of the item.

                    Sleep((uint)rand.Next(CONSUMER_SLEEP_TIME_MS));
                }

                System.Diagnostics.Debug.Write($"Consumer {ConsumerId} exiting\r\n");
                return(0);
            }
        }