You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
255 lines
8.2 KiB
255 lines
8.2 KiB
%
|
|
% threads.tex: description of threads interface for VideoLAN client
|
|
% (c)1999 VideoLAN
|
|
%
|
|
\section{A common thread interface}
|
|
|
|
This document describes how the different threads in the VideoLAN client are
|
|
organized, their API and functionnment.
|
|
|
|
%
|
|
% Thread properties
|
|
%
|
|
\subsection{Thread properties}
|
|
|
|
A thread is described by a \csymbol{X\_thread\_t} structure (i.e.
|
|
\csymbol{vout\_thread\_t}), which is used to reference the thread in calls to
|
|
its API. This structure includes beside following thread-specific data the
|
|
following fields:
|
|
|
|
\begin{csource}
|
|
typedef struct X_thread_s \{
|
|
pthread_t thread_id; /* thread id for pthreads */
|
|
boolean_t b_die; /* `die' flag */
|
|
boolean_t b_run; /* `run' flag */
|
|
boolean_t b_error; /* `error' flag */
|
|
boolean_t b_active; /* `active' flag */
|
|
|
|
... other fields ...
|
|
\} X_thread_t;
|
|
\end{csource}
|
|
|
|
%
|
|
% Meaning of common flags
|
|
%
|
|
\subsection{Meaning of common flags}
|
|
|
|
\begin{description}
|
|
\item[\csymbol{die}]:
|
|
The \csymbol{die} flag means that the thread received a destruction request
|
|
from another thread. It must terminate as soon as possible. This field is
|
|
written (set to 1) by other threads and read by the thread itself. It cannot
|
|
be reset to 0 once it has been set.
|
|
|
|
Note that when the \csymbol{die} flag is set, no other thread should feed the
|
|
dying one, and all shared structures should have been freed (i.e. the images
|
|
and video streams for the video output thread).
|
|
|
|
\item[\csymbol{run}]:
|
|
The \csymbol{run} flag tells the other threads that the concerned thread is
|
|
ready to receive data. It is set to 1 by the thread itself when the second
|
|
phase of the initialization has succeeded, and set to 0 again by the thread
|
|
once it exited.
|
|
|
|
\item[\csymbol{error}]:
|
|
The \csymbol{error} flag tells the other threads that a fatal error occured in
|
|
the concerned thread. It can be set by all threads, and is read by the thread
|
|
itself and the controlling thread.
|
|
|
|
When a thread is in \csymbol{error} state, it runs in a special loop,
|
|
accepting feed from other threads, but trashing eveything, waiting for a
|
|
\csymbol{die} signal.
|
|
|
|
Therefore, the controlling thread should check periodically if a thread has an
|
|
\csymbol{error} set and, if yes, set its \csymbol{die} flag after having
|
|
destroyed all depending threads.
|
|
|
|
This flag is optionnal, but recommanded if an error can be envisaged in a later
|
|
extension.
|
|
|
|
\item[\csymbol{active}]:
|
|
This flag's purpose is to avoid using useless resources. An in-\csymbol{active}
|
|
thread must accept input as if it was inactive, but can treat its input
|
|
differently.
|
|
In example: the video output thread will set itself as in-\csymbol{active}
|
|
when it is unmapped, and continue to sort and trash images, but will not
|
|
render or display them to avoid consumming useless CPU. When a video decoder
|
|
thread will detect that its related output thread is inactive, it will set
|
|
itself inactive and trash everything except I images.
|
|
|
|
The \csymbol{active} flag can be set and read by anyone. Precautions should be
|
|
taken to avoid too long wake-up times.
|
|
|
|
This flag is optionnal, but recommanded if its use can be envisaged in a later
|
|
extension.
|
|
\end{description}
|
|
|
|
%
|
|
% API
|
|
%
|
|
\subsection{API}
|
|
|
|
This API is only a recommandation.
|
|
|
|
% Creation
|
|
\subsubsection{Creation}
|
|
|
|
\begin{csource}
|
|
X_thread_t * X_CreateThread( X_cfg_t *p_cfg )
|
|
\end{csource}
|
|
|
|
This function will allocate thread descriptor, perform basic (and fast)
|
|
initialization steps, and create the thread itself using
|
|
\csymbol{pthread\_create}.
|
|
|
|
Once it has been called, all flags are set to 0. It will return the thread
|
|
descriptor or \csymbol{NULL} on failure.
|
|
|
|
% Termination
|
|
\subsubsection{Termination}
|
|
|
|
\begin{csource}
|
|
void X_TerminateThread( X_thread_t * p_X );
|
|
\end{csource}
|
|
|
|
This function will set the \csymbol{die} flag of the thread and and return
|
|
immediately.
|
|
|
|
% Destruction
|
|
\subsubsection{Destruction}
|
|
|
|
\begin{csource}
|
|
int X_DestroyThread( X_thread_t *p_X );
|
|
\end{csource}
|
|
|
|
This function will try to destroy the thread descriptor, if it is possible
|
|
(if the \csymbol{run} flag is not set). It will return 0 if it succeeded,
|
|
and non 0 if the thread was still active.
|
|
|
|
%
|
|
% Local functions names
|
|
%
|
|
\subsection{Local functions names}
|
|
|
|
The following functions names are recommanded to implement the different
|
|
parts of the thread creation and destruction:
|
|
|
|
\begin{csource}
|
|
int InitThread(); /* second phase of initialization */
|
|
int RunThread(); /* main loop */
|
|
int RunError(); /* error loop */
|
|
int DestroyThread(); /* thread destruction */
|
|
\end{csource}
|
|
|
|
\csymbol{X\_CreateThread()} will spawn a thread using \csymbol{RunThread()}
|
|
function, which will call \csymbol{InitThread()}, enter its main loop,
|
|
eventually call \csymbol{RunError()} and finally calls \csymbol{DestroyThread}
|
|
when \csymbol{die} is received.
|
|
|
|
%
|
|
% Order of operations
|
|
%
|
|
\subsection{Order of operations}
|
|
|
|
% Creation
|
|
\subsubsection{Creation}
|
|
|
|
\begin{tabular}{l|l}
|
|
Controlling thread & Thread \\
|
|
\hline
|
|
|
|
\csymbol{p\_X = X\_CreateThread( p\_cfg )}: & \\
|
|
descriptor allocation and initialization & \\
|
|
all flags are set to 0 & \\
|
|
base structures initialization & \\
|
|
If \csymbol{p\_X == NULL}: error & \\
|
|
\csymbol{X\_DestroyThread( p\_X )}: & \\
|
|
destruction of the descriptor & \\
|
|
end...
|
|
Else, continuation.... & \csymbol{pthread\_create()} \\
|
|
& Second step of initialization \\
|
|
& On error: \\
|
|
& \csymbol{b\_error = 1} \\
|
|
& destruction of structures \\
|
|
& Else: \\
|
|
& \csymbol{b\_run = 1} \\
|
|
& beginning of main loop \\
|
|
|
|
\hline
|
|
|
|
Wait for \csymbol{b\_run} or \csymbol{b\_error}...& main loop... \\
|
|
If \csymbol{b\_error}: & \\
|
|
\csymbol{X\_DestroyThread( p\_X )} & \\
|
|
end... & \\
|
|
Else (\csymbol{b\_run == 1}): & \\
|
|
the thread is ready and can be feeded... & \\
|
|
|
|
\hline
|
|
\end{tabular}
|
|
|
|
Notes:
|
|
\begin{enumerate}
|
|
\item The configuration structure can have been destroyed just after
|
|
\csymbol{X\_CreateThread()}. Therefore, it should not be used during second
|
|
initialization step.
|
|
|
|
\item When an error occurs during second initialization step, the allocated structures
|
|
are automatically destroyed (except the thread descriptor). Therefore, a call to
|
|
\csymbol{X\_TerminateThread} is not required.
|
|
\end{enumerate}
|
|
|
|
% Main loop
|
|
\subsubsection{Main loop}
|
|
|
|
\begin{tabular}{l|l}
|
|
Controlling thread & Thread \\
|
|
\hline
|
|
|
|
Periodically check for \csymbol{b\_error} & Periodically check for \\
|
|
If set, then: & \csymbol{b\_error} and \csymbol{b\_die}\\
|
|
terminate all dependant threads & \\
|
|
destroy all dependant threads & \\
|
|
terminate and destroy thread & \\
|
|
|
|
\hline
|
|
\end{tabular}
|
|
|
|
% Destruction
|
|
\subsubsection{Destruction}
|
|
|
|
\begin{tabular}{l|l}
|
|
Controlling thread & Thread \\
|
|
\hline
|
|
|
|
\csymbol{X\_TerminateThread( p\_X )}: & \\
|
|
set \csymbol{b\_die} & \\
|
|
all flags are set to 0 & If \csymbol{DEBUG}, check if \\
|
|
& all shared structures are ok. \\
|
|
& Destroy and close everything, but \\
|
|
& keep descriptor. \\
|
|
& Set \csymbol{b\_run} to 0. \\
|
|
& Exit thread. \\
|
|
|
|
\hline
|
|
|
|
Loop until \csymbol{X\_DestroyThread} is 0: & \\
|
|
check if \csymbol{b\_run == 0} & \\
|
|
if yes: & \\
|
|
destroy descriptor & \\
|
|
return 0 & \\
|
|
else: & \\
|
|
return 1 & \\
|
|
|
|
\hline
|
|
\end{tabular}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|