From 7b4d7f99a60c095ecd28a3e72d48241abe9f7fdb Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin 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} + + + + +\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} + + + 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 +// 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.45.2