Driver: D3XX: Refactor pipe logic
parent
70733b3d96
commit
e88cd244c8
|
|
@ -65,6 +65,7 @@ bool FTD3XX::open() {
|
||||||
handle.emplace(tmpHandle);
|
handle.emplace(tmpHandle);
|
||||||
|
|
||||||
setIsClosing(false);
|
setIsClosing(false);
|
||||||
|
setIsDisconnected(false);
|
||||||
readThread = std::thread(&FTD3XX::readTask, this);
|
readThread = std::thread(&FTD3XX::readTask, this);
|
||||||
writeThread = std::thread(&FTD3XX::writeTask, this);
|
writeThread = std::thread(&FTD3XX::writeTask, this);
|
||||||
|
|
||||||
|
|
@ -82,7 +83,9 @@ bool FTD3XX::close() {
|
||||||
}
|
}
|
||||||
|
|
||||||
setIsClosing(true);
|
setIsClosing(true);
|
||||||
setIsDisconnected(false);
|
|
||||||
|
// unblock the read thread
|
||||||
|
FT_AbortPipe(*handle, READ_PIPE_ID);
|
||||||
|
|
||||||
if(readThread.joinable())
|
if(readThread.joinable())
|
||||||
readThread.join();
|
readThread.join();
|
||||||
|
|
@ -105,76 +108,75 @@ bool FTD3XX::close() {
|
||||||
void FTD3XX::readTask() {
|
void FTD3XX::readTask() {
|
||||||
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
||||||
|
|
||||||
static constexpr auto bufferSize = 2048;
|
std::vector<uint8_t> buffer(2 * 1024 * 1024);
|
||||||
uint8_t buffer[bufferSize] = {};
|
|
||||||
|
|
||||||
FT_SetStreamPipe(*handle, false, false, READ_PIPE_ID, bufferSize);
|
FT_SetStreamPipe(*handle, false, false, READ_PIPE_ID, (ULONG)buffer.size());
|
||||||
FT_SetPipeTimeout(*handle, READ_PIPE_ID, 1);
|
|
||||||
while(!isClosing() && !isDisconnected()) {
|
// disable timeouts, we will interupt the read thread with AbortPipe
|
||||||
|
FT_SetPipeTimeout(*handle, READ_PIPE_ID, 0);
|
||||||
|
|
||||||
|
OVERLAPPED overlapped = {};
|
||||||
|
FT_InitializeOverlapped(*handle, &overlapped);
|
||||||
|
|
||||||
|
FT_STATUS status;
|
||||||
ULONG received = 0;
|
ULONG received = 0;
|
||||||
OVERLAPPED overlap = {};
|
|
||||||
FT_InitializeOverlapped(*handle, &overlap);
|
while(!isClosing() && !isDisconnected()) {
|
||||||
|
received = 0;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
FT_ReadPipe(*handle, READ_PIPE_ID, buffer, bufferSize, &received, &overlap);
|
status = FT_ReadPipe(*handle, READ_PIPE_ID, buffer.data(), (ULONG)buffer.size(), &received, &overlapped);
|
||||||
#else
|
#else
|
||||||
FT_ReadPipeAsync(*handle, 0, buffer, bufferSize, &received, &overlap);
|
status = FT_ReadPipeAsync(*handle, 0, buffer.data(), buffer.size(), &received, &overlapped);
|
||||||
#endif
|
#endif
|
||||||
while(!isClosing()) {
|
if(FT_FAILED(status)) {
|
||||||
const auto ret = FT_GetOverlappedResult(*handle, &overlap, &received, true);
|
if(status != FT_IO_PENDING) {
|
||||||
if(ret == FT_IO_PENDING)
|
addEvent(status, APIEvent::Severity::Error);
|
||||||
continue;
|
setIsDisconnected(true);
|
||||||
if(ret != FT_OK) {
|
break;
|
||||||
if(ret == FT_IO_ERROR) {
|
}
|
||||||
|
status = FT_GetOverlappedResult(*handle, &overlapped, &received, true);
|
||||||
|
if(FT_FAILED(status)) {
|
||||||
|
addEvent(status, APIEvent::Severity::Error);
|
||||||
setIsDisconnected(true);
|
setIsDisconnected(true);
|
||||||
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
|
|
||||||
} else {
|
|
||||||
addEvent(ret, APIEvent::Severity::Error);
|
|
||||||
}
|
|
||||||
FT_AbortPipe(*handle, READ_PIPE_ID);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
FT_ReleaseOverlapped(*handle, &overlap);
|
|
||||||
if(received > 0) {
|
if(received > 0) {
|
||||||
pushRx(buffer, received);
|
pushRx(buffer.data(), received);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FT_ReleaseOverlapped(*handle, &overlapped);
|
||||||
|
}
|
||||||
|
|
||||||
void FTD3XX::writeTask() {
|
void FTD3XX::writeTask() {
|
||||||
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
||||||
|
|
||||||
FT_SetPipeTimeout(*handle, WRITE_PIPE_ID, 100);
|
FT_SetPipeTimeout(*handle, WRITE_PIPE_ID, 0);
|
||||||
WriteOperation writeOp;
|
WriteOperation writeOp;
|
||||||
|
ULONG sent;
|
||||||
|
FT_STATUS status;
|
||||||
|
|
||||||
while(!isClosing() && !isDisconnected()) {
|
while(!isClosing() && !isDisconnected()) {
|
||||||
if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100)))
|
if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const auto size = static_cast<ULONG>(writeOp.bytes.size());
|
const auto size = static_cast<ULONG>(writeOp.bytes.size());
|
||||||
ULONG sent = 0;
|
sent = 0;
|
||||||
OVERLAPPED overlap = {};
|
|
||||||
FT_InitializeOverlapped(*handle, &overlap);
|
|
||||||
FT_SetStreamPipe(*handle, false, false, WRITE_PIPE_ID, size);
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
FT_WritePipe(*handle, WRITE_PIPE_ID, writeOp.bytes.data(), size, &sent, &overlap);
|
status = FT_WritePipe(*handle, WRITE_PIPE_ID, writeOp.bytes.data(), size, &sent, nullptr);
|
||||||
#else
|
#else
|
||||||
FT_WritePipeAsync(*handle, 0, writeOp.bytes.data(), size, &sent, &overlap);
|
status = FT_WritePipe(*handle, WRITE_PIPE_ID, writeOp.bytes.data(), size, &sent, 100);
|
||||||
#endif
|
#endif
|
||||||
while(!isClosing()) {
|
if(FT_FAILED(status)) {
|
||||||
const auto ret = FT_GetOverlappedResult(*handle, &overlap, &sent, true);
|
addEvent(status, APIEvent::Severity::Error);
|
||||||
if(ret == FT_IO_PENDING)
|
setIsDisconnected(true);
|
||||||
continue;
|
break;
|
||||||
if(ret != FT_OK) {
|
}
|
||||||
if(ret == FT_IO_ERROR) {
|
if(sent != size) {
|
||||||
|
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
|
||||||
setIsDisconnected(true);
|
setIsDisconnected(true);
|
||||||
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
|
|
||||||
} else {
|
|
||||||
addEvent(ret, APIEvent::Severity::Error);
|
|
||||||
}
|
|
||||||
FT_AbortPipe(*handle, WRITE_PIPE_ID);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
FT_ReleaseOverlapped(*handle, &overlap);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue