Why GetOverlappedResult hangs?

When I operate on the com port to communicate with a fairly slow terminal equipment(for instance,the response of it may take nearly seven or eight seconds).I set the commtimeoutsconstant to 1000ms,when the TE responds in less than 1000ms every thing is OK,but when the TE responds slower than 1000ms,the GetOverlappedResult hangs and can't return to my program. I'm quite puzzled. What should to be take into attention when dealing with com port and getoverlappedresult? How to prevent the prolem above?
yclAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Vinayak KumbarSr Program ManagerCommented:
Hi,

Is that a different thread to read the com port. R U waiting for the com events using WaitCommEvent() function. Now if the hardware responds back after the timeout value, u r supposed to drop that data, right?.

There are some samples in the following sites. U can go through them
http://www.sysinternals.com/portmon.htm 
http://codeguru.developer.com/network/commspy.shtml

Try it out.
VinExpert
0
abdijCommented:
Hi,

  Are you first trying to ReadFile() the port, GetLastError() route or directly doing GetOverlappedResult()?

Generally the reading thread does the ReadFile() to read from the port. In case theres nothing to read then the Functions returns an error. If the Error got is ERROR_IO_PENDING this implies that an IO is pending and the GetOverlappedresult() has to be used to get the result. In case the GetOverlappedresult returns ERROR_IO_INCOMPLETE it implies that the IO is still not complete. Other errors need to be probed.

Hope this what you wanted.
Abdij
Feel free to ask
abdij_b@hotmail.com
0
yclAuthor Commented:
Here's my code,what's wrong with it?

//do reading
lResult=WaitCommEvent(m_hComm,&lMask,&wl);
lResult=ResultCheck(lResult,&wl,lError,lCnt);
if(lResult && (lMask&EV_RXCHAR))
{
      lResult=ReadFile(m_hComm,m_strBuf,MAX_BUF,&lCnt,&rl);
      lResult=ResultCheck(lResult,&rl,lError,lCnt);
}

//check the result
int CPBAccess::ResultCheck(DWORD r,OVERLAPPED *ol,DWORD &err,DWORD &lCnt)
{
      int iRtn=1,iInCompCnt=0;
      DWORD lError;
      COMSTAT s;

      err=0;

      if(!r)
      {
            lError=GetLastError();
            if(lError==ERROR_IO_PENDING)
            {
                  while(!GetOverlappedResult(m_hComm,ol,&lCnt,TRUE))
                  {
                        lError=GetLastError();
                        if(lError==ERROR_IO_INCOMPLETE)
                        {            
                                    iInCompCnt++;
                                    if(iInCompCnt<500)continue;
                                    else {      iRtn=0;      break;      }
                        }
                        else
                        {
                              err=lError;      
                              iRtn=0;

                              ClearCommError(m_hComm,&lError,&s);
                        }
                  }
            }
            else
            {      
                  err=lError;            
                  iRtn=0;

                  ClearCommError(m_hComm,&lError,&s);
            }
      }
      
      return iRtn;
}

0
Cloud Class® Course: CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

abdijCommented:
Hi ,

 You are waiting for an Comm event to occur. Fine.
After getting the event signal please verify if the event is the one you have desired (lResult == WAIT_OBJECT_0).
If so
1. First ReadFile();
2. If the operation fails GetLastError()
3. If Error is ERROR_IO_PENDING then
4. GetOverlappedResult(). If success fine you have the result else
5. If Error is ERROR_IO_INCOMPLETE the operation is not yet over else some serious problem. (Normall this does not happen).

In your case the ResultCheck() is called even before a ReadFile() is done.

