-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #266 from microsoft/pete-dev
Multithreading test and documentation update
- Loading branch information
Showing
11 changed files
with
213 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
<Include> | ||
<?define SetupVersionName="Developer Preview 5" ?> | ||
<?define SetupVersionNumber="1.0.24039.2143" ?> | ||
<?define SetupVersionNumber="1.0.24039.2325" ?> | ||
</Include> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
139 changes: 139 additions & 0 deletions
139
src/api/Test/Midi2.Client.unittests/MidiEndpointCreationThreadTests.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
|
||
#include "stdafx.h" | ||
|
||
#include "MidiEndpointCreationThreadTests.h" | ||
|
||
|
||
#include <wil\resource.h> | ||
|
||
|
||
#define NUM_MESSAGES_TO_TRANSMIT 10 | ||
|
||
_Use_decl_annotations_ | ||
void MidiEndpointCreationThreadTests::ReceiveThreadWorker(MidiSession session, winrt::hstring endpointId) | ||
{ | ||
wil::unique_event_nothrow allMessagesReceived; | ||
allMessagesReceived.create(); | ||
|
||
uint32_t countMessagesReceived = 0; | ||
|
||
auto connectionThreadId = GetCurrentThreadId(); | ||
std::cout << "Receiver: connection thread: " << connectionThreadId << std::endl; | ||
|
||
// create the connection | ||
auto connection = session.CreateEndpointConnection(endpointId); | ||
|
||
auto MessageReceivedHandler = [&](IMidiMessageReceivedEventSource const& sender, MidiMessageReceivedEventArgs const& args) | ||
{ | ||
UNREFERENCED_PARAMETER(sender); | ||
UNREFERENCED_PARAMETER(args); | ||
|
||
auto callbackThreadId = GetCurrentThreadId(); | ||
std::cout << "Message received on callback thread: " << callbackThreadId << std::endl; | ||
|
||
countMessagesReceived++; | ||
|
||
// this will not be true. The thread receiving messages is a high-priority thread the application does not control. | ||
//VERIFY_ARE_EQUAL(connectionThreadId, callbackThreadId); | ||
|
||
if (countMessagesReceived >= NUM_MESSAGES_TO_TRANSMIT) | ||
{ | ||
allMessagesReceived.SetEvent(); | ||
} | ||
|
||
}; | ||
|
||
auto revoke = connection.MessageReceived(MessageReceivedHandler); | ||
std::cout << "Receiver: Event handler created." << std::endl; | ||
|
||
connection.Open(); | ||
std::cout << "Receiver: Connection opened." << std::endl; | ||
|
||
m_receiverReady.SetEvent(); | ||
|
||
std::cout << "Receiver: Waiting for messages." << std::endl; | ||
|
||
if (!allMessagesReceived.wait(10000)) | ||
{ | ||
std::cout << "Receiver: Failure waiting for receiver to connect." << std::endl; | ||
|
||
VERIFY_FAIL(); | ||
} | ||
|
||
std::cout << "Receiver: " << countMessagesReceived << " messages received." << std::endl; | ||
|
||
m_receiveComplete.SetEvent(); | ||
} | ||
|
||
|
||
_Use_decl_annotations_ | ||
void MidiEndpointCreationThreadTests::SendThreadWorker(MidiSession session, winrt::hstring endpointId) | ||
{ | ||
auto threadId = GetCurrentThreadId(); | ||
|
||
std::cout << "Sender thread: " << threadId << std::endl; | ||
|
||
// create the connection | ||
auto connection = session.CreateEndpointConnection(endpointId); | ||
connection.Open(); | ||
|
||
for (uint32_t i = 0; i < NUM_MESSAGES_TO_TRANSMIT; i++) | ||
{ | ||
connection.SendMessageWords(MidiClock::TimestampConstantSendImmediately(), 0x21234567); | ||
|
||
} | ||
|
||
std::cout << "Sender: " << NUM_MESSAGES_TO_TRANSMIT << " messages sent" << std::endl; | ||
|
||
} | ||
|
||
|
||
|
||
void MidiEndpointCreationThreadTests::TestCreateNewSessionMultithreaded() | ||
{ | ||
m_receiveComplete.create(); | ||
m_receiverReady.create(); | ||
|
||
auto sessionThreadId = GetCurrentThreadId(); | ||
|
||
std::cout << "Session thread: " << sessionThreadId << std::endl; | ||
|
||
// create session on this thread | ||
|
||
auto session = MidiSession::CreateSession(L"Multi-threaded Test"); | ||
|
||
// create loopback A on thread A | ||
std::thread workerThreadA(&MidiEndpointCreationThreadTests::ReceiveThreadWorker, this, session, MidiEndpointDeviceInformation::DiagnosticsLoopbackAEndpointId()); | ||
workerThreadA.detach(); | ||
|
||
if (!m_receiverReady.wait(10000)) | ||
{ | ||
std::cout << "Session: Failure waiting for receiver to connect." << std::endl; | ||
|
||
VERIFY_FAIL(); | ||
} | ||
else | ||
{ | ||
std::cout << "Session: Receiver ready notification received." << std::endl; | ||
} | ||
|
||
// create loopback B on thread B | ||
std::thread workerThreadB(&MidiEndpointCreationThreadTests::SendThreadWorker, this, session, MidiEndpointDeviceInformation::DiagnosticsLoopbackBEndpointId()); | ||
workerThreadB.detach(); | ||
|
||
if (!m_receiveComplete.wait(20000)) | ||
{ | ||
std::cout << "Session: Failure waiting for all messages to be received." << std::endl; | ||
|
||
VERIFY_FAIL(); | ||
} | ||
else | ||
{ | ||
std::cout << "Session: Message receive complete notification received." << std::endl; | ||
} | ||
|
||
|
||
} | ||
|
||
|
||
|
57 changes: 57 additions & 0 deletions
57
src/api/Test/Midi2.Client.unittests/MidiEndpointCreationThreadTests.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License | ||
// ============================================================================ | ||
// This is part of the Windows MIDI Services App API and should be used | ||
// in your Windows application via an official binary distribution. | ||
// Further information: https://github.com/microsoft/MIDI/ | ||
// ============================================================================ | ||
|
||
|
||
#pragma once | ||
|
||
using namespace winrt::Windows::Devices::Midi2; | ||
|
||
|
||
class MidiEndpointCreationThreadTests | ||
: public WEX::TestClass<MidiEndpointCreationThreadTests> | ||
{ | ||
public: | ||
|
||
BEGIN_TEST_CLASS(MidiEndpointCreationThreadTests) | ||
TEST_CLASS_PROPERTY(L"TestClassification", L"Unit") | ||
TEST_CLASS_PROPERTY(L"BinaryUnderTest", L"Windows.Devices.Midi2.dll") | ||
TEST_CLASS_PROPERTY(L"BinaryUnderTest", L"Midi2.BluetoothMidiAbstraction.dll") | ||
TEST_CLASS_PROPERTY(L"BinaryUnderTest", L"Midi2.DiagnosticsAbstraction.dll") | ||
TEST_CLASS_PROPERTY(L"BinaryUnderTest", L"Midi2.KSAbstraction.dll") | ||
TEST_CLASS_PROPERTY(L"BinaryUnderTest", L"Midi2.MidiSrvAbstraction.dll") | ||
TEST_CLASS_PROPERTY(L"BinaryUnderTest", L"Midi2.NetworkMidiAbstraction.dll") | ||
TEST_CLASS_PROPERTY(L"BinaryUnderTest", L"Midi2.VirtualMidiAbstraction.dll") | ||
TEST_CLASS_PROPERTY(L"BinaryUnderTest", L"Midi2.VirtualPatchBayAbstraction.dll") | ||
TEST_CLASS_PROPERTY(L"BinaryUnderTest", L"Minmidi.sys") | ||
TEST_CLASS_PROPERTY(L"BinaryUnderTest", L"usbmidi2.sys") | ||
TEST_CLASS_PROPERTY(L"BinaryUnderTest", L"MidiSrv.exe") | ||
END_TEST_CLASS() | ||
|
||
//TEST_CLASS_SETUP(ClassSetup); | ||
//TEST_CLASS_CLEANUP(ClassCleanup); | ||
|
||
//TEST_METHOD_SETUP(TestSetup); | ||
//TEST_METHOD_CLEANUP(TestCleanup); | ||
|
||
//Generic Tests | ||
TEST_METHOD(TestCreateNewSessionMultithreaded); | ||
|
||
|
||
private: | ||
|
||
void ReceiveThreadWorker(_In_ MidiSession session, _In_ winrt::hstring endpointId); | ||
void SendThreadWorker(_In_ MidiSession session, _In_ winrt::hstring endpointId); | ||
|
||
|
||
wil::unique_event_nothrow m_receiverReady; | ||
|
||
wil::unique_event_nothrow m_receiveComplete; | ||
|
||
|
||
}; | ||
|