Generic device guard; use Corsair implementation for all Corsair HID cooling-capable controllers

This commit is contained in:
Evan Mulawski 2023-11-10 15:12:26 +00:00 committed by Adam Honse
parent c5c5bf519b
commit f672397563
15 changed files with 387 additions and 109 deletions

View file

@ -7,6 +7,7 @@
\*---------------------------------------------------------*/
#include "CorsairCommanderCoreController.h"
#include "CorsairDeviceGuard.h"
#include <cstring>
#include <iomanip>
@ -23,9 +24,7 @@ CorsairCommanderCoreController::CorsairCommanderCoreController(hid_device* dev_h
packet_size = CORSAIR_COMMANDER_CORE_PACKET_SIZE_V2;
command_res_size = packet_size - 4;
this->pid = pid;
#ifdef _WIN32
global_corsair_access_handle = CreateMutexA(NULL, FALSE, GLOBAL_CORSAIR_MUTEX_NAME);
#endif
guard_manager_ptr = new DeviceGuardManager(new CorsairDeviceGuard());
/*-----------------------------------------------------*\
| Initialize controller |
@ -43,12 +42,6 @@ CorsairCommanderCoreController::~CorsairCommanderCoreController()
/*-----------------------------------------------------*\
| Close keepalive thread |
\*-----------------------------------------------------*/
#ifdef _WIN32
if(global_corsair_access_handle != NULL)
{
CloseHandle(global_corsair_access_handle);
}
#endif
keepalive_thread_run = 0;
keepalive_thread->join();
delete keepalive_thread;
@ -57,6 +50,7 @@ CorsairCommanderCoreController::~CorsairCommanderCoreController()
| Close HID device |
\*-----------------------------------------------------*/
hid_close(dev);
delete guard_manager_ptr;
}
void CorsairCommanderCoreController::InitController()
@ -153,13 +147,6 @@ void CorsairCommanderCoreController::SendCommand(unsigned char command[2], unsig
\*---------------------------------------------------------*/
unsigned char* buf = new unsigned char[packet_size];
#ifdef _WIN32
if(global_corsair_access_handle != NULL)
{
WaitForSingleObject(global_corsair_access_handle, INFINITE);
}
#endif
memset(buf, 0, packet_size);
buf[0] = 0x00;
buf[1] = 0x08;
@ -170,25 +157,28 @@ void CorsairCommanderCoreController::SendCommand(unsigned char command[2], unsig
memcpy(&buf[4], data, data_len);
}
hid_write(dev, buf, packet_size);
do
/*---------------------------------------------------------*\
| HID I/O start |
\*---------------------------------------------------------*/
{
hid_read(dev, buf, packet_size);
DeviceGuardLock _ = guard_manager_ptr->AwaitExclusiveAccess();
hid_write(dev, buf, packet_size);
do
{
hid_read(dev, buf, packet_size);
}
while (buf[0] != 0x00);
}
while (buf[0] != 0x00);
/*---------------------------------------------------------*\
| HID I/O end (lock released) |
\*---------------------------------------------------------*/
if(res != NULL)
{
memcpy(res, &buf[3], command_res_size);
}
#ifdef _WIN32
if(global_corsair_access_handle != NULL)
{
ReleaseMutex(global_corsair_access_handle);
}
#endif
delete[] buf;
}
@ -201,17 +191,9 @@ void CorsairCommanderCoreController::WriteData(unsigned char endpoint[2], unsign
/*---------------------------------------------------------*\
| Open endpoint |
\*---------------------------------------------------------*/
#ifdef _WIN32
if(global_corsair_access_handle != NULL)
{
WaitForSingleObject(global_corsair_access_handle, INFINITE);
}
#endif
unsigned char command[2] = {0x0d, 0x00};
SendCommand(command, endpoint, 2, NULL);
/*---------------------------------------------------------*\
| Write data |
\*---------------------------------------------------------*/
@ -271,13 +253,6 @@ void CorsairCommanderCoreController::WriteData(unsigned char endpoint[2], unsign
command[0] = 0x05;
command[1] = 0x01;
SendCommand(command, NULL, 0, NULL);
#ifdef _WIN32
if(global_corsair_access_handle != NULL)
{
ReleaseMutex(global_corsair_access_handle);
}
#endif
}
void CorsairCommanderCoreController::SetDirectColor
@ -371,6 +346,6 @@ void CorsairCommanderCoreController::SetFanMode()
}
WriteData(endpoint, data_type, buf, 15);
controller_ready = 1;
}

