\hypertarget{class_qore_1_1_thread_1_1_gate}{}\doxysection{Qore\+::Thread\+::Gate Class Reference}
\label{class_qore_1_1_thread_1_1_gate}\index{Qore::Thread::Gate@{Qore::Thread::Gate}}


The \mbox{\hyperlink{class_qore_1_1_thread_1_1_gate}{Gate}} class implements a reentrant thread lock.  




{\ttfamily \#include $<$QC\+\_\+\+Gate.\+dox.\+h$>$}

\doxysubsection*{Public Member Functions}
\begin{DoxyCompactItemize}
\item 
\mbox{\hyperlink{class_qore_1_1_thread_1_1_gate_aaf72409de51d42a1057b48f67c3e9598}{constructor}} ()
\begin{DoxyCompactList}\small\item\em Creates a new \mbox{\hyperlink{class_qore_1_1_thread_1_1_gate}{Gate}} object. \end{DoxyCompactList}\item 
\mbox{\hyperlink{class_qore_1_1_thread_1_1_gate_ad7cebf015ecbb354d4c7460fe8dd948d}{copy}} ()
\begin{DoxyCompactList}\small\item\em Creates a new \mbox{\hyperlink{class_qore_1_1_thread_1_1_gate}{Gate}} object, not based on the original. \end{DoxyCompactList}\item 
\mbox{\hyperlink{class_qore_1_1_thread_1_1_gate_af45282fa74979eebc635dea5c708b398}{destructor}} ()
\begin{DoxyCompactList}\small\item\em Destroys the \mbox{\hyperlink{class_qore_1_1_thread_1_1_gate}{Gate}} object. \end{DoxyCompactList}\item 
\mbox{\hyperlink{group__type__conversion__functions_ga2de8717e92c5f97ccc6511f6062d6502}{int}} \mbox{\hyperlink{class_qore_1_1_thread_1_1_gate_afedd4acee953a17bff84ad91ad226fed}{enter}} (timeout timeout\+\_\+ms)
\begin{DoxyCompactList}\small\item\em Acquires the lock if it is unlocked or locked by the same thread, otherwise blocks until the lock counter reaches zero. \end{DoxyCompactList}\item 
nothing \mbox{\hyperlink{class_qore_1_1_thread_1_1_gate_a84af8317ea5b6fb634ad03342d1738ee}{enter}} ()
\begin{DoxyCompactList}\small\item\em Increments the lock count if the lock is unlocked or already owned by the same thread, otherwise blocks until the lock counter reaches zero. \end{DoxyCompactList}\item 
\mbox{\hyperlink{group__type__conversion__functions_ga2de8717e92c5f97ccc6511f6062d6502}{int}} \mbox{\hyperlink{class_qore_1_1_thread_1_1_gate_aec16df9e3c8a030c12e2c3791263d3e7}{exit}} ()
\begin{DoxyCompactList}\small\item\em Decrements the lock counter; if it reaches zero then the lock is unlocked and any blocked threads are awoken; in this case 0 is returned; in all other cases, non-\/zero is returned. \end{DoxyCompactList}\item 
\mbox{\hyperlink{group__type__conversion__functions_ga2de8717e92c5f97ccc6511f6062d6502}{int}} \mbox{\hyperlink{class_qore_1_1_thread_1_1_gate_a57f6a41d648c62f41b85b2b1ffd6af64}{num\+Inside}} ()
\begin{DoxyCompactList}\small\item\em Returns the current lock count. \end{DoxyCompactList}\item 
\mbox{\hyperlink{group__type__conversion__functions_ga2de8717e92c5f97ccc6511f6062d6502}{int}} \mbox{\hyperlink{class_qore_1_1_thread_1_1_gate_a0ecf6d20f8147a687883f51182d5c108}{num\+Waiting}} ()
\begin{DoxyCompactList}\small\item\em Returns the number of threads blocked on the \mbox{\hyperlink{class_qore_1_1_thread_1_1_gate}{Gate}}. \end{DoxyCompactList}\item 
\mbox{\hyperlink{group__type__conversion__functions_ga2de8717e92c5f97ccc6511f6062d6502}{int}} \mbox{\hyperlink{class_qore_1_1_thread_1_1_gate_ae8358c58fb1eff5cddbc34cbec5e6d8d}{try\+Enter}} ()
\begin{DoxyCompactList}\small\item\em Acquires the lock if it is unlocked or locked by the same thread, in which case this method returns 0, otherwise returns immediately with -\/1. \end{DoxyCompactList}\end{DoxyCompactItemize}


\doxysubsection{Detailed Description}
The \mbox{\hyperlink{class_qore_1_1_thread_1_1_gate}{Gate}} class implements a reentrant thread lock. 

\begin{DoxyParagraph}{Restrictions\+:}
\mbox{\hyperlink{group__parse__options_gade963e1fbbd1f5b2c777df7221512a1b}{Qore\+::\+PO\+\_\+\+NO\+\_\+\+THREAD\+\_\+\+CLASSES}}
\end{DoxyParagraph}
\begin{DoxyParagraph}{Overview}
Once a thread grabs the lock, it can call the \mbox{\hyperlink{class_qore_1_1_thread_1_1_gate_a84af8317ea5b6fb634ad03342d1738ee}{Gate\+::enter()}} method again without blocking. Other threads that try to enter the lock will block until the thread holding the lock calls \mbox{\hyperlink{class_qore_1_1_thread_1_1_gate_aec16df9e3c8a030c12e2c3791263d3e7}{Gate\+::exit()}} an equal number of times to \mbox{\hyperlink{class_qore_1_1_thread_1_1_gate_a84af8317ea5b6fb634ad03342d1738ee}{Gate\+::enter()}} calls.~\newline
~\newline
 See the \mbox{\hyperlink{class_qore_1_1_thread_1_1_auto_gate}{Auto\+Gate}} class for a class that assists in exception-\/safe \mbox{\hyperlink{class_qore_1_1_thread_1_1_gate}{Gate}} locking.~\newline
~\newline
 Additionally, the \mbox{\hyperlink{statements_on_exit}{on\+\_\+exit statement}} can provide exception-\/safe \mbox{\hyperlink{class_qore_1_1_thread_1_1_gate}{Gate}} handling at the lexical block level as in the following example\+: 
\begin{DoxyCode}{0}
\DoxyCodeLine{\{}
\DoxyCodeLine{    g.enter();}
\DoxyCodeLine{    on\_exit}
\DoxyCodeLine{        g.exit();}
\DoxyCodeLine{    \textcolor{comment}{\# ... when this block exits the gate lock counter will be decremented,}}
\DoxyCodeLine{    \textcolor{comment}{\#     even in the case of return statements or exceptions}}
\DoxyCodeLine{\}}

\end{DoxyCode}

\end{DoxyParagraph}
\begin{DoxyParagraph}{Thread Resource Handling}
The \mbox{\hyperlink{class_qore_1_1_thread_1_1_gate}{Gate}} class manages the lock as a \mbox{\hyperlink{threading_thread_resources}{thread resource}}; if the lock is not released when the thread exits (or when \mbox{\hyperlink{group__threading__functions_ga421dca39ccb55b191d5d09fd98c2075a}{Qore\+::throw\+\_\+thread\+\_\+resource\+\_\+exceptions()}} or \mbox{\hyperlink{group__threading__functions_ga4e62409b8a1b414276d033267e7299e4}{Qore\+::throw\+\_\+thread\+\_\+resource\+\_\+exceptions\+\_\+to\+\_\+mark()}} is called), the lock is released automatically and a {\ttfamily LOCK-\/\+ERROR} exception is thrown describing the situation.~\newline
~\newline
 Being an builtin class, the \mbox{\hyperlink{class_qore_1_1_thread_1_1_gate}{Gate}} class does not inherit \mbox{\hyperlink{class_qore_1_1_thread_1_1_abstract_thread_resource}{Abstract\+Thread\+Resource}} explicitly as a part of the exported API, and the internal \mbox{\hyperlink{class_qore_1_1_thread_1_1_abstract_thread_resource_a0431f7384991eaf6900ee3a952b57f87}{Abstract\+Thread\+Resource\+::cleanup()}} method cannot be overridden or suppressed.
\end{DoxyParagraph}
\begin{DoxyNote}{Note}
This class is not available with the \mbox{\hyperlink{group__parse__options_gade963e1fbbd1f5b2c777df7221512a1b}{PO\+\_\+\+NO\+\_\+\+THREAD\+\_\+\+CLASSES}} parse option. 
\end{DoxyNote}


\doxysubsection{Member Function Documentation}
\mbox{\Hypertarget{class_qore_1_1_thread_1_1_gate_aaf72409de51d42a1057b48f67c3e9598}\label{class_qore_1_1_thread_1_1_gate_aaf72409de51d42a1057b48f67c3e9598}} 
\index{Qore::Thread::Gate@{Qore::Thread::Gate}!constructor@{constructor}}
\index{constructor@{constructor}!Qore::Thread::Gate@{Qore::Thread::Gate}}
\doxysubsubsection{\texorpdfstring{constructor()}{constructor()}}
{\footnotesize\ttfamily Qore\+::\+Thread\+::\+Gate\+::constructor (\begin{DoxyParamCaption}{ }\end{DoxyParamCaption})}



Creates a new \mbox{\hyperlink{class_qore_1_1_thread_1_1_gate}{Gate}} object. 

\begin{DoxyParagraph}{Example\+:}

\begin{DoxyCode}{0}
\DoxyCodeLine{Gate gate();}

\end{DoxyCode}
 
\end{DoxyParagraph}
\mbox{\Hypertarget{class_qore_1_1_thread_1_1_gate_ad7cebf015ecbb354d4c7460fe8dd948d}\label{class_qore_1_1_thread_1_1_gate_ad7cebf015ecbb354d4c7460fe8dd948d}} 
\index{Qore::Thread::Gate@{Qore::Thread::Gate}!copy@{copy}}
\index{copy@{copy}!Qore::Thread::Gate@{Qore::Thread::Gate}}
\doxysubsubsection{\texorpdfstring{copy()}{copy()}}
{\footnotesize\ttfamily Qore\+::\+Thread\+::\+Gate\+::copy (\begin{DoxyParamCaption}{ }\end{DoxyParamCaption})}



Creates a new \mbox{\hyperlink{class_qore_1_1_thread_1_1_gate}{Gate}} object, not based on the original. 

\begin{DoxyParagraph}{Example\+:}

\begin{DoxyCode}{0}
\DoxyCodeLine{Gate new\_gate = gate.copy();}

\end{DoxyCode}
 
\end{DoxyParagraph}
\mbox{\Hypertarget{class_qore_1_1_thread_1_1_gate_af45282fa74979eebc635dea5c708b398}\label{class_qore_1_1_thread_1_1_gate_af45282fa74979eebc635dea5c708b398}} 
\index{Qore::Thread::Gate@{Qore::Thread::Gate}!destructor@{destructor}}
\index{destructor@{destructor}!Qore::Thread::Gate@{Qore::Thread::Gate}}
\doxysubsubsection{\texorpdfstring{destructor()}{destructor()}}
{\footnotesize\ttfamily Qore\+::\+Thread\+::\+Gate\+::destructor (\begin{DoxyParamCaption}{ }\end{DoxyParamCaption})}



Destroys the \mbox{\hyperlink{class_qore_1_1_thread_1_1_gate}{Gate}} object. 

Note that it is a programming error to delete this object while other threads are blocked on it; in this case an exception is thrown in the deleting thread, and in each thread blocked on this object when it is deleted.

\begin{DoxyParagraph}{Example\+:}

\begin{DoxyCode}{0}
\DoxyCodeLine{delete gate;}

\end{DoxyCode}

\end{DoxyParagraph}

\begin{DoxyExceptions}{Exceptions}
{\em LOCK-\/\+ERROR} & Object deleted while other threads blocked on it \\
\hline
\end{DoxyExceptions}
\mbox{\Hypertarget{class_qore_1_1_thread_1_1_gate_a84af8317ea5b6fb634ad03342d1738ee}\label{class_qore_1_1_thread_1_1_gate_a84af8317ea5b6fb634ad03342d1738ee}} 
\index{Qore::Thread::Gate@{Qore::Thread::Gate}!enter@{enter}}
\index{enter@{enter}!Qore::Thread::Gate@{Qore::Thread::Gate}}
\doxysubsubsection{\texorpdfstring{enter()}{enter()}\hspace{0.1cm}{\footnotesize\ttfamily [1/2]}}
{\footnotesize\ttfamily nothing Qore\+::\+Thread\+::\+Gate\+::enter (\begin{DoxyParamCaption}{ }\end{DoxyParamCaption})}



Increments the lock count if the lock is unlocked or already owned by the same thread, otherwise blocks until the lock counter reaches zero. 

\begin{DoxyParagraph}{Example\+:}

\begin{DoxyCode}{0}
\DoxyCodeLine{gate.enter();}

\end{DoxyCode}

\end{DoxyParagraph}

\begin{DoxyExceptions}{Exceptions}
{\em LOCK-\/\+ERROR} & object deleted in another thread, etc \\
\hline
{\em THREAD-\/\+DEADLOCK} & a deadlock was detected while trying to acquire the lock \\
\hline
\end{DoxyExceptions}
\mbox{\Hypertarget{class_qore_1_1_thread_1_1_gate_afedd4acee953a17bff84ad91ad226fed}\label{class_qore_1_1_thread_1_1_gate_afedd4acee953a17bff84ad91ad226fed}} 
\index{Qore::Thread::Gate@{Qore::Thread::Gate}!enter@{enter}}
\index{enter@{enter}!Qore::Thread::Gate@{Qore::Thread::Gate}}
\doxysubsubsection{\texorpdfstring{enter()}{enter()}\hspace{0.1cm}{\footnotesize\ttfamily [2/2]}}
{\footnotesize\ttfamily \mbox{\hyperlink{group__type__conversion__functions_ga2de8717e92c5f97ccc6511f6062d6502}{int}} Qore\+::\+Thread\+::\+Gate\+::enter (\begin{DoxyParamCaption}\item[{timeout}]{timeout\+\_\+ms }\end{DoxyParamCaption})}



Acquires the lock if it is unlocked or locked by the same thread, otherwise blocks until the lock counter reaches zero. 


\begin{DoxyParams}{Parameters}
{\em timeout\+\_\+ms} & a \mbox{\hyperlink{data_type_declarations_timeout_type}{timeout}} value to wait to acquire the lock (enter the \mbox{\hyperlink{class_qore_1_1_thread_1_1_gate}{Gate}}); integers are interpreted as milliseconds; \mbox{\hyperlink{basic_data_types_relative_dates}{relative date/time values}} are interpreted literally (with a resolution of milliseconds)\\
\hline
\end{DoxyParams}
\begin{DoxyReturn}{Returns}
0 if no timeout occurred, non-\/zero if a timeout occurred.
\end{DoxyReturn}
\begin{DoxyParagraph}{Example\+:}

\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keywordflow}{if} (gate.enter(1500ms))}
\DoxyCodeLine{    throw \textcolor{stringliteral}{"{}TIMEOUT-\/ERROR"{}}, \textcolor{stringliteral}{"{}gate acquisition timed out after 1.5s"{}};}

\end{DoxyCode}

\end{DoxyParagraph}

\begin{DoxyExceptions}{Exceptions}
{\em LOCK-\/\+ERROR} & object deleted in another thread, etc \\
\hline
{\em THREAD-\/\+DEADLOCK} & a deadlock was detected while trying to acquire the lock \\
\hline
\end{DoxyExceptions}
\mbox{\Hypertarget{class_qore_1_1_thread_1_1_gate_aec16df9e3c8a030c12e2c3791263d3e7}\label{class_qore_1_1_thread_1_1_gate_aec16df9e3c8a030c12e2c3791263d3e7}} 
\index{Qore::Thread::Gate@{Qore::Thread::Gate}!exit@{exit}}
\index{exit@{exit}!Qore::Thread::Gate@{Qore::Thread::Gate}}
\doxysubsubsection{\texorpdfstring{exit()}{exit()}}
{\footnotesize\ttfamily \mbox{\hyperlink{group__type__conversion__functions_ga2de8717e92c5f97ccc6511f6062d6502}{int}} Qore\+::\+Thread\+::\+Gate\+::exit (\begin{DoxyParamCaption}{ }\end{DoxyParamCaption})}



Decrements the lock counter; if it reaches zero then the lock is unlocked and any blocked threads are awoken; in this case 0 is returned; in all other cases, non-\/zero is returned. 

\begin{DoxyReturn}{Returns}
returns 0 if the \mbox{\hyperlink{class_qore_1_1_thread_1_1_gate}{Gate}} was unlocked; otherwise returns non-\/zero
\end{DoxyReturn}
\begin{DoxyParagraph}{Example\+:}

\begin{DoxyCode}{0}
\DoxyCodeLine{gate.exit();}

\end{DoxyCode}

\end{DoxyParagraph}

\begin{DoxyExceptions}{Exceptions}
{\em LOCK-\/\+ERROR} & lock not owned by the current thread, object deleted in another thread, etc \\
\hline
\end{DoxyExceptions}
\mbox{\Hypertarget{class_qore_1_1_thread_1_1_gate_a57f6a41d648c62f41b85b2b1ffd6af64}\label{class_qore_1_1_thread_1_1_gate_a57f6a41d648c62f41b85b2b1ffd6af64}} 
\index{Qore::Thread::Gate@{Qore::Thread::Gate}!numInside@{numInside}}
\index{numInside@{numInside}!Qore::Thread::Gate@{Qore::Thread::Gate}}
\doxysubsubsection{\texorpdfstring{numInside()}{numInside()}}
{\footnotesize\ttfamily \mbox{\hyperlink{group__type__conversion__functions_ga2de8717e92c5f97ccc6511f6062d6502}{int}} Qore\+::\+Thread\+::\+Gate\+::num\+Inside (\begin{DoxyParamCaption}{ }\end{DoxyParamCaption})}



Returns the current lock count. 

\begin{DoxyReturn}{Returns}
the current lock count
\end{DoxyReturn}
\begin{DoxyParagraph}{Code Flags\+:}
\mbox{\hyperlink{code_flags_CONSTANT}{CONSTANT}}
\end{DoxyParagraph}
\begin{DoxyParagraph}{Example\+:}

\begin{DoxyCode}{0}
\DoxyCodeLine{int c = gate.numInside();}

\end{DoxyCode}
 
\end{DoxyParagraph}
\mbox{\Hypertarget{class_qore_1_1_thread_1_1_gate_a0ecf6d20f8147a687883f51182d5c108}\label{class_qore_1_1_thread_1_1_gate_a0ecf6d20f8147a687883f51182d5c108}} 
\index{Qore::Thread::Gate@{Qore::Thread::Gate}!numWaiting@{numWaiting}}
\index{numWaiting@{numWaiting}!Qore::Thread::Gate@{Qore::Thread::Gate}}
\doxysubsubsection{\texorpdfstring{numWaiting()}{numWaiting()}}
{\footnotesize\ttfamily \mbox{\hyperlink{group__type__conversion__functions_ga2de8717e92c5f97ccc6511f6062d6502}{int}} Qore\+::\+Thread\+::\+Gate\+::num\+Waiting (\begin{DoxyParamCaption}{ }\end{DoxyParamCaption})}



Returns the number of threads blocked on the \mbox{\hyperlink{class_qore_1_1_thread_1_1_gate}{Gate}}. 

\begin{DoxyParagraph}{Code Flags\+:}
\mbox{\hyperlink{code_flags_CONSTANT}{CONSTANT}}
\end{DoxyParagraph}
\begin{DoxyParagraph}{Example\+:}

\begin{DoxyCode}{0}
\DoxyCodeLine{int c = gate.numWaiting();}

\end{DoxyCode}
 
\end{DoxyParagraph}
\mbox{\Hypertarget{class_qore_1_1_thread_1_1_gate_ae8358c58fb1eff5cddbc34cbec5e6d8d}\label{class_qore_1_1_thread_1_1_gate_ae8358c58fb1eff5cddbc34cbec5e6d8d}} 
\index{Qore::Thread::Gate@{Qore::Thread::Gate}!tryEnter@{tryEnter}}
\index{tryEnter@{tryEnter}!Qore::Thread::Gate@{Qore::Thread::Gate}}
\doxysubsubsection{\texorpdfstring{tryEnter()}{tryEnter()}}
{\footnotesize\ttfamily \mbox{\hyperlink{group__type__conversion__functions_ga2de8717e92c5f97ccc6511f6062d6502}{int}} Qore\+::\+Thread\+::\+Gate\+::try\+Enter (\begin{DoxyParamCaption}{ }\end{DoxyParamCaption})}



Acquires the lock if it is unlocked or locked by the same thread, in which case this method returns 0, otherwise returns immediately with -\/1. 

\begin{DoxyReturn}{Returns}
0 for success (acquired the lock) or -\/1 for failure (would block)
\end{DoxyReturn}
\begin{DoxyParagraph}{Example\+:}

\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{keywordflow}{if} (gate.tryEnter()) \{}
\DoxyCodeLine{    on\_exit gate.exit();}
\DoxyCodeLine{    printf(\textcolor{stringliteral}{"{}YIPEE!  We finally got the gate!\(\backslash\)n"{}});}
\DoxyCodeLine{\}}

\end{DoxyCode}

\end{DoxyParagraph}

\begin{DoxyExceptions}{Exceptions}
{\em LOCK-\/\+ERROR} & object deleted in another thread, etc \\
\hline
\end{DoxyExceptions}