Here is a snap shot of some communication code that i had downloaded.

      BOOL bReadStat = ReadFile(lpConn->hCommDev, lpszBlock, dwLength,
                                &dwLength, &lpConn->osRead);

      if(!bReadStat)
      {
         if(GetLastError() == ERROR_IO_PENDING)
         {
            OutputDebugString("\n\rIO Pending");
            // we have to wait for read to complete.  This function will timeout
            // according to the CommTimeOuts.ReadTotalTimeoutConstant variable
            // Every time it times out, check for port errors
            while(!GetOverlappedResult(lpConn->hCommDev, &lpConn->osRead,
                                       &dwLength, TRUE))
            {
               DWORD dwError = GetLastError();
               if(dwError == ERROR_IO_INCOMPLETE)
               {
                  // normal result if not finished
                  continue;
               }
               else
               {
                  // CAN DISPLAY ERROR MESSAGE HERE
                  // an error occured, try to recover
                  ::ClearCommError(lpConn->hCommDev, &dwErrorFlags, &ComStat);
                  if(dwErrorFlags > 0)
                  {
                     // CAN DISPLAY ERROR MESSAGE HERE
                  }

                  break;
               }
            }
           
         }
         else
         {
            // some other error occured
            dwLength = 0;
            ClearCommError(lpConn->hCommDev, &dwErrorFlags, &ComStat);
            if(dwErrorFlags > 0)
            {
               // CAN DISPLAY ERROR MESSAGE HERE
            }
         }
      }

Hope this satisfies your needs. Model your code structure likewise and see the result. Happy coding.
All the best
Bye.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
abdijCommented:
Hi,

 Are you still there???????????

Bye
Abdij
0
yclAuthor Commented:
Sorry,but I have one more question to ask: What should we do if WaitCommEvent fails?
0
abdijCommented:
Hi,

 The reasons why the WaitCommEvent fails can be known by doing a GetLastError().

DWORD dwError =  GetLastError();
Either get this value in Debug mode or wsprintf() to form the string out of DWORD and MessageBox() it.
Once you know the error number find what it stands for in the Error Codes.
Mostly you might have not created the event in the Overlapped function or such errors. report the error to me too, lets see what it it is. its too dangerous to predict without data.

Awaiting prompt reply,
Abdij
0
yclAuthor Commented:
Here is my code:

long lCnt,lError;

MyWaitEvent=CreateEvent(NULL,TRUE,FALSE,NULL);

MyReadEvent=CreateEvent(NULL,TRUE,FALSE,NULL);

wl.hEvent=MyWaitEvent;
rl.hEvent=MyReadEvent;

do
{
 lResult=WaitCommEventm_hComm,&lMask,&wl);
lResult=ResultChecklResult,&wl,lError,lCnt);
if(lResult==WAIT_OBJECT_0 && (lMask&EV_RXCHAR))
{
                  lResult=ReadFile(m_hComm,m_strBuf+m_iBufPtr,MAX_BUF-m_iBufPtr,&lCnt,&rl);
                  lResult=ResultCheck(lResult,&rl,lError,lCnt);

}while(lCnt>0)
0
abdijCommented:
Hi,
 Again, is the ResultCheck() function same as the previous you had?
 If so you are again calling the GetOverlappedResult() before readFile().

Can you not do it this way?

DWORD dwError = 0;

lResult = WaitCommEvent(m_hComm,&lMask,&wl);
if(lResult == 0)
{
 dwError = GetLastError();
 // see what the error is)
}
if(lMask&EV_RXCHAR == EV_RXCHAR)
{
 lResult = ReadFile(m_hComm, m_strBuf+m_iBufPtr, MAX_BUF-m_iBufPtr, &lCnt, &rl);
 if(lResult == 0)
 {
   dwError = GetLastError();
   if(dwError == ERROR_IO_PENDING)
   {
    lResult = GetOverlappedresult(....);
    if(lResult == ERROR_IO_INCOMPLETE)
    {
      // normal error
      continue;
    }
    else
    {
     // garve error display;
     }
   }


If you give me your mail id i will send a sample on how this is done. I think your way of doing it is not correct.

Once again go through the Question history and model your code accordingly. Please.

You are currently not implementing it the way i suggested.

Bye
Give me mail id.
Abdij


lResult  = ResultCheck(lResult, &rl, lError, lCnt);




0
yclAuthor Commented:
my mail is ycl@371.net
0
yclAuthor Commented:
Thank you very much,my mail is ycl@371.net
0
abdijCommented:
Hi,
 I have sent you the sample

Bye.
ABdij
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.