...
@ollydbg: Does my patch still cause the hang with the above fix?
@Huki, many thanks, fairly clear explanation, I just test the code and no hang now.
This is the code I use:
bool Tokenizer::ReplaceBufferText(const wxString& target, bool updatePeekToken)
{
if (target.IsEmpty())
return false;
if (m_IsReplaceParsing)
{
if (m_RepeatReplaceCount >= s_MaxRepeatReplaceCount)
{
m_TokenIndex = m_BufferLen - m_FirstRemainingLength;
m_PeekAvailable = false;
SkipToEOL(false);
return false;
}
else
++m_RepeatReplaceCount;
}
.....
BTW: I originally thought the test condition in PeekToken() can be changed to
if (m_IsReplaceParsing && savedReplaceCount < (int)m_RepeatReplaceCount)
Because in some cases, m_RepeatReplaceCount will reset to zero, but finally I found that is not necessary, because both m_IsReplaceParsing and m_RepeatReplaceCount will be reset to zero in the same time.
if (m_FirstRemainingLength != 0 && m_BufferLen - m_FirstRemainingLength < m_TokenIndex)
{
m_FirstRemainingLength = 0;
m_IsReplaceParsing = false;
m_RepeatReplaceCount = 0;
}
BTW2: Why we need two variables? I think m_IsReplaceParsing is a redundant variable of m_RepeatReplaceCount. Checking all the source code, I realize that
RepeatReplaceCount > 0 means m_IsReplaceParsing == true
RepeatReplaceCount == 0 means m_IsReplaceParsing == false
So, if we remove the m_IsReplaceParsing, we can change the test to
if (savedReplaceCount < m_RepeatReplaceCount)
But the code to initialize savedReplaceCount can be simply
size_t savedReplaceCount = m_RepeatReplaceCount;
Then
can change to
if (m_RepeatReplaceCount > 0)
Also need to adjust the code below
// Set replace parsing state, and save first replace token index
if (!m_IsReplaceParsing)
{
m_FirstRemainingLength = m_BufferLen - m_TokenIndex;
m_IsReplaceParsing = true;
}
I will prepare two commits:
1, fix the hang issue as you suggest.
2, code refactoring by remove the m_IsReplaceParsing variable.
Finally, thanks for your help!