I have a question regarding calling methods from different threads. Well I am using WinUSB driver to communicate with USB device. I have separate thread to read data from device. Commands to device are set within main thread. Actually I am using WinUSB_WritePipe and WinUSB_ReadPipe methods to do such operations. In thread where data is read I use asynchronus method of reading with overlapped structure and WaitForMultipleObject. My device has some features that I need to set and this is done via GUI in main thread.
I am observing some strange behaviour. My question is do I need to lock calls (eg. with mutex) to this methods so just one thread at time is accessing or calling method.
OLD WAY:
type TMyThread = TThread
protected
procedure Execute; override;
end;
procedure TMyThread.Execute;
begin
while not Terminated do
begin
WinUsb_ReadPipe(Pipe, Amount, Overlapped)
ErrNo := GetLastError;
if ErrNo = ERROR_IO_PENDING then
begin
wRes = WaitForMultipleObjects(2, @HndEvt, false);
if wRes = WAIT_OBJECT_0 then
begin
ResetEvent(Overlapped.hEvent);
WinUSB_GetOVerlappedResult
DoSomethingWithData; // Do something
end;
end;
end;
end;
MainThread:
begin
// Set device sample rate
WinUSB_WritePipe (Pipe, Amount, Data, ...)
end;
NEW WAY:
type TMyThread = TThread
protected
procedure Execute; override;
public
procedure Lock;
procedure Unlock;
constructor Create(ASuspended: boolean); override;
destructor Destroy; override;
end;
constructor TMyThread.Create(ASuspended: boolean);
begin
hMtx := CreateMutex(nil, false, nil);
end;
destructor TMyThread.Destroy(ASuspended: boolean);
begin
CloseHandle(hMtx);
end;
procedure TMyThread.Lock;
begin
WaitForSingleObject(hMtx, 10000);
end;
procedure TMyThread.Unlock;
begin
ReleaseMutex(hMtx);
end;
procedure TMyThread.Execute;
begin
while not Terminated do
begin
Lock;
WinUsb_ReadPipe(Pipe, Amount, Overlapped)
Unlock;
ErrNo := GetLastError;
if ErrNo = ERROR_IO_PENDING then
begin
wRes = WaitForMultipleObjects(2, @HndEvt, false);
if wRes = WAIT_OBJECT_0 then
begin
ResetEvent(Overlapped.hEvent);
Lock;
WinUSB_GetOVerlappedResult
Unlock;
DoSomethingWithData; // Do something
end;
end;
end;
end;
MainThread:
begin
// Set device sample rate
Lock; // same mutex as in TMYThread
WinUSB_WritePipe (Pipe, Amount, Data, ...)
Unlock; // same mutex as in TMYThread
end;
This is very simplified code which intension is only for description of my problem and do not reflect my programming skills. :) Of course with same mutex I lock then calling of same method in main thread.
I hope I described my problem as simple as possible... so again: Do I need to lock calls to those methods in different threads?
Thank you for your time and answers in advance. I really apppreciate it!
Br, Nix
if you download and read the winUSB white paper you will find that there is one big drawback of winUSB : it does not support multiple concurrent applications for the same USB device. IMHO this means you can't have concurrent calls for reading.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With