From 7b4d7f99a60c095ecd28a3e72d48241abe9f7fdb Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Thu, 14 Aug 2003 00:09:36 +0000
Subject: [PATCH] added wxRecursionGuard

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@22835 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/changes.txt           |   1 +
 docs/latex/wx/classes.tex  |   1 +
 docs/latex/wx/recguard.tex | 105 +++++++++++++++++++++++++++++++++++++
 include/wx/recguard.h      |  53 +++++++++++++++++++
 4 files changed, 160 insertions(+)
 create mode 100644 docs/latex/wx/recguard.tex
 create mode 100644 include/wx/recguard.h

diff --git a/docs/changes.txt b/docs/changes.txt
index ef06308310..adecb94b27 100644
--- a/docs/changes.txt
+++ b/docs/changes.txt
@@ -67,6 +67,7 @@ All:
 - added support for POST method and alt ports to wxHTTP (Roger Chickering)
 - added wxSocket::IPAddress() (Chris Mellon)
 - wxDataStreams can read/write many elements at once (Mickael Gilabert)
+- added wxRecursionGuard class
 - added wxThreadHelper class (Daniel Howard)
 
 wxBase:
diff --git a/docs/latex/wx/classes.tex b/docs/latex/wx/classes.tex
index 1b48ad7659..d788fa4820 100644
--- a/docs/latex/wx/classes.tex
+++ b/docs/latex/wx/classes.tex
@@ -237,6 +237,7 @@
 \input radiobut.tex
 \input realpoin.tex
 \input rect.tex
+\input recguard.tex
 \input regex.tex
 \input region.tex
 \input renderer.tex
diff --git a/docs/latex/wx/recguard.tex b/docs/latex/wx/recguard.tex
new file mode 100644
index 0000000000..f7bdfa0cdf
--- /dev/null
+++ b/docs/latex/wx/recguard.tex
@@ -0,0 +1,105 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Name:        recguard.tex
+%% Purpose:     wxRecursionGuard documentation
+%% Author:      Vadim Zeitlin
+%% Modified by:
+%% Created:     14.08.03
+%% RCS-ID:      $Id$
+%% Copyright:   (c) Vadim Zeitlin
+%% License:     wxWindows license
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\section{\class{wxRecursionGuard}}\label{wxrecursionguard}
+
+wxRecursionGuard is a very simple class which can be used to prevent reentrancy
+problems in a function. It is not thread-safe and so should be used only in the
+single-threaded programs or in combination with some thread synchronization
+mechanisms.
+
+wxRecursionGuard is always used together with 
+\helpref{wxRecursionGuardFlag}{wxrecursionguardflag} like in this example:
+\begin{verbatim}
+    void Foo()
+    {
+        static wxRecursionGuardFlag s_flag;
+        wxRecursionGuard guard(s_flag);
+        if ( guard.IsInside() )
+        {
+            // don't allow reentrancy
+            return;
+        }
+
+        ...
+    }
+\end{verbatim}
+
+As you can see, wxRecursionGuard simply tests the flag value and sets it to
+true if it hadn't been already set. 
+\helpref{IsInside()}{wxrecursionguardisinside} allows to test the old flag
+value. The advantage of using this class compared to directly manipulating the
+flag is that the flag is always reset in the wxRecursionGuard destructor and so
+you don't risk to forget to do it even if the function returns in an unexpected
+way (for example because an exception has been thrown).
+
+\wxheading{Derived from}
+
+No base class
+
+\wxheading{Include files}
+
+<wx/recguard.h>
+
+
+\latexignore{\rtfignore{\wxheading{Members}}}
+
+\membersection{wxRecursionGuard::wxRecursionGuard}\label{wxrecursionguardctor}
+
+\func{}{wxRecursionGuard}{\param{wxRecursionGuardFlag\& }{flag}}
+
+A wxRecursionGuard object must always be initialized with a (static) 
+\helpref{wxRecursionGuardFlag}{wxrecursionguardflag}. The constructor saves the
+value of the flag to be able to return the correct value from 
+\helpref{IsInside}{wxrecursionguardisinside}.
+
+
+\membersection{wxRecursionGuard::\destruct{wxRecursionGuard}}\label{wxrecursionguarddtor}
+
+\func{}{\destruct{wxRecursionGuard}}{\void}
+
+The destructor resets the flag value so that the function can be entered again
+the next time.
+
+Note that it is not virtual and so this class is not meant to be derived from
+(besides, there is absolutely no reason to do it anyhow).
+
+
+\membersection{wxRecursionGuard::IsInside}\label{wxrecursionguardisinside}
+
+\constfunc{bool}{IsInside}{\void}
+
+Returns \true if we're already inside the code block ``protected'' by this
+wxRecursionGuard (i.e. between this line and the end of current scope). Usually
+the function using wxRecursionGuard takes some specific actions in such case
+(may be simply returning) to prevent reentrant calls to itself.
+
+If this method returns \false, it is safe to continue.
+
+
+
+\section{\class{wxRecursionGuardFlag}}\label{wxrecursionguardflag}
+
+This is a completely opaque class which exists only to be used with 
+\helpref{wxRecursionGuard}{wxrecursionguard}, please see the example in that
+class documentation.
+
+Please notice that wxRecursionGuardFlag object \emph{must} be declared 
+\texttt{static} or the recursion would never be detected.
+
+\wxheading{Derived from}
+
+No base class
+
+\wxheading{Include files}
+
+<wx/recguard.h>
+
diff --git a/include/wx/recguard.h b/include/wx/recguard.h
new file mode 100644
index 0000000000..ea4e4995db
--- /dev/null
+++ b/include/wx/recguard.h
@@ -0,0 +1,53 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        wx/recguard.h
+// Purpose:     declaration and implementation of wxRecursionGuard class
+// Author:      Vadim Zeitlin
+// Modified by:
+// Created:     14.08.2003
+// RCS-ID:      $Id$
+// Copyright:   (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
+// Licence:     wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_RECGUARD_H_
+#define _WX_RECGUARD_H_
+
+#include "wx/defs.h"
+
+// ----------------------------------------------------------------------------
+// wxRecursionGuardFlag is used with wxRecursionGuard
+// ----------------------------------------------------------------------------
+
+typedef int wxRecursionGuardFlag;
+
+// ----------------------------------------------------------------------------
+// wxRecursionGuard is the simplest way to protect a function from reentrancy
+// ----------------------------------------------------------------------------
+
+class WXDLLIMPEXP_BASE wxRecursionGuard
+{
+public:
+    wxRecursionGuard(wxRecursionGuardFlag& flag)
+        : m_flag(flag)
+    { 
+        m_isInside = flag++ != 0;
+    }
+
+    ~wxRecursionGuard()
+    {
+        wxASSERT_MSG( m_flag > 0, _T("unbalanced wxRecursionGuards!?") );
+
+        m_flag--;
+    }
+
+    bool IsInside() const { return m_isInside; }
+
+private:
+    wxRecursionGuardFlag& m_flag;
+
+    // true if the flag had been already set when we were created
+    bool m_isInside;
+};
+
+#endif // _WX_RECGUARD_H_
+
-- 
2.50.0

