🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.cppbuilder.nativeapi
Article #216

events and overlapped structures

#216
From: Lesley Anne
Date: Tue, 08 Jul 2008 19:00
116 lines
5519 bytes
I've been having trouble figuring out how to get events and overlapped
structures to work.  This portion of our application connects to a named
pipe and reads from it.  So long as there is data on the pipe to be read,
it works fine.  We can connect and disconnect and re-connect again and
read whatever is there whenever we're connected.  The problem comes when
there is no data on the pipe to be read.  In our initial (non-overlapped)
version, it got stuck in the ReadFile function.  This is why we went to
the overlapped structure, so that we could tell it to stop trying to read,
even if it hadn't read anything.  But it doesn't seem to help.  We still
get stuck trying to read, so I'm trying to figure out why our stop event
isn't working.

In our main unit, we have a global
   HANDLE gbl_hStopEvent;
which is initialized in the main form's constructor as:
   gbl_hStopEvent = CreateEvent(NULL,  // default security attribute
                                TRUE,  // manual reset event
                               FALSE,  // initial state = not signaled
                                NULL); // not a named event object

We have a startup function that connects to a named pipe and then starts up
a reading thread:
     pReadThread = new TReadThread(hReadPipe, gbl_hStopEvent);

When we want to close the connection we have a Cleanup function which
triggers the reading thread to terminate and sets that gbl_hStopEvent so
that the reading thread will get out of its WaitForMultipleObjects call
and see that it was terminated.

void Cleanup(void) {
   pReadThread->Terminate();
   SetEvent(gbl_hStopEvent);
   FlushFileBuffers(hWritePipe);
   //FlushFileBuffers(hReadPipe);
   DisconnectNamedPipe(hReadPipe);
   DisconnectNamedPipe(hWritePipe);
}

The problem is that the thread isn't seeing that gbl_hStopEvent.  If it isn't
getting data to read, then it remains permanently stuck (presumably in its
WaitForMultipleObjects call).  What's more, since that's using the read pipe,
the main unit is unable to DisconnectNamedPipe(hReadPipe) so then that gets
stuck as well.

Here's what the reading thread looks like:

// ---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "ReadThreadUnit.h"
#pragma package(smart_init)
// ---------------------------------------------------------------------------
__fastcall TReadThread::TReadThread(HANDLE hReadPipe, HANDLE hStopEvent)
        : TThread(false)
{
   ReadPipeHandle  = hReadPipe;
   StopEventHandle = hStopEvent;
}
// ---------------------------------------------------------------------------
void __fastcall TReadThread::Execute()
{
   DWORD cbBytesRead=0 ;
   BOOL Success;
   OVERLAPPED op;
   HANDLE HandleArray[2];
   bool bStop=false;

   memset(&op, 0, sizeof(op));
   HandleArray[0] = op.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
   HandleArray[1] = StopEventHandle;
   ResetEvent(StopEventHandle);

   while (!Terminated && !bStop) {
      Success = ReadFile(ReadPipeHandle, szReadRequest, READ_BUFSIZE,
                            &cbBytesRead, &op);

      if (Success) {
         szReadRequest[cbBytesRead] = 0;
         if (cbBytesRead)
              Synchronize(SendReadMessage);
         else Synchronize(SendReadError);
      }
      else {
         if (GetLastError() == ERROR_IO_PENDING) {
            SetLastError(0);
            switch (WaitForMultipleObjects(2, HandleArray, FALSE, INFINITE)) {
               case WAIT_OBJECT_0:
                  Success = GetOverlappedResult(ReadPipeHandle, &op,
                                                &cbBytesRead, FALSE);
                  if (Success) {
                     szReadRequest[cbBytesRead] = 0;
                     Synchronize(SendReadMessage);
                  }
                  else
                     Synchronize(SendReadError);
                  ResetEvent(HandleArray[0]);
               break ;
               case WAIT_OBJECT_0+1:
                  bStop = true;
               break;
            }
         }
         else Synchronize(SendReadError);
      }
   }
}
// ---------------------------------------------------------------------------
void __fastcall TReadThread::SendReadMessage() {
   Form1->HandleReadMessage(szReadRequest) ;
}
// ---------------------------------------------------------------------------
void __fastcall TReadThread::SendReadError() {
   Form1->HandleReadErrors() ;
}
// ---------------------------------------------------------------------------
Technical Details
Message-ID: <4873b98e$1@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!g2news1.google.com!news3.google.com!feeder.news-service.com!newsfeed.freenet.de!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail

Show Full Headers
Complete Article Headers
X-Google-Thread: 10cc67,e9d4b7e876cb4c6a,start
X-Google-Attributes: gid10cc67,domainid0,public,usenet
X-Google-Language: ENGLISH,ASCII-7-bit
From: "Lesley Anne" <mspfila (dash) brl (at) yahoo (dot) com>
Newsgroups: borland.public.cppbuilder.nativeapi
Subject: events and overlapped structures
Date: Tue, 8 Jul 2008 15:00:18 -0400
Lines: 118
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2900.3138
X-RFC2646: Format=Flowed; Original
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.3198
NNTP-Posting-Host: 144.160.5.25
Message-ID: <4873b98e$1@newsgroups.borland.com>
X-Trace: newsgroups.borland.com 1215543694 144.160.5.25 (8 Jul 2008 12:01:34 -0700)
Path: arc1-ca.pugleaf.net!g2news1.google.com!news3.google.com!feeder.news-service.com!newsfeed.freenet.de!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail