%!TEX root = std.tex
\makeevenhead{cpppage}{Josuttis, Baker, O'Neal, Sutter, Williams: \tcode{stop_token} and \tcode{jthread}}{}{\textbf{P0660R10}}
\makeoddhead{cpppage}{Josuttis, Baker, O'Neal, Sutter, Williams: \tcode{stop_token} and \tcode{jthread}}{}{\textbf{P0660R10}}

{\small
\begin{tabular}{@{}ll}
Project:  	& ISO JTC1/SC22/WG21: Programming Language C++ \\
Doc No: 	& WG21 P0660R10 \\
Date: 		& 2019-07-19 \\
Reply to: 	& Nicolai Josuttis (nico@josuttis.de), \\
                &         Lewis Baker (lbaker@fb.com) \\
                &         Billy O'Neal (bion@microsoft.com) \\
                &         Herb Sutter (hsutter@microsoft.com), \\
                &         Anthony Williams (anthony@justsoftwaresolutions.co.uk) \\
Audience: 	& SG1, LEWG, LWG \\
Prev. Version:	& \url{www.wg21.link/P0660R9}, \url{www.wg21.link/P1287R0} \\
\end{tabular}
}

%******************************************************************
\section*{{\huge{}Stop Token and Joining Thread, Rev 10}}

\subsubsection*{New in R10}
\begin{itemize}
 \item \tcode{request_stop()} returns whether the stop state was changed.
 \item \tcode{stop_callback} has type member \tcode{callback_type}.
 \item \tcode{stop_callback} constructor supports copying/conversion of callback.
 \item \tcode{stop_callback} deduction guide now deduces to decayed type.
 \item Class \tcode{jthread} is now part of header \tcode{<thread>}.
 \item Copy missing definitions from class \tcode{std::thread} to class \tcode{std::jthread}.
 \item Extend cross references to \tcode{std::thread}.
 \item Several (other) fixes from LWG multiple reviews.
 \item Several editorial fixes.
\end{itemize}

\subsubsection*{New in R9}
\begin{itemize}
 \item Fixes as requested by LEWG in Kona 2/2019.
        \begin{itemize}
         \item clarify constness of get \tcode{stop_stop_source()} and \tcode{get_stop_token()}
        \end{itemize}
 \item Fixes as requested from wording review by SG1 in Kona 2/2019.
        \begin{itemize}
         \item clarify concurrency issues
        \end{itemize}
 \item Fixes of small errors and typos.
\end{itemize}

\subsubsection*{New in R8}
As requested at
\href{http://wiki.edg.com/bin/view/Wg21sandiego2018/P0660}{the LEWG meeting in San Diego 2018}:
\begin{itemize}
 \item Terminology (especially rename \tcode{interrupt_token} to \tcode{stop_token}).
 \item Add a deduction guide for \tcode{stop_callback}
 \item Add \tcode{std::nostopstate_t} to create stop tokens that don't share a stop state
 \item Make comparisons hidden friends
 \item Several clarifications in wording
\end{itemize}

\subsubsection*{New in R7}
\begin{itemize}
 \item Adopt \url{www.wg21.link/P1287} as discussed in
        \href{http://wiki.edg.com/bin/view/Wg21sandiego2018/P1287R0}{the SG1 meeting in San Diego 2018},
        which includes:
        \begin{itemize}
         \item Add callbacks for interrupt tokens.
         \item Split into \tcode{interrupt_token} and \tcode{interrupt_source}.
        \end{itemize}
\end{itemize}

\subsubsection*{New in R6}
\begin{itemize}
 \item User \tcode{condition_variable_any} instead of \tcode{consition_variable}
        to avoid all possible races, deadlocks, and unintended undefined behavior.
 \item Clarify future binary compatibility for interrupt handling
        (mention requirements for future callback support and allow \tcode{bad_alloc} exceptions on waits.
\end{itemize}

\subsubsection*{New in R5}
As requested at
\href{http://wiki.edg.com/bin/view/ExecSeattle2018/MinutesDay2}{the SG1 meeting in Seattle 2018}:
\begin{itemize}
 \item Removed exception class \tcode{std::interrupted} and the \tcode{throw_if_interrupted()} API.
 \item Removed all TLS extensions and extensions to \tcode{std::this_thread}.
 \item Added support to let \tcode{jhread} call a callable that
        either takes the interrupt token as additional first argument
        or doesn't get it (taking just all passed arguments).
\end{itemize}

\subsubsection*{New in R4}
\begin{itemize}
 \item Removed interruptible CV waiting members that don't take a predicate.
 \item Removed adding a new \tcode{cv_status} value \tcode{interrupted}.
 \item Added CV members for interruptible timed waits.
 \item Renamed CV members that wait interruptible.
 \item Several minor fixes (e.g. on \tcode{noexcept}) and full proposed wording.
\end{itemize}

%**************************
\subsection*{Purpose}

This is the proposed wording for a cooperatively interruptible joining thread.

For a full discussion fo the motivation, see
\url{www.wg21.link/p0660r0} and
\url{www.wg21.link/p0660r1}.

A default implementation exists at:
\url{http://github.com/josuttis/jthread}.
Note that the proposed functionality can be fully implemented 
on top of the existing C++ standard library without special OS support.

%**************************
\subsection*{Basis examples}

%****************
\subsubsection*{Basis \tcode{jthead} examples}

\begin{itemize}
 \item At the end of its lifetime a \tcode{jthread} automatically signals a request to stop the started thread
        (if still joinable) and joins:
\begin{codeblock}
void testJThreadWithToken() 
{
    std::jthread t([] (std::stop_token stoken) {
                     while (!stoken.stop_requested()) {
                       //...
                     }
                   });
    //...
} // jthread destructor signals requests to stop and therefore ends the started thread and joins
\end{codeblock}

The stop could also be explicitly requested with \tcode{t.request_stop()}.

 \item If the started thread doesn't take a stop token, 
        the destructor still has the benefit of calling \tcode{join()} (if still joinable):
\begin{codeblock}
void testJThreadJoining()
{
    std::jthread t([] {
                     //...
                   });
    //...
} // jthread destructor calls join()
\end{codeblock}
        This is a significant improvement over \tcode{std::thread} where you had to program the following
        to get the same behavior (which is common in many scenarios):
\begin{codeblock}
void compareWithStdThreadJoining()
{
    std::thread t([] {
                    //...
                  });
    try {
      //...
    }
    catch (...) {
      j.join();
      throw;  // rethrow
    }
    t.join();
}
\end{codeblock}

 \item An extended CV API enables to interrupt CV waits using the passed stop token
        (i.e. interrupting the CV wait without polling):
\begin{codeblock}
void testInterruptibleCVWait() 
{
  bool ready = false;
  std::mutex readyMutex;
  std::condition_variable_any readyCV;
  std::jthread t([&ready, &readyMutex, &readyCV] (std::stop_token st) {
                    while (...) {
                      ...
                      {
                        std::unique_lock lg{readyMutex};
                        readyCV.wait_until(lg,
                                           [&ready] {
                                              return ready;
                                           },
                                           st);  // also ends wait on stop request for \tcode{st}
                      }
                      ...
                    }
                  });
  ...
} // jthread destructor signals stop request and therefore unblocks the CV wait and ends the started thread
\end{codeblock}
\end{itemize}

%****************
\subsubsection*{Basis i\tcode{stop_source}/\tcode{stop_token} examples}

\begin{codeblock}
// create stop_source and stop_token:
std::stop_source ssrc;
std::stop_token stok{ssrc.get_token()};

// register callback
bool cb1called{false};
auto cb1 = [&]{ cb1called = true; };
std::stop_callback scb1{stok, cb1};  // stop_callback copies cb1
assert(!cb1called);

// request stop
ssrc.request_stop();                 // calls all currently registered callbacks
assert(cb1called);

// register another callback
bool cb2called{false};
std::stop_callback scb2{stok, 
                        [&]{ cb2called = true; }
                       };            // immediately calls callback (moved into scb2)
assert(cb2called);
\end{codeblock}

%**************************
\subsection*{Feature Test Macro}

{\color{insertcolor}
Update [tab:support.ft] with
\begin{codeblock}
	__cpp_lib_jthread
\end{codeblock}
and the corresponding value
for the headers \tcode{<stop_token>} and \tcode{<thread>}.
}%\color{insertcolor}


\clearpage

%**************************

\subsection*{Design Discussion}

\subsubsection*{Problems with "interrupt"}

Earlier versions of this paper used the names \tcode{interrupt_token},
\tcode{interrupt_source} and \tcode{interrupt_callback} to refer to the
abstraction used to signal interrupt.

However, the term "interrupt" already has common usage in industry and
typically refers to something which can be interrupted and then return
back to the non-interrupted state.

For example, hardware interrupts are raised when some event happens and then
once the interrupt is handled the system returns back to the non-interrupted
state, allowing the interrupt to be raised again.

The boost::thread library also uses the term "interrupt" to refer to an operation
that can be raised many times and when the interrupt is handled the state is
reset back to non-interrupted.

This is different from the semantics of the abstraction proposed in this paper 
which has the semantics that once it has been signalled it never returns to
the non-signalled state. Thus the term "interrupt" seems inappropriate and is
likely to lead to confusion.

\subsubsection*{Alternative names}

There was some discussion in at LEWG at San Diego about alternative names
for \tcode{interrupt_token} and there were two candidates:
\tcode{cancellation_token} and \tcode{stop_token}.

The term \tcode{cancellation_token} has precedent in other C++ libraries.
For example, Microsoft's PPL uses the names `cancellation_token`, `cancellation_token_source`
and `cancellation_registration`.

The use of the "cancel" term also has precedent in the Networking TS which defines methods
such as \tcode{basic_waitable_timer::cancel()} and \tcode{basic_socket::cancel()} and makes
use of \tcode{std::errc::operation_canceled} as an error code in response to a request to
cancel the operation.

However, some concerns were raised about the potential for confusion if a \tcode{std::jthread::cancel()}
method were added as some may confuse this as somehow being related to the semantics of
\tcode{pthread_cancel()} which is able to cancel a thread at an arbitrary point rather than
cooperatively at well-defined cancellation points.

A straw poll was taken in LEWG at San Diego and the group favoured \tcode{stop_token}.

A suggestion was also made to introduce the use of the term "request" to more clearly
communicate the asynchronous and cooperative nature of the abstraction. This suggestion
has been adopted.

As a result the proposed names for the types and methods are now as follows:
\begin{codeblock}
class stop_token {
 public:
  ...
  [[nodiscard]] bool stop_requested() const noexcept;
  [[nodiscard]] bool stop_possible() const noexcept;
};

class stop_source {
 public:
  ...
  [[nodiscard]] bool stop_requested() const noexcept;
  [[nodiscard]] bool stop_possible() const noexcept;
  bool request_stop() noexcept;
};

template<Invocable Callback>
class stop_callback {
 public:
  ...
};
\end{codeblock}

\subsubsection*{Callback Registration/Deregistration}

An important capability for asynchronous use-cases for \tcode{stop_token} is the ability to attach
a callback to the \tcode{stop_token} that will be called if a request to stop is made. The motivations
for this are discussed in more detail in P1287R0.

Registration of a callback is performed by constructing a \tcode{stop_callback} object,
passing the constructor both a \tcode{stop_token} and a \tcode{Invocable} object that
is invoked if/when a call to \tcode{request_stop()} is made.

For example:
\begin{codeblock}
void cancellable_operation(std::stop_token stoken = {})
{
  auto handle = begin_operation();
  std::stop_callback cb{ stoken, [&] { cancel_operation(handle); }};
  ...
  auto result = end_operation(handle);
}
\end{codeblock}

When a \tcode{stop_callback} object is constructed, if the \tcode{stop_token} has
already received a request to stop then the callback is immediately invoked inside
the constructor. Otherwise, the callback is registered with the \tcode{stop_token}
and is later invoked if/when some thread calls \tcode{request_stop()}
on an associated \tcode{stop_source}.

The callback registration is guaranteed to be performed atomically. If there is a
concurrent call to \tcode{request_stop()} from another thread then either the
current thread will see the request to stop and immediately invoke the callback
on the current thread or the other thread will see the callback registration and
will invoke the callback before returning from \tcode{request_stop()}.

When the \tcode{stop_callback} object is destructed the callback is deregistered
from the list of callbacks associated with the \tcode{stop_token}'s shared state
the callback is guaranteed not to be called after the \tcode{stop_callback}
destructor returns.

Note that there is a potential race here between the callback being deregistered
and a call to \tcode{request_stop()} being made on another thread which could
invoke the callback. If the callback has not yet started executing on the other
thread then the callback is deregistered and is never called. Otherwise, if the
callback has already started executing on another thread then the call to
\tcode{\~stop_callback()} will block the current thread until the callback returns.

If the call to the \tcode{stop_callback} destructor is made from within the the
invocation of the callback on the same thread then the destructor does not block
waiting for the callback to return as this would cause a deadlock. Instead,
the destructor returns immediately without waiting for the callback to return.

\subsubsection*{Other Hints}

It is intentional that class \tcode{std::jthread} supports the full API of \tcode{std::thread}
(i.e., by supporting to start the thread without taking a stop token as first parameter)
to be able to replace any usage of \tcode{std::thread} by \tcode{std::jthread}
without further code changes.

The terminology was carefully selected with the following reasons
\begin{itemize}
 \item With a stop token we neither "interrupt" nor "cancel" something.
        We request a stop that cooperatively has to get handled.
 \item \tcode{stop_possible()} helps to avoid adding new callbacks
        or checking for stop states.
        The name was selected to have a common and pretty self-explanatory name
        that is shared by both \tcode{stop_source}s and \tcode{stop_token}s.
\end{itemize}

\subsubsection*{Initialization of \tcode{stop_callback}s}

Class \tcode{stop_callback} was carefully designed to be able to accept any callback,
whether passed as lvalue or rvalue and whether an implicit conversion
to a specified callback type is requested.

The deduction guide for \tcode{stop_callback}s deduces the callback argument type
(\tcode{callback_type})
such that the constructor performs a decayed copy of the callback argument.
Because the constructors are function templates,
type conversions are possible.

Given:
\begin{codeblock}
struct ImplicitArg {
};
struct ExplicitArg {
};
struct MyCallback {
  MyCallback(ImplicitArg x);
  explicit MyCallback(ExplicitArg x);
  void operator()() const;
};
\end{codeblock}

we have the following behavior:

\begin{LongTable}{\tcode{stop_callback} initializations}{}{x{.51\hsize}x{.45\hsize}}
\\ \topline
\lhdr{Example} &   \rhdr{Behavior} \\ \capsep
\endfirsthead
\continuedcaption\\
\topline
\lhdr{Example} &   \rhdr{Behavior} \\ \capsep
\endhead

 \tcode{auto stop = [] \{ ... \}; } \br
 \tcode{stop_callback  cb\{token, stop\}; }
  &
        Constructs copy of \tcode{stop} lambda in \tcode{cb}.
        \\ \rowsep

 \tcode{auto stop = [] \{ ... \}; } \br
 \tcode{stop_callback  cb\{token, std::move(stop)\}; }
  &
        Moves \tcode{stop} into \tcode{cb}.
	\\ \rowsep

 \tcode{auto stop = [] \{ ... \}; } \br
 \tcode{stop_callback cb\{token, std::ref(stop)\}; }
  &
        Captures lvalue reference to stop in \tcode{cb}.
        Deduces \tcode{callback_type} as \tcode{std::reference_wrapper<decltype(stop)>}.
	
        %???: With JonathanÂs deduction guide suggestion this would deduce
        %Callback arg to lambda\tcode{\&}.
        % NO
        \\ \rowsep

 \tcode{stop_callback cb\{token, [] \{ ... \}\}; }
  &
        Move constructs temporary lambda into cb.
	\\ \rowsep

 \tcode{stop_callback<function<void()>> cb\{ } \br
 \hspace*{1em}\tcode{token, [] \{ ... \} } \br
 \tcode{\}; }
  &
        %Constructs a temporary function<void()> from lambda and moves this temporary into cb.
        Directly constructs function member of \tcode{cb} from lambda.
        No temporary/move operation.
        \\ \rowsep

 \tcode{function<void()> f = [] \{ ... \};     } \br
 \tcode{stop_callback cb\{token, f\}; } 
  &
        %Ill-formed. Cannot bind function<void()>&& parameter to lvalue argument, f.
        Copies \tcode{f} into \tcode{cb}.
        Deduces \tcode{callback_type} as \tcode{function<void()>}.
        \\ \rowsep

 \tcode{function<void()> f = [] \{ ... \};     } \br
 \tcode{stop_callback<function<void()>> cb\{token, f\}; } 
  &
        %Ill-formed. Cannot bind function<void()>&& parameter to lvalue argument, f.
        Copies \tcode{f} into \tcode{cb}.
        \\ \rowsep

 \tcode{auto cb = [token] \{     } \br
 \hspace*{1em}\tcode{function<void()> f;     } \br
 \hspace*{1em}\tcode{if (cond) \{     } \br
 \hspace*{2em}\tcode{  f = [] \{ ... \};     } \br
 \hspace*{1em}\tcode{\} else \{     } \br
 \hspace*{2em}\tcode{  f = [] \{ ... \};     } \br
 \hspace*{1em}\tcode{\}     } \br
 \hspace*{1em}\tcode{return stop_callback\{token, f\};     } \br
 \tcode{\}();     }
  &	
        Initializes \tcode{cb} with a copy of \tcode{f}.
        Deduces \tcode{callback_type} as \tcode{function<void()>}.
        \\ \rowsep

 \tcode{ImplicitArg i; } \br
 \tcode{stop_callback<MyCallback> cb\{token, i\}; }
  &
        %Implicitly converts i to temporary myCallback and moves this into cb.
        Directly constructs \tcode{myCallback} member of \tcode{cb} from \tcode{i} by calling implicit constructor.
        \\ \rowsep

 \tcode{ExplicitArg e; } \br
 \tcode{stop_callback<MyCallback> cb\{token, e\}; }
  &
        Directly constructs myCallback member of \tcode{cb} from \tcode{e} by calling explicit constructor.
        \\ \rowsep

 \tcode{stop_callback<MyCallback> cb =     } \br
 \hspace*{1em}\tcode{  [\&]() -> stop_callback<MyCallback> \{     } \br
 \hspace*{2em}\tcode{    ExplicitArg e;     } \br
 \hspace*{2em}\tcode{    return \{token, e\};     } \br
 \hspace*{1em}\tcode{  \}();     }
  &
        %Currently ill-formed.
        %All stop_callback constructors are unconditionally explicit.
        Ill-formed. Implicit construction not supported.

        %Would still be ill-formed even if we marked constructor as explicit(!ConvertibleTo<Arg, Callback>)
        \\ \rowsep

 \tcode{stop_callback<MyCallback> cb =     } \br
 \hspace*{1em}\tcode{  [\&]() -> stop_callback<MyCallback> \{     } \br
 \hspace*{2em}\tcode{    ImplicitArg i;     } \br
 \hspace*{2em}\tcode{    return \{token, i\};     } \br
 \hspace*{1em}\tcode{  \}();     }
  &
        %Currently ill-formed.
        %All stop_callback constructors are unconditionally explicit.
        Ill-formed. Implicit construction not supported.

        %Would become valid if we marked constructor as explicit(!ConvertibleTo<Arg, Callback>)
        \\ \rowsep
\end{LongTable}
 

%**************************
\subsection*{Acknowledgements}

Thanks to all who incredibly helped me to prepare this paper,
such as all people in the C++ concurrency and library working groups.
Especially, we want to thank:
 Billy Baker, Hans Boehm, Olivier Giroux, Pablo Halpern, Howard Hinnant, Alisdair Meredith, Gor Nishanov,
 Daniel Sunderland, Tony Van Eerd, Ville Voutilainen, Jonathan Wakely.

%******************************************************************
\section*{Proposed Wording}
All against N4762.

{\color{blue}
[{\itshape{}Editorial note:} This proposal uses the LaTeX macros of the draft standard.
        To adopt it please ask for the LaTeX source code of the proposed wording. ]
}

%\clearpage