View file

@ -9,15 +9,12 @@
\*---------------------------------------------------------*/
#include "RGBController.h"
#include "DeviceGuardManager.h"
#include <vector>
#include <chrono>
#include <hidapi/hidapi.h>
#ifdef _WIN32
#include <Windows.h>
#endif
#pragma once
#define CORSAIR_COMMANDER_CORE_PACKET_SIZE_V1 1025 // First bit is the report bit
@ -28,10 +25,6 @@
#define CORSAIR_QL_FAN_ZONE_OFFSET 102
#define CORSAIR_COMMANDER_CORE_NUM_CHANNELS 6
#ifdef _WIN32
#define GLOBAL_CORSAIR_MUTEX_NAME "Global\\CorsairLinkReadWriteGuardMutex"
#endif
enum
{
CORSAIR_COMMANDER_CORE_MODE_DIRECT = 0x00,
@ -56,23 +49,20 @@ public:
void SetFanMode();
private:
hid_device* dev;
std::thread* keepalive_thread;
std::atomic<bool> keepalive_thread_run;
std::atomic<bool> controller_ready;
std::string location;
std::vector<RGBColor> lastcolors;
std::vector<zone> lastzones;
unsigned short int version[3] = {0, 0, 0};
int packet_size;
int command_res_size;
int pid;
std::chrono::time_point<std::chrono::steady_clock> last_commit_time;
hid_device* dev;
std::thread* keepalive_thread;
std::atomic<bool> keepalive_thread_run;
std::atomic<bool> controller_ready;
std::string location;
std::vector<RGBColor> lastcolors;
std::vector<zone> lastzones;
unsigned short int version[3] = {0, 0, 0};
int packet_size;
int command_res_size;
int pid;
std::chrono::time_point<std::chrono::steady_clock> last_commit_time;
DeviceGuardManager* guard_manager_ptr;
#ifdef _WIN32
HANDLE global_corsair_access_handle = NULL;
#endif
void SendCommand(unsigned char command[2], unsigned char data[], unsigned short int data_len, unsigned char res[]);
void WriteData(unsigned char endpoint[2], unsigned char data_type[2], unsigned char data[], unsigned short int data_len);

View file

@ -0,0 +1,64 @@
/*---------------------------------------------------------*\
| CorsairDeviceGuard.h |
| |
| A DeviceGuard implementation for Corsair devices. |
| |
| On Windows platforms, a global mutex is used. |
| |
| Evan Mulawski, 2023-09-04 |
| |
\*---------------------------------------------------------*/
#include "CorsairDeviceGuard.h"
CorsairDeviceGuard::CorsairDeviceGuard() : DeviceGuard()
{
#ifdef _WIN32
mutex_handle = CreateWindowsMutex();
#endif
}
void CorsairDeviceGuard::Acquire()
{
#ifdef _WIN32
while(true)
{
DWORD result = WaitForSingleObject(mutex_handle, INFINITE);
if(result == WAIT_OBJECT_0)
{
break;
}
if(result == WAIT_ABANDONED)
{
ReleaseMutex(mutex_handle);
}
}
#endif
}
void CorsairDeviceGuard::Release()
{
#ifdef _WIN32
ReleaseMutex(mutex_handle);
#endif
}
#ifdef _WIN32
HANDLE CorsairDeviceGuard::CreateWindowsMutex()
{
SECURITY_DESCRIPTOR sd;
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = &sd;
sa.bInheritHandle = FALSE;
return CreateMutex(&sa, FALSE, "Global\\CorsairLinkReadWriteGuardMutex");
}
#endif

View file

@ -0,0 +1,34 @@
/*---------------------------------------------------------*\
| CorsairDeviceGuard.h |
| |
| A DeviceGuard implementation for Corsair devices. |
| |
| On Windows platforms, a global mutex is used. |
| |
| Evan Mulawski, 2023-09-04 |
| |
\*---------------------------------------------------------*/
#pragma once
#include "DeviceGuard.h"
#ifdef _WIN32
#include <Windows.h>
#endif
class CorsairDeviceGuard : public DeviceGuard
{
public:
CorsairDeviceGuard();
void Acquire() override;
void Release() override;
private:
#ifdef _WIN32
HANDLE mutex_handle;
HANDLE CreateWindowsMutex();
#endif
};

View file

@ -8,6 +8,7 @@
\*-------------------------------------------------------------------*/
#include "CorsairHydroPlatinumController.h"
#include "CorsairDeviceGuard.h"
#include <cstring>
static const uint8_t CRC_TABLE[256] =
@ -86,6 +87,7 @@ CorsairHydroPlatinumController::CorsairHydroPlatinumController(hid_device* dev_h
{
dev = dev_handle;
location = path;
guard_manager_ptr = new DeviceGuardManager(new CorsairDeviceGuard());
SendMagic(MAGIC_1, CORSAIR_HYDRO_PLATINUM_MAGIC_1);
SendMagic(MAGIC_2, CORSAIR_HYDRO_PLATINUM_MAGIC_2);
@ -95,6 +97,7 @@ CorsairHydroPlatinumController::CorsairHydroPlatinumController(hid_device* dev_h
CorsairHydroPlatinumController::~CorsairHydroPlatinumController()
{
hid_close(dev);
delete guard_manager_ptr;
}
std::string CorsairHydroPlatinumController::GetLocation()
@ -152,8 +155,18 @@ void CorsairHydroPlatinumController::SendMagic(const uint8_t* magic, unsigned in
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, CORSAIR_HYDRO_PLATINUM_PACKET_SIZE);
hid_read(dev, usb_buf, CORSAIR_HYDRO_PLATINUM_PACKET_SIZE);
/*---------------------------------------------------------*\
| HID I/O start |
\*---------------------------------------------------------*/
{
DeviceGuardLock _ = guard_manager_ptr->AwaitExclusiveAccess();
hid_write(dev, usb_buf, CORSAIR_HYDRO_PLATINUM_PACKET_SIZE);
hid_read(dev, usb_buf, CORSAIR_HYDRO_PLATINUM_PACKET_SIZE);
}
/*---------------------------------------------------------*\
| HID I/O end (lock released) |
\*---------------------------------------------------------*/
if(firmware_version.empty())
{
@ -204,8 +217,17 @@ void CorsairHydroPlatinumController::SendColors(std::vector<RGBColor> colors, un
checksum_array.insert(checksum_array.begin(), std::begin(usb_buf) + 2, std::end(usb_buf) - 1);
usb_buf[64] = ComputePEC(static_cast<void*>(checksum_array.data()), 62);
hid_write(dev, usb_buf, CORSAIR_HYDRO_PLATINUM_PACKET_SIZE);
hid_read(dev, usb_buf, CORSAIR_HYDRO_PLATINUM_PACKET_SIZE);
/*---------------------------------------------------------*\
| HID I/O start |
\*---------------------------------------------------------*/
{
DeviceGuardLock _ = guard_manager_ptr->AwaitExclusiveAccess();
hid_write(dev, usb_buf, CORSAIR_HYDRO_PLATINUM_PACKET_SIZE);
}
/*---------------------------------------------------------*\
| HID I/O end (lock released) |
\*---------------------------------------------------------*/
/*-----------------------------------------------------*\
| This delay prevents the AIO from soft-locking when |
@ -242,4 +264,4 @@ uint8_t CorsairHydroPlatinumController::ComputePEC(const void * data, size_t siz
}
return val;
}
}

View file

@ -10,6 +10,8 @@
#pragma once
#include "RGBController.h"
#include "DeviceGuardManager.h"
#include <vector>
#include <string>
#include <hidapi/hidapi.h>
@ -39,11 +41,11 @@ public:
void SetupColors(std::vector<RGBColor> colors);
private:
hid_device* dev;
std::string location;
std::string firmware_version;
std::atomic<unsigned int> sequence_number;
hid_device* dev;
std::string location;
std::string firmware_version;
std::atomic<unsigned int> sequence_number;
DeviceGuardManager* guard_manager_ptr;
void SendMagic(const uint8_t* magic, unsigned int command);
void SendColors(std::vector<RGBColor> colors, unsigned int start, unsigned int end, unsigned int command);

View file

@ -5,6 +5,7 @@
\*---------------------------------------------------------*/
#include "CorsairLightingNodeController.h"
#include "CorsairDeviceGuard.h"
#include <fstream>
#include <iostream>
@ -17,6 +18,7 @@ CorsairLightingNodeController::CorsairLightingNodeController(hid_device* dev_han
{
dev = dev_handle;
location = path;
guard_manager_ptr = new DeviceGuardManager(new CorsairDeviceGuard());
SendFirmwareRequest();
@ -37,6 +39,7 @@ CorsairLightingNodeController::~CorsairLightingNodeController()
delete keepalive_thread;
hid_close(dev);
delete guard_manager_ptr;
}
void CorsairLightingNodeController::KeepaliveThread()
@ -176,7 +179,7 @@ void CorsairLightingNodeController::SetChannelLEDs(unsigned char channel, RGBCol
{
pkt_size = 50;
}
for(int color_idx = 0; color_idx < pkt_size; color_idx++)
{
red_color_data[color_idx] = RGBGetRValue(colors[pkt_offset + color_idx]);
@ -205,7 +208,7 @@ void CorsairLightingNodeController::SetChannelLEDs(unsigned char channel, RGBCol
void CorsairLightingNodeController::SendFirmwareRequest()
{
int actual;
unsigned char usb_buf[65];
unsigned char usb_buf[CORSAIR_LIGHTING_NODE_WRITE_PACKET_SIZE];
/*-----------------------------------------------------*\
| Zero out buffer |
@ -221,8 +224,7 @@ void CorsairLightingNodeController::SendFirmwareRequest()
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
actual = hid_read(dev, usb_buf, 17);
actual = WriteAndRead(usb_buf);
if(actual > 0)
{
@ -239,7 +241,7 @@ void CorsairLightingNodeController::SendDirect
unsigned char* color_data
)
{
unsigned char usb_buf[65];
unsigned char usb_buf[CORSAIR_LIGHTING_NODE_WRITE_PACKET_SIZE];
/*-----------------------------------------------------*\
| Zero out buffer |
@ -264,13 +266,12 @@ void CorsairLightingNodeController::SendDirect
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read_timeout(dev, usb_buf, 17, 5);
WriteAndRead(usb_buf, 5);
}
void CorsairLightingNodeController::SendCommit()
{
unsigned char usb_buf[65];
unsigned char usb_buf[CORSAIR_LIGHTING_NODE_WRITE_PACKET_SIZE];
/*-----------------------------------------------------*\
| Zero out buffer |
@ -292,8 +293,7 @@ void CorsairLightingNodeController::SendCommit()
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read_timeout(dev, usb_buf, 17, 5);
WriteAndRead(usb_buf, 5);
}
void CorsairLightingNodeController::SendBegin
@ -301,7 +301,7 @@ void CorsairLightingNodeController::SendBegin
unsigned char channel
)
{
unsigned char usb_buf[65];
unsigned char usb_buf[CORSAIR_LIGHTING_NODE_WRITE_PACKET_SIZE];
/*-----------------------------------------------------*\
| Zero out buffer |
@ -318,8 +318,7 @@ void CorsairLightingNodeController::SendBegin
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
WriteAndRead(usb_buf);
}
void CorsairLightingNodeController::SendEffectConfig
@ -345,7 +344,7 @@ void CorsairLightingNodeController::SendEffectConfig
unsigned short temperature_2
)
{
unsigned char usb_buf[65];
unsigned char usb_buf[CORSAIR_LIGHTING_NODE_WRITE_PACKET_SIZE];
/*-----------------------------------------------------*\
| Zero out buffer |
@ -396,8 +395,7 @@ void CorsairLightingNodeController::SendEffectConfig
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
WriteAndRead(usb_buf);
}
void CorsairLightingNodeController::SendTemperature()
@ -410,7 +408,7 @@ void CorsairLightingNodeController::SendReset
unsigned char channel
)
{
unsigned char usb_buf[65];
unsigned char usb_buf[CORSAIR_LIGHTING_NODE_WRITE_PACKET_SIZE];
/*-----------------------------------------------------*\
| Zero out buffer |
@ -427,8 +425,7 @@ void CorsairLightingNodeController::SendReset
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
WriteAndRead(usb_buf);
}
void CorsairLightingNodeController::SendPortState
@ -437,7 +434,7 @@ void CorsairLightingNodeController::SendPortState
unsigned char state
)
{
unsigned char usb_buf[65];
unsigned char usb_buf[CORSAIR_LIGHTING_NODE_WRITE_PACKET_SIZE];
/*-----------------------------------------------------*\
| Zero out buffer |
@ -455,8 +452,7 @@ void CorsairLightingNodeController::SendPortState
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read_timeout(dev, usb_buf, 17, 5);
WriteAndRead(usb_buf, 5);
}
void CorsairLightingNodeController::SendBrightness
@ -465,7 +461,7 @@ void CorsairLightingNodeController::SendBrightness
unsigned char brightness
)
{
unsigned char usb_buf[65];
unsigned char usb_buf[CORSAIR_LIGHTING_NODE_WRITE_PACKET_SIZE];
/*-----------------------------------------------------*\
| Brightness goes from 0-100 |
@ -491,8 +487,7 @@ void CorsairLightingNodeController::SendBrightness
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
WriteAndRead(usb_buf);
}
void CorsairLightingNodeController::SendLEDCount()
@ -504,3 +499,34 @@ void CorsairLightingNodeController::SendProtocol()
{
}
int CorsairLightingNodeController::WriteAndRead
(
unsigned char *buf,
int read_timeout_ms
)
{
int hid_read_ret;
/*---------------------------------------------------------*\
| HID I/O start |
\*---------------------------------------------------------*/
{
DeviceGuardLock _ = guard_manager_ptr->AwaitExclusiveAccess();
hid_write(dev, buf, CORSAIR_LIGHTING_NODE_WRITE_PACKET_SIZE);
if(read_timeout_ms > 0)
{
hid_read_ret = hid_read_timeout(dev, buf, CORSAIR_LIGHTING_NODE_READ_PACKET_SIZE, read_timeout_ms);
}
else
{
hid_read_ret = hid_read(dev, buf, CORSAIR_LIGHTING_NODE_READ_PACKET_SIZE);
}
}
/*---------------------------------------------------------*\
| HID I/O end (lock released) |
\*---------------------------------------------------------*/
return hid_read_ret;
}

View file

@ -4,13 +4,18 @@
| Adam Honse (calcprogrammer1@gmail.com), 1/12/2020 |
\*---------------------------------------------------------*/
#include "DeviceGuardManager.h"
#include "RGBController.h"
#include <chrono>
#include <vector>
#include <hidapi/hidapi.h>
#pragma once
#define CORSAIR_LIGHTING_NODE_WRITE_PACKET_SIZE 65 /* First byte is the report number */
#define CORSAIR_LIGHTING_NODE_READ_PACKET_SIZE 17 /* First byte is the report number */
enum
{
CORSAIR_LIGHTING_NODE_PACKET_ID_FIRMWARE = 0x02, /* Get firmware version */
@ -89,7 +94,7 @@ public:
unsigned int GetStripsOnChannel(unsigned int channel);
void SetBrightness(unsigned char brightness);
void SetChannelEffect(unsigned char channel,
unsigned char num_leds,
unsigned char mode,
@ -112,12 +117,13 @@ public:
void KeepaliveThread();
private:
hid_device* dev;
std::string firmware_version;
std::string location;
std::thread* keepalive_thread;
std::atomic<bool> keepalive_thread_run;
std::chrono::time_point<std::chrono::steady_clock> last_commit_time;
hid_device* dev;
std::string firmware_version;
std::string location;
std::thread* keepalive_thread;
std::atomic<bool> keepalive_thread_run;
std::chrono::time_point<std::chrono::steady_clock> last_commit_time;
DeviceGuardManager* guard_manager_ptr;
void SendFirmwareRequest();
@ -182,4 +188,10 @@ private:
void SendLEDCount();
void SendProtocol();
int WriteAndRead
(
unsigned char *buf,
int read_timeout_ms = -1
);
};

View file

@ -78,6 +78,7 @@ INCLUDEPATH +=
hidapi_wrapper/ \
i2c_smbus/ \
i2c_tools/ \
interop/ \
net_port/ \
pci_ids/ \
scsiapi/ \
@ -124,6 +125,7 @@ INCLUDEPATH +=
Controllers/AsusAuraUSBController/ \
Controllers/CherryKeyboardController/ \
Controllers/CoolerMasterController/ \
Controllers/CorsairController/ \
Controllers/CorsairCommanderCoreController/ \
Controllers/CorsairDominatorPlatinumController/ \
Controllers/CorsairHydroController/ \
@ -269,6 +271,9 @@ HEADERS +=
hidapi_wrapper/hidapi_wrapper.h \
i2c_smbus/i2c_smbus.h \
i2c_tools/i2c_tools.h \
interop/DeviceGuard.h \
interop/DeviceGuardLock.h \
interop/DeviceGuardManager.h \
net_port/net_port.h \
pci_ids/pci_ids.h \
qt/DeviceView.h \
@ -419,6 +424,7 @@ HEADERS +=
Controllers/CoolerMasterController/RGBController_CMSmallARGBController.h \
Controllers/CorsairCommanderCoreController/CorsairCommanderCoreController.h \
Controllers/CorsairCommanderCoreController/RGBController_CorsairCommanderCore.h \
Controllers/CorsairController/CorsairDeviceGuard.h \
Controllers/CorsairDominatorPlatinumController/CorsairDominatorPlatinumController.h \
Controllers/CorsairDominatorPlatinumController/RGBController_CorsairDominatorPlatinum.h \
Controllers/CorsairHydroController/CorsairHydroController.h \
@ -877,6 +883,9 @@ SOURCES +=
qt/DetectorTableModel.cpp \
i2c_smbus/i2c_smbus.cpp \
i2c_tools/i2c_tools.cpp \
interop/DeviceGuard.cpp \
interop/DeviceGuardLock.cpp \
interop/DeviceGuardManager.cpp \
net_port/net_port.cpp \
qt/DeviceView.cpp \
qt/hsv.cpp \
@ -1044,6 +1053,7 @@ SOURCES +=
Controllers/CorsairCommanderCoreController/CorsairCommanderCoreController.cpp \
Controllers/CorsairCommanderCoreController/CorsairCommanderCoreControllerDetect.cpp \
Controllers/CorsairCommanderCoreController/RGBController_CorsairCommanderCore.cpp \
Controllers/CorsairController/CorsairDeviceGuard.cpp \
Controllers/CorsairDominatorPlatinumController/CorsairDominatorPlatinumController.cpp \
Controllers/CorsairDominatorPlatinumController/CorsairDominatorPlatinumControllerDetect.cpp \
Controllers/CorsairDominatorPlatinumController/RGBController_CorsairDominatorPlatinum.cpp \

22
interop/DeviceGuard.cpp Normal file
View file

@ -0,0 +1,22 @@
/*---------------------------------------------------------*\
| DeviceGuard.cpp |
| |
| An abstract interface for acquiring and releasing |
| a guard on a device, serving as a foundation for |
| implementing device-specific synchronization mechanisms. |
| |
| Evan Mulawski, 2023-09-05 |
| |
\*---------------------------------------------------------*/
#include "DeviceGuard.h"
DeviceGuard::DeviceGuard()
{
}
DeviceGuard::~DeviceGuard()
{
}

22
interop/DeviceGuard.h Normal file
View file

@ -0,0 +1,22 @@
/*---------------------------------------------------------*\
| DeviceGuard.h |
| |
| An abstract interface for acquiring and releasing |
| a guard on a device, serving as a foundation for |
| implementing device-specific synchronization mechanisms. |
| |
| Evan Mulawski, 2023-09-05 |
| |
\*---------------------------------------------------------*/
#pragma once
class DeviceGuard
{
public:
DeviceGuard();
virtual ~DeviceGuard();
virtual void Acquire() = 0;
virtual void Release() = 0;
};

View file

@ -0,0 +1,22 @@
/*---------------------------------------------------------*\
| DeviceGuardLock.cpp |
| |
| Represents a lock for a device guard, ensuring |
| exclusive access to a device when acquired |
| and releasing it when destroyed. |
| |
| Evan Mulawski, 2023-09-05 |
| |
\*---------------------------------------------------------*/
#include "DeviceGuardLock.h"
DeviceGuardLock::DeviceGuardLock(DeviceGuard& guard_ref) : guard(guard_ref)
{
guard.Acquire();
}
DeviceGuardLock::~DeviceGuardLock()
{
guard.Release();
}

24
interop/DeviceGuardLock.h Normal file
View file

@ -0,0 +1,24 @@
/*---------------------------------------------------------*\
| DeviceGuardLock.h |
| |
| Represents a lock for a device guard, ensuring |
| exclusive access to a device when acquired |
| and releasing it when destroyed. |
| |
| Evan Mulawski, 2023-09-05 |
| |
\*---------------------------------------------------------*/
#pragma once
#include "DeviceGuard.h"
class DeviceGuardLock
{
public:
DeviceGuardLock(DeviceGuard& guard_ref);
~DeviceGuardLock();
private:
DeviceGuard& guard;
};

View file

@ -0,0 +1,27 @@
/*---------------------------------------------------------*\
| DeviceGuardManager.cpp |
| |
| Responsible for managing a DeviceGuard implementation, |
| allowing clients to wait for exclusive access to a |
| device using the DeviceGuardLock it provides. |
| |
| Evan Mulawski, 2023-09-05 |
| |
\*---------------------------------------------------------*/
#include "DeviceGuardManager.h"
DeviceGuardManager::DeviceGuardManager(DeviceGuard* guard_ptr) : guard(guard_ptr)
{
}
DeviceGuardManager::~DeviceGuardManager()
{
delete guard;
}
DeviceGuardLock DeviceGuardManager::AwaitExclusiveAccess()
{
return DeviceGuardLock(*guard);
}

View file

@ -0,0 +1,26 @@
/*---------------------------------------------------------*\
| DeviceGuardManager.h |
| |
| Responsible for managing a DeviceGuard implementation, |
| allowing clients to wait for exclusive access to a |
| device using the DeviceGuardLock it provides. |
| |
| Evan Mulawski, 2023-09-05 |
| |
\*---------------------------------------------------------*/
#pragma once
#include "DeviceGuardLock.h"
class DeviceGuardManager
{
public:
DeviceGuardManager(DeviceGuard* guard_ptr);
~DeviceGuardManager();
DeviceGuardLock AwaitExclusiveAccess();
private:
DeviceGuard* guard;
};