ADTPro not working (#707) (PR #714)

. Wrap m_vbTxEmpty in a mutex
. Check WriteFile() result & log error
This commit is contained in:
TomCh 2019-11-02 19:53:00 +00:00 committed by GitHub
parent 5edd8ac32b
commit 3d4691e9bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 9 deletions

View File

@ -181,7 +181,11 @@ void CSuperSerialCard::UpdateCommState()
dcb.ByteSize = m_uByteSize; dcb.ByteSize = m_uByteSize;
dcb.Parity = m_uParity; dcb.Parity = m_uParity;
dcb.StopBits = m_uStopBits; dcb.StopBits = m_uStopBits;
// Specifies the DTR (data-terminal-ready) input flow control (use dcb.fOutxCtsFlow for output)
dcb.fDtrControl = m_uDTR; // GH#386 dcb.fDtrControl = m_uDTR; // GH#386
// Specifies the RTS (request-to-send) input flow control (use dcb.fOutxDsrFlow for output)
dcb.fRtsControl = m_uRTS; // GH#311 dcb.fRtsControl = m_uRTS; // GH#311
SetCommState(m_hCommHandle,&dcb); SetCommState(m_hCommHandle,&dcb);
@ -687,7 +691,21 @@ BYTE __stdcall CSuperSerialCard::CommReceive(WORD, WORD, BYTE, BYTE, ULONG)
void CSuperSerialCard::TransmitDone(void) void CSuperSerialCard::TransmitDone(void)
{ {
m_vbTxEmpty = true; // Transmit done if (m_hCommHandle != INVALID_HANDLE_VALUE)
{
// Use CriticalSection to ensure that write to m_vbTxEmpty is atomic w.r.t CommTransmit() (GH#707)
EnterCriticalSection(&m_CriticalSection);
_ASSERT(m_vbTxEmpty == false);
m_vbTxEmpty = true; // Transmit done (COM)
LeaveCriticalSection(&m_CriticalSection);
}
else
{
_ASSERT(m_vbTxEmpty == false);
m_vbTxEmpty = true; // Transmit done (TCP)
}
if (m_bTxIrqEnabled) // GH#522 if (m_bTxIrqEnabled) // GH#522
{ {
@ -713,6 +731,7 @@ BYTE __stdcall CSuperSerialCard::CommTransmit(WORD, WORD, BYTE, BYTE value, ULON
data &= ~(1 << m_uByteSize); data &= ~(1 << m_uByteSize);
} }
int sent = send(m_hCommAcceptSocket, (const char*)&data, 1, 0); int sent = send(m_hCommAcceptSocket, (const char*)&data, 1, 0);
_ASSERT(sent == 1);
if (sent == 1) if (sent == 1)
{ {
m_vbTxEmpty = false; m_vbTxEmpty = false;
@ -722,10 +741,30 @@ BYTE __stdcall CSuperSerialCard::CommTransmit(WORD, WORD, BYTE, BYTE value, ULON
} }
else if (m_hCommHandle != INVALID_HANDLE_VALUE) else if (m_hCommHandle != INVALID_HANDLE_VALUE)
{ {
BOOL res = false;
DWORD error = 0;
// Use CriticalSection to keep WriteFile() & m_vbTxEmpty in sync (GH#707)
EnterCriticalSection(&m_CriticalSection);
_ASSERT(m_vbTxEmpty == true);
DWORD uBytesWritten; DWORD uBytesWritten;
WriteFile(m_hCommHandle, &value, 1, &uBytesWritten, &m_o); res = WriteFile(m_hCommHandle, &value, 1, &uBytesWritten, &m_o);
m_vbTxEmpty = false; _ASSERT(res);
// NB. Now CommThread() determines when transmit buffer is empty and calls TransmitDone() if (res)
{
m_vbTxEmpty = false;
// NB. Now CommThread() determines when transmit buffer is empty and calls TransmitDone()
}
else
{
error = GetLastError();
}
LeaveCriticalSection(&m_CriticalSection);
if (!res)
LogFileOutput("SSC: CommTransmit(): WriteFile() failed: 0x%08X\n", error);
} }
return 0; return 0;
@ -999,8 +1038,6 @@ void CSuperSerialCard::CommSetSerialPort(HWND hWindow, DWORD dwNewSerialPortItem
// . COMSTAT::InQueue = 0x1000 // . COMSTAT::InQueue = 0x1000
// //
static UINT g_uDbgTotalCOMRx = 0;
void CSuperSerialCard::CheckCommEvent(DWORD dwEvtMask) void CSuperSerialCard::CheckCommEvent(DWORD dwEvtMask)
{ {
if (dwEvtMask & EV_RXCHAR) if (dwEvtMask & EV_RXCHAR)
@ -1016,8 +1053,6 @@ void CSuperSerialCard::CheckCommEvent(DWORD dwEvtMask)
if (!ReadFile(m_hCommHandle, Data, sizeof(Data), &dwReceived, &m_o) || !dwReceived) if (!ReadFile(m_hCommHandle, Data, sizeof(Data), &dwReceived, &m_o) || !dwReceived)
break; break;
g_uDbgTotalCOMRx += dwReceived;
bGotData = true; bGotData = true;
EnterCriticalSection(&m_CriticalSection); EnterCriticalSection(&m_CriticalSection);

View File

@ -115,7 +115,7 @@ private:
// //
CRITICAL_SECTION m_CriticalSection; // To guard /g_vRecvBytes/ CRITICAL_SECTION m_CriticalSection; // To guard /m_vuRxCurrBuffer/ and /m_vbTxEmpty/
std::deque<BYTE> m_qComSerialBuffer[2]; std::deque<BYTE> m_qComSerialBuffer[2];
volatile UINT m_vuRxCurrBuffer; // Written to on COM recv. SSC reads from other one volatile UINT m_vuRxCurrBuffer; // Written to on COM recv. SSC reads from other one
std::deque<BYTE> m_qTcpSerialBuffer; std::deque<BYTE> m_qTcpSerialBuffer;