[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2367
  • Last Modified:

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?
0
ycl
Asked:
ycl
  • 6
  • 5
1 Solution
 
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
Learn to develop an Android App

Want to increase your earning potential in 2018? Pad your resume with app building experience. Learn how with this hands-on course.

 
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
 
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

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 6
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now