🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

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

Re: aborting a function

#14905
From: Clayton Arends
Date: Sat, 26 Jul 2003 07:51
187 lines
5213 bytes
"Robert L. Smith" <bsmithOMIT@cinSPAMele.com> wrote in message
news:3f21a974@newsgroups.borland.com...

> More complicated approaches using threads ... haven't worked.

I don't understand what you mean by this.  Using a thread is the only way I
can see to allow your application to continue execution and to wait for the
hardware call to talk_to_hardware() to return.  Perhaps there were technical
difficulties trying to get a thread to work for you ... if the suggestion I
have below doesn't work in your case then perhaps you can elaborate on why a
thread won't work for you.

> Is there a simple way to meet all these requirements?

This is how I might do it:


//--------------------------------------------------------------------------
-  // thread.h

//--------------------------------------------------------------------------
-
  #include <Classes.hpp>
  #include <SyncObjs.hpp>

  class TalkHardwareThread : public TThread
  {
    typedef TThread inherited;
    private:
      int fCallCount;
      TCriticalSection* fCallCountCS;

    protected:
      virtual void __fastcall Execute();

    public:
      __fastcall TalkHardwareThread(bool CreateSuspended);

      void AddCallToQueue();
      void Abort();
  };


//--------------------------------------------------------------------------
-  // thread.cpp

//--------------------------------------------------------------------------
-
  #include "thread.h"


  //*****
  // dummy routines to simulate the hardware interface
  bool aborting = false;
  void abort_talking()
  {
    aborting = true;
  }

  int talk_to_hardware()
  {
    // dummy routine to allow compile
    for (int count = 0; count < 20 && !aborting; ++count)
      Sleep(100); // sleep short increments to allow for abort

    Beep();
    return 0;
  }
  //*****

  __fastcall TalkHardwareThread::TalkHardwareThread(bool CreateSuspended)
    : inherited(CreateSuspended)
  {
  }

  void TalkHardwareThread::AddCallToQueue()
  {
    fCallCountCS->Enter();
    ++fCallCount;
    fCallCountCS->Leave();

    if (Suspended)
      Resume();
  }

  void TalkHardwareThread::Abort()
  {
    fCallCountCS->Enter();
    fCallCount = 0;
    fCallCountCS->Leave();

    abort_talking();
  }

  void __fastcall TalkHardwareThread::Execute()
  {
    fCallCountCS = new TCriticalSection;

    try
    {
      while (!Terminated)
      {
        fCallCountCS->Enter();
        bool  call = fCallCount > 0;
        fCallCountCS->Leave();

        if (call)
        {
          fCallCountCS->Enter();
          --fCallCount;
          fCallCountCS->Leave();

          talk_to_hardware();
        }
        else
          Suspend();
      }
    }
    catch (...)
    {
    }

    delete fCallCountCS;
  }


//--------------------------------------------------------------------------
-  // main.h

//--------------------------------------------------------------------------
-
  #include "thread.h"

  class TForm1 : public TForm
  {
    __published:
    TButton *TalkBtn;
    TButton *AbortBtn;
    void __fastcall TalkBtnClick(TObject *Sender);
    void __fastcall AbortBtnClick(TObject *Sender);
    private:
      TalkHardwareThread* fTalkHardwareThread;

    public:
      __fastcall TForm1(TComponent* Owner);
      __fastcall ~TForm1();
  };


//--------------------------------------------------------------------------
-  // main.cpp

//--------------------------------------------------------------------------
-
  #include "main.h"

  TForm1 *Form1;

  __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
  {
    fTalkHardwareThread = new TalkHardwareThread(false);
  }

  __fastcall TForm1::~TForm1()
  {
    fTalkHardwareThread->Abort();
    fTalkHardwareThread->Terminate();
    if (fTalkHardwareThread->Suspended)
      fTalkHardwareThread->Resume();
    Application->ProcessMessages();
    fTalkHardwareThread->WaitFor();

    delete fTalkHardwareThread;
  }

  void __fastcall TForm1::TalkBtnClick(TObject *Sender)
  {
    fTalkHardwareThread->AddCallToQueue();
  }

  void __fastcall TForm1::AbortBtnClick(TObject *Sender)
  {
    fTalkHardwareThread->Abort();
  }

HTH,
- Clayton
Technical Details
Message-ID: <3f2232db$1@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!sn-xit-02!sn-xit-06!sn-xit-08!supernews.com!newsfeed.wirehub.nl!news.kweb.on.ca!KWeb!newsgroups.borland.com!not-for-mail
References: <3f21a974@newsgroups.borland.com>

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 10cc67,cb957e45a585bf2c
X-Google-Attributes: gid10cc67,public
X-Google-ArrivalTime: 2003-07-26 01:09:35 PST
From: "Clayton Arends" <nospam_claytonarends@hotmail.com>
Newsgroups: borland.public.cppbuilder.nativeapi
References: <3f21a974@newsgroups.borland.com>
Subject: Re: aborting a function
Date: Sat, 26 Jul 2003 00:51:04 -0700
Lines: 189
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2800.1158
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1165
NNTP-Posting-Host: 24.30.128.202
Message-ID: <3f2232db$1@newsgroups.borland.com>
X-Trace: newsgroups.borland.com 1059205851 24.30.128.202 (26 Jul 2003 00:50:51 -0700)
Path: arc1-ca.pugleaf.net!archiver1.google.com!news1.google.com!sn-xit-02!sn-xit-06!sn-xit-08!supernews.com!newsfeed.wirehub.nl!news.kweb.on.ca!KWeb!newsgroups.borland.com!not-for-mail