🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

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

Re: Differences between Semaphore and Mutex

#1320
From: Dennis Jones
Date: Sun, 16 Sep 2007 19:27
106 lines
4695 bytes
"Danny" <danny2912@libero.it> wrote in message 
news:46ed7265@newsgroups.borland.com...
> Hi Dennis,
> thank you for your detailed explanation.
> Fundamentally I have a TThread class, and when I close my application, the 
> terminate event isn't come execute, and so I need to synchronization. 
> Currently I've:
>
> void __fastcall TFMain::FormClose(TObject *Sender, TCloseAction &Action)
> {
>    HANDLE h=CreateSemaphore(NULL,0,1,"PddSem");
>    Control->Terminate();
>    while(WaitForSingleObject(h,500)!=WAIT_OBJECT_0)
>      Application->ProcessMessages();
>    ::CloseHandle(h);
> }
>
> void __fastcall TThreadControl::TerminateEvent(TObject *Sender)
> {
>  .... my code .....
>  HANDLE h=OpenSemaphore(SEMAPHORE_ALL_ACCESS,false,"PddSem");
>  ReleaseSemaphore(h,1,NULL);
>  CloseHandle(h);
> }
>
> However I'll try with TCriticalSection class.


It looks like you want to wait for the thread to complete before exiting the 
application.  However, you don't really need another synchronization object 
to do that.  You should be able to wait on the TThread's handle directly. 
For example:

  while(WaitForSingleObject(Control->Handle,500)!=WAIT_OBJECT_0)
     Application->ProcessMessages();

I'm guessing you are using ProcessMessages so that the form continues to 
update while the thread is shutting down.  This works okay, but it's not 
very efficient.  By the time FormClose is called, the form is about to be 
closed, and by waiting for a thread to terminate inside FormClose -- if you 
want the form to update during the shutdown process -- you are forced to 
find a way to update the form while the thread shuts down (because FormClose 
executes within the context of the main thread, thereby preventing updates 
from happening).  A better solution would be to shutdown the thread before 
closing the form, thereby allowing the main thread to continue updating the 
form while the thread shuts down, without any special handling.

For example, when you know it is time to close the form, you could post a 
message to the form that, when handled, does something like this (UNTESTED):


class TFMain : public TForm
{
    MESSAGE void __fastcall WM_CloseApp(TMessage &Message);
    #define WM_CLOSEAPP WM_APP+1
BEGIN_MESSAGE_MAP
    MESSAGE_HANDLER(WM_CLOSEAPP, TMessage, WM_CloseApp);
END_MESSAGE_MAP(TForm);
};

MESSAGE void __fastcall TFMain::WM_CloseApp(TMessage &Message)
{
    delete FThread;  // requires the destructor to terminate and wait
    Close();
}

__fastcall TThreadControl::~TThreadControl()
{
   Terminate();
   WaitFor();
}


Note: If you don't want to write the thread's destructor that way, or if the 
thread is destroyed automatically by way of a smart pointer or the 
FreeOnTerminate flag, you might prefer to do something like this instead:

MESSAGE void __fastcall TFMain::WM_CloseApp(TMessage &Message)
{
    FThread->Terminate();
    FThread->WaitFor();
    Close();
}


// Now, when you want to close the application, you post a special message 
to the form so the WM_CloseApp method gets called:
PostMessage( this->Handle, WM_CLOSEAPP, 0, 0 );

Don't post the message from FormClose though, or your form will disappear 
while the thread shuts down.  Instead, when you could do it in 
FormCloseQuery:

void __fastcall TFMain::FormCloseQuery(TObject *Sender, bool &CanClose)
{
    if ( IDOK == Application->MessageBox( "Okay to close the application?", 
"Confirm", MB_OK | MB_TOPMOST | MB_ICONQUESTION ) )
    {
        PostMessage( this->Handle, WM_CLOSEAPP, 0, 0 );
    }
}

Hope this helps.

- Dennis 
Technical Details
Message-ID: <46ed83aa@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!g2news2.google.com!news2.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail
References: <46ecd663@newsgroups.borland.com> <kcaqe3d7a9ahqkl01dpp52rerc4g54o9et@4ax.com> <46ed637d$1@newsgroups.borland.com> <46ed7265@newsgroups.borland.com>

Show Full Headers
Complete Article Headers
X-Google-Thread: 10cc67,6b2ce248fe32d850
X-Google-Attributes: gid10cc67,public,usenet
X-Google-Language: ENGLISH,ASCII-7-bit
From: "Dennis Jones" <nospam@nospam.com>
Newsgroups: borland.public.cppbuilder.nativeapi
References: <46ecd663@newsgroups.borland.com> <kcaqe3d7a9ahqkl01dpp52rerc4g54o9et@4ax.com> <46ed637d$1@newsgroups.borland.com> <46ed7265@newsgroups.borland.com>
Subject: Re: Differences between Semaphore and Mutex
Date: Sun, 16 Sep 2007 12:27:40 -0700
Lines: 108
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2900.3138
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.3138
X-RFC2646: Format=Flowed; Response
NNTP-Posting-Host: 71.245.109.58
Message-ID: <46ed83aa@newsgroups.borland.com>
X-Trace: newsgroups.borland.com 1189970858 71.245.109.58 (16 Sep 2007 12:27:38 -0700)
Path: arc1-ca.pugleaf.net!g2news2.google.com!news2.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail