\hypertarget{group__Ecore__Thread__Group}{}\section{Ecore Thread functions}
\label{group__Ecore__Thread__Group}\index{Ecore Thread functions@{Ecore Thread functions}}


Facilities to run heavy tasks in different threads to avoid blocking the main loop.  


\subsection*{Typedefs}
\begin{DoxyCompactItemize}
\item 
\mbox{\Hypertarget{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}\label{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}} 
typedef struct \+\_\+\+Ecore\+\_\+\+Thread \hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread}
\begin{DoxyCompactList}\small\item\em A handle for threaded jobs. \end{DoxyCompactList}\item 
\mbox{\Hypertarget{group__Ecore__Thread__Group_ga2df413a7ddcf4912abe99c0be8de4d33}\label{group__Ecore__Thread__Group_ga2df413a7ddcf4912abe99c0be8de4d33}} 
typedef void($\ast$ \hyperlink{group__Ecore__Thread__Group_ga2df413a7ddcf4912abe99c0be8de4d33}{Ecore\+\_\+\+Thread\+\_\+\+Cb}) (void $\ast$data, \hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} $\ast$thread)
\begin{DoxyCompactList}\small\item\em A callback used by Ecore\+\_\+\+Thread helper. \end{DoxyCompactList}\item 
\mbox{\Hypertarget{group__Ecore__Thread__Group_gad2d0337f9bd59848a3194bac11e71a1a}\label{group__Ecore__Thread__Group_gad2d0337f9bd59848a3194bac11e71a1a}} 
typedef void($\ast$ \hyperlink{group__Ecore__Thread__Group_gad2d0337f9bd59848a3194bac11e71a1a}{Ecore\+\_\+\+Thread\+\_\+\+Notify\+\_\+\+Cb}) (void $\ast$data, \hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} $\ast$thread, void $\ast$msg\+\_\+data)
\begin{DoxyCompactList}\small\item\em A callback used by the main loop to receive data sent by an \hyperlink{group__Ecore__Thread__Group}{Ecore Thread functions}. \end{DoxyCompactList}\end{DoxyCompactItemize}
\subsection*{Functions}
\begin{DoxyCompactItemize}
\item 
\hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} $\ast$ \hyperlink{group__Ecore__Thread__Group_gaac9c9933ef0a90ba86f8fd0247e9c7ef}{ecore\+\_\+thread\+\_\+run} (\hyperlink{group__Ecore__Thread__Group_ga2df413a7ddcf4912abe99c0be8de4d33}{Ecore\+\_\+\+Thread\+\_\+\+Cb} func\+\_\+blocking, \hyperlink{group__Ecore__Thread__Group_ga2df413a7ddcf4912abe99c0be8de4d33}{Ecore\+\_\+\+Thread\+\_\+\+Cb} func\+\_\+end, \hyperlink{group__Ecore__Thread__Group_ga2df413a7ddcf4912abe99c0be8de4d33}{Ecore\+\_\+\+Thread\+\_\+\+Cb} func\+\_\+cancel, const void $\ast$data)
\begin{DoxyCompactList}\small\item\em Schedule a task to run in a parallel thread to avoid locking the main loop. \end{DoxyCompactList}\item 
\hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} $\ast$ \hyperlink{group__Ecore__Thread__Group_ga4bde6b50e177f26ab5b2688aa99e3878}{ecore\+\_\+thread\+\_\+feedback\+\_\+run} (\hyperlink{group__Ecore__Thread__Group_ga2df413a7ddcf4912abe99c0be8de4d33}{Ecore\+\_\+\+Thread\+\_\+\+Cb} func\+\_\+heavy, \hyperlink{group__Ecore__Thread__Group_gad2d0337f9bd59848a3194bac11e71a1a}{Ecore\+\_\+\+Thread\+\_\+\+Notify\+\_\+\+Cb} func\+\_\+notify, \hyperlink{group__Ecore__Thread__Group_ga2df413a7ddcf4912abe99c0be8de4d33}{Ecore\+\_\+\+Thread\+\_\+\+Cb} func\+\_\+end, \hyperlink{group__Ecore__Thread__Group_ga2df413a7ddcf4912abe99c0be8de4d33}{Ecore\+\_\+\+Thread\+\_\+\+Cb} func\+\_\+cancel, const void $\ast$data, \hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\+\_\+\+Bool} try\+\_\+no\+\_\+queue)
\begin{DoxyCompactList}\small\item\em Launch a thread to run a task that can talk back to the main thread. \end{DoxyCompactList}\item 
\hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\+\_\+\+Bool} \hyperlink{group__Ecore__Thread__Group_gae9b9b20e1ed53c62c51617b55aed2511}{ecore\+\_\+thread\+\_\+cancel} (\hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} $\ast$thread)
\begin{DoxyCompactList}\small\item\em Cancel a running thread. \end{DoxyCompactList}\item 
\hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\+\_\+\+Bool} \hyperlink{group__Ecore__Thread__Group_ga0b252a091ed78a33afed31cf147f58e2}{ecore\+\_\+thread\+\_\+wait} (\hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} $\ast$thread, double wait)
\begin{DoxyCompactList}\small\item\em Block the main loop until the thread execution is over. \end{DoxyCompactList}\item 
\hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\+\_\+\+Bool} \hyperlink{group__Ecore__Thread__Group_ga792471a7ed00718b71d58b791ddbd08d}{ecore\+\_\+thread\+\_\+check} (\hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} $\ast$thread)
\begin{DoxyCompactList}\small\item\em Checks if a thread is pending cancellation. \end{DoxyCompactList}\item 
\hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\+\_\+\+Bool} \hyperlink{group__Ecore__Thread__Group_ga8fadd19caae011ab1483665f09ce4d91}{ecore\+\_\+thread\+\_\+feedback} (\hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} $\ast$thread, const void $\ast$msg\+\_\+data)
\begin{DoxyCompactList}\small\item\em Sends data from the worker thread to the main loop. \end{DoxyCompactList}\item 
\hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\+\_\+\+Bool} \hyperlink{group__Ecore__Thread__Group_gadf825c1a58f06bba2a304d025bed3185}{ecore\+\_\+thread\+\_\+reschedule} (\hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} $\ast$thread)
\begin{DoxyCompactList}\small\item\em Asks for the function in the thread to be called again at a later time. \end{DoxyCompactList}\item 
int \hyperlink{group__Ecore__Thread__Group_gad7a28588dc26d6af8b6db8abc3ef37ce}{ecore\+\_\+thread\+\_\+active\+\_\+get} (void)
\begin{DoxyCompactList}\small\item\em Gets the number of active threads running jobs. \end{DoxyCompactList}\item 
int \hyperlink{group__Ecore__Thread__Group_ga3e32f650cfe811e69bba7825c71b9070}{ecore\+\_\+thread\+\_\+pending\+\_\+get} (void)
\begin{DoxyCompactList}\small\item\em Gets the number of short jobs waiting for a thread to run. \end{DoxyCompactList}\item 
int \hyperlink{group__Ecore__Thread__Group_gaa5c56445198f7b03c1f080039499689a}{ecore\+\_\+thread\+\_\+pending\+\_\+feedback\+\_\+get} (void)
\begin{DoxyCompactList}\small\item\em Gets the number of feedback jobs waiting for a thread to run. \end{DoxyCompactList}\item 
int \hyperlink{group__Ecore__Thread__Group_gaeaa014287d578a200d41cca861bceac3}{ecore\+\_\+thread\+\_\+pending\+\_\+total\+\_\+get} (void)
\begin{DoxyCompactList}\small\item\em Gets the total number of pending jobs. \end{DoxyCompactList}\item 
int \hyperlink{group__Ecore__Thread__Group_gabad7972818b7fb1346ae7a098cd47220}{ecore\+\_\+thread\+\_\+max\+\_\+get} (void)
\begin{DoxyCompactList}\small\item\em Gets the maximum number of threads that can run simultaneously. \end{DoxyCompactList}\item 
void \hyperlink{group__Ecore__Thread__Group_gaaf965a46e0cc12857883806812af7693}{ecore\+\_\+thread\+\_\+max\+\_\+set} (int num)
\begin{DoxyCompactList}\small\item\em Sets the maximum number of threads allowed to run simultaneously. \end{DoxyCompactList}\item 
void \hyperlink{group__Ecore__Thread__Group_ga4324944541abf9f84861690b4ff66e18}{ecore\+\_\+thread\+\_\+max\+\_\+reset} (void)
\begin{DoxyCompactList}\small\item\em Resets the maximum number of concurrently running threads to the default. \end{DoxyCompactList}\item 
int \hyperlink{group__Ecore__Thread__Group_ga6e7703b3013d9c872449f6e2ec093b53}{ecore\+\_\+thread\+\_\+available\+\_\+get} (void)
\begin{DoxyCompactList}\small\item\em Gets the number of threads available for running tasks. \end{DoxyCompactList}\item 
\hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\+\_\+\+Bool} \hyperlink{group__Ecore__Thread__Group_ga6878f550a9bcc8002c0c709b4b4dca66}{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+add} (\hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} $\ast$thread, const char $\ast$key, void $\ast$value, \hyperlink{group__Eina__Types__Group_gadbac560ba2bca5c61d97bfbb542018f3}{Eina\+\_\+\+Free\+\_\+\+Cb} cb, \hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\+\_\+\+Bool} direct)
\begin{DoxyCompactList}\small\item\em Adds some data to a hash local to the thread. \end{DoxyCompactList}\item 
void $\ast$ \hyperlink{group__Ecore__Thread__Group_ga56a7d8c062f5c42fbc338c9ded4da453}{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+set} (\hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} $\ast$thread, const char $\ast$key, void $\ast$value, \hyperlink{group__Eina__Types__Group_gadbac560ba2bca5c61d97bfbb542018f3}{Eina\+\_\+\+Free\+\_\+\+Cb} cb)
\begin{DoxyCompactList}\small\item\em Sets some data in the hash local to the given thread. \end{DoxyCompactList}\item 
void $\ast$ \hyperlink{group__Ecore__Thread__Group_ga1a937d674f1a20162b31b95d0ed100ad}{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+find} (\hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} $\ast$thread, const char $\ast$key)
\begin{DoxyCompactList}\small\item\em Gets data stored in the hash local to the given thread. \end{DoxyCompactList}\item 
\hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\+\_\+\+Bool} \hyperlink{group__Ecore__Thread__Group_gad3c1d51a24772b885b26486be86c2779}{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+del} (\hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} $\ast$thread, const char $\ast$key)
\begin{DoxyCompactList}\small\item\em Deletes from the thread\textquotesingle{}s hash the data corresponding to the given key. \end{DoxyCompactList}\item 
\hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\+\_\+\+Bool} \hyperlink{group__Ecore__Thread__Group_ga4e9de7492f8400e19ddd157d8cc21811}{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+add} (const char $\ast$key, void $\ast$value, \hyperlink{group__Eina__Types__Group_gadbac560ba2bca5c61d97bfbb542018f3}{Eina\+\_\+\+Free\+\_\+\+Cb} cb, \hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\+\_\+\+Bool} direct)
\begin{DoxyCompactList}\small\item\em Adds some data to a hash shared by all threads. \end{DoxyCompactList}\item 
void $\ast$ \hyperlink{group__Ecore__Thread__Group_gace0bfd51f1dceef9d66f620bcffccabd}{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+set} (const char $\ast$key, void $\ast$value, \hyperlink{group__Eina__Types__Group_gadbac560ba2bca5c61d97bfbb542018f3}{Eina\+\_\+\+Free\+\_\+\+Cb} cb)
\begin{DoxyCompactList}\small\item\em Sets some data in the hash shared by all threads. \end{DoxyCompactList}\item 
void $\ast$ \hyperlink{group__Ecore__Thread__Group_ga011eeb2f99aaa950089ddc6ea989da29}{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+find} (const char $\ast$key)
\begin{DoxyCompactList}\small\item\em Gets data stored in the hash shared by all threads. \end{DoxyCompactList}\item 
\hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\+\_\+\+Bool} \hyperlink{group__Ecore__Thread__Group_ga8e53feb974331550744cbc2e40dc9132}{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+del} (const char $\ast$key)
\begin{DoxyCompactList}\small\item\em Deletes from the shared hash the data corresponding to the given key. \end{DoxyCompactList}\item 
void $\ast$ \hyperlink{group__Ecore__Thread__Group_ga910b00728b8b0201677f7a09e8d44896}{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+wait} (const char $\ast$key, double seconds)
\begin{DoxyCompactList}\small\item\em Gets data stored in the shared hash, or wait for it if it doesn\textquotesingle{}t exist. \end{DoxyCompactList}\end{DoxyCompactItemize}


\subsection{Detailed Description}
Facilities to run heavy tasks in different threads to avoid blocking the main loop. 

The E\+FL is, for the most part, not thread safe. This means that if you have some task running in another thread and you have, for example, an Evas object to show the status progress of this task, you cannot update the object from within the thread. This can only be done from the main thread, the one running the main loop. This problem can be solved by running a thread that sends messages to the main one using an \hyperlink{group__Ecore__Pipe__Group}{Ecore\+\_\+\+Pipe}, but when you need to handle other things like cancelling the thread, your code grows in complexity and gets much harder to maintain.

Ecore Thread is here to solve that problem. It is {\bfseries not} a simple wrapper around standard P\+O\+S\+IX threads (or the equivalent in other systems) and it\textquotesingle{}s not meant to be used to run parallel tasks throughout the entire duration of the program, especially when these tasks are performance critical, as Ecore manages these tasks using a pool of threads based on system configuration.

What Ecore Thread does, is make it a lot easier to dispatch a worker function to perform some heavy task and then get the result once it completes, without blocking the application\textquotesingle{}s UI. In addition, cancelling and rescheduling comes practically for free and the developer needs not worry about how many threads are launched, since Ecore will schedule them according to the number of processors the system has and maximum amount of concurrent threads set for the application.

At the system level, Ecore will start a new thread on an as-\/needed basis until the maximum set is reached. When no more threads can be launched, new worker functions will be queued in a waiting list until a thread becomes available. This way, system threads will be shared throughout different worker functions, but running only one at a time. At the same time, a worker function that is rescheduled may be run on a different thread the next time.

The \hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} handler has two meanings, depending on what context it is on. The one returned when starting a worker with any of the functions \hyperlink{group__Ecore__Thread__Group_gaac9c9933ef0a90ba86f8fd0247e9c7ef}{ecore\+\_\+thread\+\_\+run()} or \hyperlink{group__Ecore__Thread__Group_ga4bde6b50e177f26ab5b2688aa99e3878}{ecore\+\_\+thread\+\_\+feedback\+\_\+run()} is an identifier of that specific instance of the function and can be used from the main loop with the \hyperlink{group__Ecore__Thread__Group_gae9b9b20e1ed53c62c51617b55aed2511}{ecore\+\_\+thread\+\_\+cancel()} and \hyperlink{group__Ecore__Thread__Group_ga792471a7ed00718b71d58b791ddbd08d}{ecore\+\_\+thread\+\_\+check()} functions. This handler must not be shared with the worker function function running in the thread. This same handler will be the one received on the {\ttfamily end}, {\ttfamily cancel} and {\ttfamily feedback} callbacks.

The worker function, that\textquotesingle{}s the one running in the thread, also receives an \hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} handler that can be used with \hyperlink{group__Ecore__Thread__Group_gae9b9b20e1ed53c62c51617b55aed2511}{ecore\+\_\+thread\+\_\+cancel()} and \hyperlink{group__Ecore__Thread__Group_ga792471a7ed00718b71d58b791ddbd08d}{ecore\+\_\+thread\+\_\+check()}, sharing the flag with the main loop. But this handler is also associated with the thread where the function is running. This has strong implications when working with thread local data.

There are two kinds of worker threads Ecore handles\+: simple, or short, workers and feedback workers.

The first kind is for simple functions that perform a usually small but time consuming task. Ecore will run this function in a thread as soon as one becomes available and notify the calling user of its completion once the task is done.

The following image shows the flow of a program running four tasks on a pool of two threads.

  
\begin{DoxyImageNoCaption}
  \mbox{\includegraphics[width=\textwidth]{ecore_thread}}
\end{DoxyImageNoCaption}


For larger tasks that may require continuous communication with the main program, the feedback workers provide the same functionality plus a way for the function running in the thread to send messages to the main thread.

The next diagram omits some details shown in the previous one regarding how threads are spawned and tasks are queued, but illustrates how feedback jobs communicate with the main loop and the special case of threads running out of pool.

  
\begin{DoxyImageNoCaption}
  \mbox{\includegraphics[width=\textwidth]{ecore_thread_feedback}}
\end{DoxyImageNoCaption}


See an overview example in \hyperlink{ecore_thread_example_c}{Ecore\+\_\+\+Thread -\/ A\+PI overview}. 

\subsection{Function Documentation}
\mbox{\Hypertarget{group__Ecore__Thread__Group_gaac9c9933ef0a90ba86f8fd0247e9c7ef}\label{group__Ecore__Thread__Group_gaac9c9933ef0a90ba86f8fd0247e9c7ef}} 
\index{Ecore Thread functions@{Ecore Thread functions}!ecore\+\_\+thread\+\_\+run@{ecore\+\_\+thread\+\_\+run}}
\index{ecore\+\_\+thread\+\_\+run@{ecore\+\_\+thread\+\_\+run}!Ecore Thread functions@{Ecore Thread functions}}
\subsubsection{\texorpdfstring{ecore\+\_\+thread\+\_\+run()}{ecore\_thread\_run()}}
{\footnotesize\ttfamily \hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread}$\ast$ ecore\+\_\+thread\+\_\+run (\begin{DoxyParamCaption}\item[{\hyperlink{group__Ecore__Thread__Group_ga2df413a7ddcf4912abe99c0be8de4d33}{Ecore\+\_\+\+Thread\+\_\+\+Cb}}]{func\+\_\+blocking,  }\item[{\hyperlink{group__Ecore__Thread__Group_ga2df413a7ddcf4912abe99c0be8de4d33}{Ecore\+\_\+\+Thread\+\_\+\+Cb}}]{func\+\_\+end,  }\item[{\hyperlink{group__Ecore__Thread__Group_ga2df413a7ddcf4912abe99c0be8de4d33}{Ecore\+\_\+\+Thread\+\_\+\+Cb}}]{func\+\_\+cancel,  }\item[{const void $\ast$}]{data }\end{DoxyParamCaption})}



Schedule a task to run in a parallel thread to avoid locking the main loop. 


\begin{DoxyParams}{Parameters}
{\em func\+\_\+blocking} & The function that should run in another thread. \\
\hline
{\em func\+\_\+end} & Function to call from main loop when {\ttfamily func\+\_\+blocking} completes its task successfully (may be N\+U\+LL) \\
\hline
{\em func\+\_\+cancel} & Function to call from main loop if the thread running {\ttfamily func\+\_\+blocking} is cancelled or fails to start (may be N\+U\+LL) \\
\hline
{\em data} & User context data to pass to all callbacks. \\
\hline
\end{DoxyParams}
\begin{DoxyReturn}{Returns}
A new thread handler, or {\ttfamily N\+U\+LL} on failure.
\end{DoxyReturn}
This function will try to create a new thread to run {\ttfamily func\+\_\+blocking} in, or if the maximum number of concurrent threads has been reached, will add it to the pending list, where it will wait until a thread becomes available. The return value will be an \hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} handle that can be used to cancel the thread before its completion.

\begin{DoxyNote}{Note}
This function should always return immediately, but in the rare case that Ecore is built with no thread support, {\ttfamily func\+\_\+blocking} will be called here, actually blocking the main loop.
\end{DoxyNote}
Once a thread becomes available, {\ttfamily func\+\_\+blocking} will be run in it until it finishes, then {\ttfamily func\+\_\+end} is called from the thread containing the main loop to inform the user of its completion. While in {\ttfamily func\+\_\+blocking}, no functions from the E\+FL can be used, except for those from Eina that are marked to be thread-\/safe. Even for the latter, caution needs to be taken if the data is shared across several threads.

{\ttfamily func\+\_\+end} will be called from the main thread when {\ttfamily func\+\_\+blocking} ends, so here it\textquotesingle{}s safe to use anything from the E\+FL freely.

The thread can also be cancelled before its completion calling \hyperlink{group__Ecore__Thread__Group_gae9b9b20e1ed53c62c51617b55aed2511}{ecore\+\_\+thread\+\_\+cancel()}, either from the main thread or {\ttfamily func\+\_\+blocking}. In this case, {\ttfamily func\+\_\+cancel} will be called, also from the main thread to inform of this happening. If the thread could not be created, this function will be called and it\textquotesingle{}s {\ttfamily thread} parameter will be N\+U\+LL. It\textquotesingle{}s also safe to call any E\+FL function here, as it will be running in the main thread.

Inside {\ttfamily func\+\_\+blocking}, it\textquotesingle{}s possible to call \hyperlink{group__Ecore__Thread__Group_gadf825c1a58f06bba2a304d025bed3185}{ecore\+\_\+thread\+\_\+reschedule()} to tell Ecore that this function should be called again.

Be aware that no assumptions can be made about the order in which the {\ttfamily func\+\_\+end} callbacks for each task will be called. Once the function is running in a different thread, it\textquotesingle{}s the OS that will handle its running schedule, and different functions may take longer to finish than others. Also remember that just starting several tasks together doesn\textquotesingle{}t mean they will be running at the same time. Ecore will schedule them based on the number of threads available for the particular system it\textquotesingle{}s running in, so some of the jobs started may be waiting until another one finishes before it can execute its own {\ttfamily func\+\_\+blocking}.

\begin{DoxySeeAlso}{See also}
\hyperlink{group__Ecore__Thread__Group_ga4bde6b50e177f26ab5b2688aa99e3878}{ecore\+\_\+thread\+\_\+feedback\+\_\+run()} 

\hyperlink{group__Ecore__Thread__Group_gae9b9b20e1ed53c62c51617b55aed2511}{ecore\+\_\+thread\+\_\+cancel()} 

\hyperlink{group__Ecore__Thread__Group_gadf825c1a58f06bba2a304d025bed3185}{ecore\+\_\+thread\+\_\+reschedule()} 

\hyperlink{group__Ecore__Thread__Group_gaaf965a46e0cc12857883806812af7693}{ecore\+\_\+thread\+\_\+max\+\_\+set()} 
\end{DoxySeeAlso}
\begin{Desc}
\item[Examples\+: ]\par
\hyperlink{ecore_thread_example_8c-example}{ecore\+\_\+thread\+\_\+example.\+c}.\end{Desc}


References E\+I\+N\+A\+\_\+\+F\+A\+L\+SE, eina\+\_\+list\+\_\+append(), eina\+\_\+list\+\_\+remove(), E\+I\+N\+A\+\_\+\+M\+A\+I\+N\+\_\+\+L\+O\+O\+P\+\_\+\+C\+H\+E\+C\+K\+\_\+\+R\+E\+T\+U\+R\+N\+\_\+\+V\+AL, eina\+\_\+threads\+\_\+init(), eina\+\_\+threads\+\_\+shutdown(), and E\+I\+N\+A\+\_\+\+T\+R\+UE.



Referenced by efreet\+\_\+menu\+\_\+async\+\_\+parse().

\mbox{\Hypertarget{group__Ecore__Thread__Group_ga4bde6b50e177f26ab5b2688aa99e3878}\label{group__Ecore__Thread__Group_ga4bde6b50e177f26ab5b2688aa99e3878}} 
\index{Ecore Thread functions@{Ecore Thread functions}!ecore\+\_\+thread\+\_\+feedback\+\_\+run@{ecore\+\_\+thread\+\_\+feedback\+\_\+run}}
\index{ecore\+\_\+thread\+\_\+feedback\+\_\+run@{ecore\+\_\+thread\+\_\+feedback\+\_\+run}!Ecore Thread functions@{Ecore Thread functions}}
\subsubsection{\texorpdfstring{ecore\+\_\+thread\+\_\+feedback\+\_\+run()}{ecore\_thread\_feedback\_run()}}
{\footnotesize\ttfamily \hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread}$\ast$ ecore\+\_\+thread\+\_\+feedback\+\_\+run (\begin{DoxyParamCaption}\item[{\hyperlink{group__Ecore__Thread__Group_ga2df413a7ddcf4912abe99c0be8de4d33}{Ecore\+\_\+\+Thread\+\_\+\+Cb}}]{func\+\_\+heavy,  }\item[{\hyperlink{group__Ecore__Thread__Group_gad2d0337f9bd59848a3194bac11e71a1a}{Ecore\+\_\+\+Thread\+\_\+\+Notify\+\_\+\+Cb}}]{func\+\_\+notify,  }\item[{\hyperlink{group__Ecore__Thread__Group_ga2df413a7ddcf4912abe99c0be8de4d33}{Ecore\+\_\+\+Thread\+\_\+\+Cb}}]{func\+\_\+end,  }\item[{\hyperlink{group__Ecore__Thread__Group_ga2df413a7ddcf4912abe99c0be8de4d33}{Ecore\+\_\+\+Thread\+\_\+\+Cb}}]{func\+\_\+cancel,  }\item[{const void $\ast$}]{data,  }\item[{\hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\+\_\+\+Bool}}]{try\+\_\+no\+\_\+queue }\end{DoxyParamCaption})}



Launch a thread to run a task that can talk back to the main thread. 


\begin{DoxyParams}{Parameters}
{\em func\+\_\+heavy} & The function that should run in another thread. \\
\hline
{\em func\+\_\+notify} & Function that receives the data sent from the thread \\
\hline
{\em func\+\_\+end} & Function to call from main loop when {\ttfamily func\+\_\+heavy} completes its task successfully \\
\hline
{\em func\+\_\+cancel} & Function to call from main loop if the thread running {\ttfamily func\+\_\+heavy} is cancelled or fails to start \\
\hline
{\em data} & User context data to pass to all callback. \\
\hline
{\em try\+\_\+no\+\_\+queue} & If you want to run outside of the thread pool. \\
\hline
\end{DoxyParams}
\begin{DoxyReturn}{Returns}
A new thread handler, or {\ttfamily N\+U\+LL} on failure.
\end{DoxyReturn}
See \hyperlink{group__Ecore__Thread__Group_gaac9c9933ef0a90ba86f8fd0247e9c7ef}{ecore\+\_\+thread\+\_\+run()} for a general description of this function.

The difference with the above is that \hyperlink{group__Ecore__Thread__Group_gaac9c9933ef0a90ba86f8fd0247e9c7ef}{ecore\+\_\+thread\+\_\+run()} is meant for tasks that don\textquotesingle{}t need to communicate anything until they finish, while this function is provided with a new callback, {\ttfamily func\+\_\+notify}, that will be called from the main thread for every message sent from {\ttfamily func\+\_\+heavy} with \hyperlink{group__Ecore__Thread__Group_ga8fadd19caae011ab1483665f09ce4d91}{ecore\+\_\+thread\+\_\+feedback()}.

Like \hyperlink{group__Ecore__Thread__Group_gaac9c9933ef0a90ba86f8fd0247e9c7ef}{ecore\+\_\+thread\+\_\+run()}, a new thread will be launched to run {\ttfamily func\+\_\+heavy} unless the maximum number of simultaneous threads has been reached, in which case the function will be scheduled to run whenever a running task ends and a thread becomes free. But if {\ttfamily try\+\_\+no\+\_\+queue} is set, Ecore will first try to launch a thread outside of the pool to run the task. If it fails, it will revert to the normal behaviour of using a thread from the pool as if {\ttfamily try\+\_\+no\+\_\+queue} had not been set.

Keep in mind that Ecore handles the thread pool based on the number of C\+P\+Us available, but running a thread outside of the pool doesn\textquotesingle{}t count for this, so having too many of them may have drastic effects over the program\textquotesingle{}s performance.

\begin{DoxySeeAlso}{See also}
\hyperlink{group__Ecore__Thread__Group_ga8fadd19caae011ab1483665f09ce4d91}{ecore\+\_\+thread\+\_\+feedback()} 

\hyperlink{group__Ecore__Thread__Group_gaac9c9933ef0a90ba86f8fd0247e9c7ef}{ecore\+\_\+thread\+\_\+run()} 

\hyperlink{group__Ecore__Thread__Group_gae9b9b20e1ed53c62c51617b55aed2511}{ecore\+\_\+thread\+\_\+cancel()} 

\hyperlink{group__Ecore__Thread__Group_gadf825c1a58f06bba2a304d025bed3185}{ecore\+\_\+thread\+\_\+reschedule()} 

\hyperlink{group__Ecore__Thread__Group_gaaf965a46e0cc12857883806812af7693}{ecore\+\_\+thread\+\_\+max\+\_\+set()} 
\end{DoxySeeAlso}
\begin{Desc}
\item[Examples\+: ]\par
\hyperlink{ecore_thread_example_8c-example}{ecore\+\_\+thread\+\_\+example.\+c}.\end{Desc}


References E\+I\+N\+A\+\_\+\+F\+A\+L\+SE, eina\+\_\+list\+\_\+append(), eina\+\_\+list\+\_\+remove(), E\+I\+N\+A\+\_\+\+M\+A\+I\+N\+\_\+\+L\+O\+O\+P\+\_\+\+C\+H\+E\+C\+K\+\_\+\+R\+E\+T\+U\+R\+N\+\_\+\+V\+AL, eina\+\_\+threads\+\_\+init(), eina\+\_\+threads\+\_\+shutdown(), and E\+I\+N\+A\+\_\+\+T\+R\+UE.

\mbox{\Hypertarget{group__Ecore__Thread__Group_gae9b9b20e1ed53c62c51617b55aed2511}\label{group__Ecore__Thread__Group_gae9b9b20e1ed53c62c51617b55aed2511}} 
\index{Ecore Thread functions@{Ecore Thread functions}!ecore\+\_\+thread\+\_\+cancel@{ecore\+\_\+thread\+\_\+cancel}}
\index{ecore\+\_\+thread\+\_\+cancel@{ecore\+\_\+thread\+\_\+cancel}!Ecore Thread functions@{Ecore Thread functions}}
\subsubsection{\texorpdfstring{ecore\+\_\+thread\+\_\+cancel()}{ecore\_thread\_cancel()}}
{\footnotesize\ttfamily \hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\+\_\+\+Bool} ecore\+\_\+thread\+\_\+cancel (\begin{DoxyParamCaption}\item[{\hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} $\ast$}]{thread }\end{DoxyParamCaption})}



Cancel a running thread. 


\begin{DoxyParams}{Parameters}
{\em thread} & The thread to cancel. \\
\hline
\end{DoxyParams}
\begin{DoxyReturn}{Returns}
Will return {\ttfamily E\+I\+N\+A\+\_\+\+T\+R\+UE} if the thread has been cancelled, {\ttfamily E\+I\+N\+A\+\_\+\+F\+A\+L\+SE} if it is pending.
\end{DoxyReturn}
This function can be called both in the main loop or in the running thread.

This function cancels a running thread. If {\ttfamily thread} can be immediately cancelled (it\textquotesingle{}s still pending execution after creation or rescheduling), then the {\ttfamily cancel} callback will be called, {\ttfamily thread} will be freed and the function will return {\ttfamily E\+I\+N\+A\+\_\+\+T\+R\+UE}.

If the thread is already running, then this function returns {\ttfamily E\+I\+N\+A\+\_\+\+F\+A\+L\+SE} after marking the {\ttfamily thread} as pending cancellation. For the thread to actually be terminated, it needs to return from the user function back into Ecore control. This can happen in several ways\+: \begin{DoxyItemize}
\item The function ends and returns normally. If it hadn\textquotesingle{}t been cancelled, {\ttfamily func\+\_\+end} would be called here, but instead {\ttfamily func\+\_\+cancel} will happen. \item The function returns after requesting to be rescheduled with \hyperlink{group__Ecore__Thread__Group_gadf825c1a58f06bba2a304d025bed3185}{ecore\+\_\+thread\+\_\+reschedule()}. \item The function is prepared to leave early by checking if \hyperlink{group__Ecore__Thread__Group_ga792471a7ed00718b71d58b791ddbd08d}{ecore\+\_\+thread\+\_\+check()} returns {\ttfamily E\+I\+N\+A\+\_\+\+T\+R\+UE}.\end{DoxyItemize}
The user function can cancel itself by calling \hyperlink{group__Ecore__Thread__Group_gae9b9b20e1ed53c62c51617b55aed2511}{ecore\+\_\+thread\+\_\+cancel()}, but it should always use the \hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} handle passed to it and never share it with the main loop thread by means of shared user data or any other way.

{\ttfamily thread} will be freed and should not be used again if this function returns {\ttfamily E\+I\+N\+A\+\_\+\+T\+R\+UE} or after the {\ttfamily func\+\_\+cancel} callback returns.

\begin{DoxySeeAlso}{See also}
\hyperlink{group__Ecore__Thread__Group_ga792471a7ed00718b71d58b791ddbd08d}{ecore\+\_\+thread\+\_\+check()} 
\end{DoxySeeAlso}
\begin{Desc}
\item[Examples\+: ]\par
\hyperlink{ecore_thread_example_8c-example}{ecore\+\_\+thread\+\_\+example.\+c}.\end{Desc}


References E\+I\+N\+A\+\_\+\+F\+A\+L\+SE, E\+I\+N\+A\+\_\+\+L\+I\+S\+T\+\_\+\+F\+O\+R\+E\+A\+CH, eina\+\_\+list\+\_\+remove\+\_\+list(), and E\+I\+N\+A\+\_\+\+T\+R\+UE.



Referenced by ethumb\+\_\+client\+\_\+thumb\+\_\+exists\+\_\+cancel().

\mbox{\Hypertarget{group__Ecore__Thread__Group_ga0b252a091ed78a33afed31cf147f58e2}\label{group__Ecore__Thread__Group_ga0b252a091ed78a33afed31cf147f58e2}} 
\index{Ecore Thread functions@{Ecore Thread functions}!ecore\+\_\+thread\+\_\+wait@{ecore\+\_\+thread\+\_\+wait}}
\index{ecore\+\_\+thread\+\_\+wait@{ecore\+\_\+thread\+\_\+wait}!Ecore Thread functions@{Ecore Thread functions}}
\subsubsection{\texorpdfstring{ecore\+\_\+thread\+\_\+wait()}{ecore\_thread\_wait()}}
{\footnotesize\ttfamily \hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\+\_\+\+Bool} ecore\+\_\+thread\+\_\+wait (\begin{DoxyParamCaption}\item[{\hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} $\ast$}]{thread,  }\item[{double}]{wait }\end{DoxyParamCaption})}



Block the main loop until the thread execution is over. 

\begin{DoxySince}{Since}
1.\+13.\+0
\end{DoxySince}

\begin{DoxyParams}{Parameters}
{\em thread} & The thread to wait on. \\
\hline
{\em wait} & Maximum time to wait before exiting anyway. \\
\hline
\end{DoxyParams}
\begin{DoxyReturn}{Returns}
E\+I\+N\+A\+\_\+\+T\+R\+UE if the thread execution is over. 
\end{DoxyReturn}


References ecore\+\_\+main\+\_\+loop\+\_\+thread\+\_\+safe\+\_\+call\+\_\+wait(), ecore\+\_\+time\+\_\+get(), E\+I\+N\+A\+\_\+\+F\+A\+L\+SE, and E\+I\+N\+A\+\_\+\+T\+R\+UE.

\mbox{\Hypertarget{group__Ecore__Thread__Group_ga792471a7ed00718b71d58b791ddbd08d}\label{group__Ecore__Thread__Group_ga792471a7ed00718b71d58b791ddbd08d}} 
\index{Ecore Thread functions@{Ecore Thread functions}!ecore\+\_\+thread\+\_\+check@{ecore\+\_\+thread\+\_\+check}}
\index{ecore\+\_\+thread\+\_\+check@{ecore\+\_\+thread\+\_\+check}!Ecore Thread functions@{Ecore Thread functions}}
\subsubsection{\texorpdfstring{ecore\+\_\+thread\+\_\+check()}{ecore\_thread\_check()}}
{\footnotesize\ttfamily \hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\+\_\+\+Bool} ecore\+\_\+thread\+\_\+check (\begin{DoxyParamCaption}\item[{\hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} $\ast$}]{thread }\end{DoxyParamCaption})}



Checks if a thread is pending cancellation. 


\begin{DoxyParams}{Parameters}
{\em thread} & The thread to test. \\
\hline
\end{DoxyParams}
\begin{DoxyReturn}{Returns}
{\ttfamily E\+I\+N\+A\+\_\+\+T\+R\+UE} if the thread is pending cancellation, {\ttfamily E\+I\+N\+A\+\_\+\+F\+A\+L\+SE} if it is not.
\end{DoxyReturn}
This function can be called both in the main loop or in the running thread.

When \hyperlink{group__Ecore__Thread__Group_gae9b9b20e1ed53c62c51617b55aed2511}{ecore\+\_\+thread\+\_\+cancel()} is called on an already running task, the thread is marked as pending cancellation. This function returns {\ttfamily E\+I\+N\+A\+\_\+\+T\+R\+UE} if this mark is set for the given {\ttfamily thread} and can be used from the main loop thread to check if a still active thread has been cancelled, or from the user function running in the thread to check if it should stop doing what it\textquotesingle{}s doing and return early, effectively cancelling the task.

\begin{DoxySeeAlso}{See also}
\hyperlink{group__Ecore__Thread__Group_gae9b9b20e1ed53c62c51617b55aed2511}{ecore\+\_\+thread\+\_\+cancel()} 
\end{DoxySeeAlso}
\begin{Desc}
\item[Examples\+: ]\par
\hyperlink{ecore_thread_example_8c-example}{ecore\+\_\+thread\+\_\+example.\+c}.\end{Desc}


References E\+I\+N\+A\+\_\+\+T\+R\+UE.



Referenced by ethumb\+\_\+client\+\_\+thumb\+\_\+exists\+\_\+check().

\mbox{\Hypertarget{group__Ecore__Thread__Group_ga8fadd19caae011ab1483665f09ce4d91}\label{group__Ecore__Thread__Group_ga8fadd19caae011ab1483665f09ce4d91}} 
\index{Ecore Thread functions@{Ecore Thread functions}!ecore\+\_\+thread\+\_\+feedback@{ecore\+\_\+thread\+\_\+feedback}}
\index{ecore\+\_\+thread\+\_\+feedback@{ecore\+\_\+thread\+\_\+feedback}!Ecore Thread functions@{Ecore Thread functions}}
\subsubsection{\texorpdfstring{ecore\+\_\+thread\+\_\+feedback()}{ecore\_thread\_feedback()}}
{\footnotesize\ttfamily \hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\+\_\+\+Bool} ecore\+\_\+thread\+\_\+feedback (\begin{DoxyParamCaption}\item[{\hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} $\ast$}]{thread,  }\item[{const void $\ast$}]{msg\+\_\+data }\end{DoxyParamCaption})}



Sends data from the worker thread to the main loop. 


\begin{DoxyParams}{Parameters}
{\em thread} & The current \hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} context to send data from \\
\hline
{\em msg\+\_\+data} & Data to be transmitted to the main loop \\
\hline
\end{DoxyParams}
\begin{DoxyReturn}{Returns}
{\ttfamily E\+I\+N\+A\+\_\+\+T\+R\+UE} if {\ttfamily msg\+\_\+data} was successfully sent to main loop, {\ttfamily E\+I\+N\+A\+\_\+\+F\+A\+L\+SE} if anything goes wrong.
\end{DoxyReturn}
You should use this function only in the {\ttfamily func\+\_\+heavy} call.

Only the address to {\ttfamily msg\+\_\+data} will be sent and once this function returns {\ttfamily E\+I\+N\+A\+\_\+\+T\+R\+UE}, the job running in the thread should never touch the contents of it again. The data sent should be malloc()\textquotesingle{}ed or something similar, as long as it\textquotesingle{}s not memory local to the thread that risks being overwritten or deleted once it goes out of scope or the thread finishes.

Care must be taken that {\ttfamily msg\+\_\+data} is properly freed in the {\ttfamily func\+\_\+notify} callback set when creating the thread.

\begin{DoxySeeAlso}{See also}
\hyperlink{group__Ecore__Thread__Group_ga4bde6b50e177f26ab5b2688aa99e3878}{ecore\+\_\+thread\+\_\+feedback\+\_\+run()} 
\end{DoxySeeAlso}
\begin{Desc}
\item[Examples\+: ]\par
\hyperlink{ecore_thread_example_8c-example}{ecore\+\_\+thread\+\_\+example.\+c}.\end{Desc}


References ecore\+\_\+main\+\_\+loop\+\_\+thread\+\_\+safe\+\_\+call\+\_\+async(), E\+I\+N\+A\+\_\+\+F\+A\+L\+SE, and E\+I\+N\+A\+\_\+\+T\+R\+UE.

\mbox{\Hypertarget{group__Ecore__Thread__Group_gadf825c1a58f06bba2a304d025bed3185}\label{group__Ecore__Thread__Group_gadf825c1a58f06bba2a304d025bed3185}} 
\index{Ecore Thread functions@{Ecore Thread functions}!ecore\+\_\+thread\+\_\+reschedule@{ecore\+\_\+thread\+\_\+reschedule}}
\index{ecore\+\_\+thread\+\_\+reschedule@{ecore\+\_\+thread\+\_\+reschedule}!Ecore Thread functions@{Ecore Thread functions}}
\subsubsection{\texorpdfstring{ecore\+\_\+thread\+\_\+reschedule()}{ecore\_thread\_reschedule()}}
{\footnotesize\ttfamily \hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\+\_\+\+Bool} ecore\+\_\+thread\+\_\+reschedule (\begin{DoxyParamCaption}\item[{\hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} $\ast$}]{thread }\end{DoxyParamCaption})}



Asks for the function in the thread to be called again at a later time. 


\begin{DoxyParams}{Parameters}
{\em thread} & The current \hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} context to rescheduled \\
\hline
\end{DoxyParams}
\begin{DoxyReturn}{Returns}
{\ttfamily E\+I\+N\+A\+\_\+\+T\+R\+UE} if the task was successfully rescheduled, {\ttfamily E\+I\+N\+A\+\_\+\+F\+A\+L\+SE} if anything goes wrong.
\end{DoxyReturn}
This function should be called only from the same function represented by {\ttfamily thread}.

Calling this function will mark the thread for a reschedule, so as soon as it returns, it will be added to the end of the list of pending tasks. If no other tasks are waiting or there are sufficient threads available, the rescheduled task will be launched again immediately.

This should never return {\ttfamily E\+I\+N\+A\+\_\+\+F\+A\+L\+SE}, unless it was called from the wrong thread or with the wrong arguments.

The {\ttfamily func\+\_\+end} callback set when the thread is created will not be called until the function in the thread returns without being rescheduled. Similarly, if the {\ttfamily thread} is cancelled, the reschedule will not take effect. \begin{Desc}
\item[Examples\+: ]\par
\hyperlink{ecore_thread_example_8c-example}{ecore\+\_\+thread\+\_\+example.\+c}.\end{Desc}


References E\+I\+N\+A\+\_\+\+F\+A\+L\+SE, and E\+I\+N\+A\+\_\+\+T\+R\+UE.

\mbox{\Hypertarget{group__Ecore__Thread__Group_gad7a28588dc26d6af8b6db8abc3ef37ce}\label{group__Ecore__Thread__Group_gad7a28588dc26d6af8b6db8abc3ef37ce}} 
\index{Ecore Thread functions@{Ecore Thread functions}!ecore\+\_\+thread\+\_\+active\+\_\+get@{ecore\+\_\+thread\+\_\+active\+\_\+get}}
\index{ecore\+\_\+thread\+\_\+active\+\_\+get@{ecore\+\_\+thread\+\_\+active\+\_\+get}!Ecore Thread functions@{Ecore Thread functions}}
\subsubsection{\texorpdfstring{ecore\+\_\+thread\+\_\+active\+\_\+get()}{ecore\_thread\_active\_get()}}
{\footnotesize\ttfamily int ecore\+\_\+thread\+\_\+active\+\_\+get (\begin{DoxyParamCaption}\item[{void}]{ }\end{DoxyParamCaption})}



Gets the number of active threads running jobs. 

\begin{DoxyReturn}{Returns}
Number of active threads running jobs
\end{DoxyReturn}
This returns the number of threads currently running jobs of any type through the Ecore\+\_\+\+Thread A\+PI.

\begin{DoxyNote}{Note}
Jobs started through the \hyperlink{group__Ecore__Thread__Group_ga4bde6b50e177f26ab5b2688aa99e3878}{ecore\+\_\+thread\+\_\+feedback\+\_\+run()} function with the {\ttfamily try\+\_\+no\+\_\+queue} parameter set to {\ttfamily E\+I\+N\+A\+\_\+\+T\+R\+UE} will not be accounted for in the return of this function unless the thread creation fails and it falls back to using one from the pool. 
\end{DoxyNote}
\begin{Desc}
\item[Examples\+: ]\par
\hyperlink{ecore_thread_example_8c-example}{ecore\+\_\+thread\+\_\+example.\+c}.\end{Desc}


References E\+I\+N\+A\+\_\+\+M\+A\+I\+N\+\_\+\+L\+O\+O\+P\+\_\+\+C\+H\+E\+C\+K\+\_\+\+R\+E\+T\+U\+R\+N\+\_\+\+V\+AL.

\mbox{\Hypertarget{group__Ecore__Thread__Group_ga3e32f650cfe811e69bba7825c71b9070}\label{group__Ecore__Thread__Group_ga3e32f650cfe811e69bba7825c71b9070}} 
\index{Ecore Thread functions@{Ecore Thread functions}!ecore\+\_\+thread\+\_\+pending\+\_\+get@{ecore\+\_\+thread\+\_\+pending\+\_\+get}}
\index{ecore\+\_\+thread\+\_\+pending\+\_\+get@{ecore\+\_\+thread\+\_\+pending\+\_\+get}!Ecore Thread functions@{Ecore Thread functions}}
\subsubsection{\texorpdfstring{ecore\+\_\+thread\+\_\+pending\+\_\+get()}{ecore\_thread\_pending\_get()}}
{\footnotesize\ttfamily int ecore\+\_\+thread\+\_\+pending\+\_\+get (\begin{DoxyParamCaption}\item[{void}]{ }\end{DoxyParamCaption})}



Gets the number of short jobs waiting for a thread to run. 

\begin{DoxyReturn}{Returns}
Number of pending threads running \char`\"{}short\char`\"{} jobs
\end{DoxyReturn}
This returns the number of tasks started with \hyperlink{group__Ecore__Thread__Group_gaac9c9933ef0a90ba86f8fd0247e9c7ef}{ecore\+\_\+thread\+\_\+run()} that are pending, waiting for a thread to become available to run them. \begin{Desc}
\item[Examples\+: ]\par
\hyperlink{ecore_thread_example_8c-example}{ecore\+\_\+thread\+\_\+example.\+c}.\end{Desc}


References eina\+\_\+list\+\_\+count(), and E\+I\+N\+A\+\_\+\+M\+A\+I\+N\+\_\+\+L\+O\+O\+P\+\_\+\+C\+H\+E\+C\+K\+\_\+\+R\+E\+T\+U\+R\+N\+\_\+\+V\+AL.

\mbox{\Hypertarget{group__Ecore__Thread__Group_gaa5c56445198f7b03c1f080039499689a}\label{group__Ecore__Thread__Group_gaa5c56445198f7b03c1f080039499689a}} 
\index{Ecore Thread functions@{Ecore Thread functions}!ecore\+\_\+thread\+\_\+pending\+\_\+feedback\+\_\+get@{ecore\+\_\+thread\+\_\+pending\+\_\+feedback\+\_\+get}}
\index{ecore\+\_\+thread\+\_\+pending\+\_\+feedback\+\_\+get@{ecore\+\_\+thread\+\_\+pending\+\_\+feedback\+\_\+get}!Ecore Thread functions@{Ecore Thread functions}}
\subsubsection{\texorpdfstring{ecore\+\_\+thread\+\_\+pending\+\_\+feedback\+\_\+get()}{ecore\_thread\_pending\_feedback\_get()}}
{\footnotesize\ttfamily int ecore\+\_\+thread\+\_\+pending\+\_\+feedback\+\_\+get (\begin{DoxyParamCaption}\item[{void}]{ }\end{DoxyParamCaption})}



Gets the number of feedback jobs waiting for a thread to run. 

\begin{DoxyReturn}{Returns}
Number of pending threads running \char`\"{}feedback\char`\"{} jobs
\end{DoxyReturn}
This returns the number of tasks started with \hyperlink{group__Ecore__Thread__Group_ga4bde6b50e177f26ab5b2688aa99e3878}{ecore\+\_\+thread\+\_\+feedback\+\_\+run()} that are pending, waiting for a thread to become available to run them. \begin{Desc}
\item[Examples\+: ]\par
\hyperlink{ecore_thread_example_8c-example}{ecore\+\_\+thread\+\_\+example.\+c}.\end{Desc}


References eina\+\_\+list\+\_\+count(), and E\+I\+N\+A\+\_\+\+M\+A\+I\+N\+\_\+\+L\+O\+O\+P\+\_\+\+C\+H\+E\+C\+K\+\_\+\+R\+E\+T\+U\+R\+N\+\_\+\+V\+AL.

\mbox{\Hypertarget{group__Ecore__Thread__Group_gaeaa014287d578a200d41cca861bceac3}\label{group__Ecore__Thread__Group_gaeaa014287d578a200d41cca861bceac3}} 
\index{Ecore Thread functions@{Ecore Thread functions}!ecore\+\_\+thread\+\_\+pending\+\_\+total\+\_\+get@{ecore\+\_\+thread\+\_\+pending\+\_\+total\+\_\+get}}
\index{ecore\+\_\+thread\+\_\+pending\+\_\+total\+\_\+get@{ecore\+\_\+thread\+\_\+pending\+\_\+total\+\_\+get}!Ecore Thread functions@{Ecore Thread functions}}
\subsubsection{\texorpdfstring{ecore\+\_\+thread\+\_\+pending\+\_\+total\+\_\+get()}{ecore\_thread\_pending\_total\_get()}}
{\footnotesize\ttfamily int ecore\+\_\+thread\+\_\+pending\+\_\+total\+\_\+get (\begin{DoxyParamCaption}\item[{void}]{ }\end{DoxyParamCaption})}



Gets the total number of pending jobs. 

\begin{DoxyReturn}{Returns}
Number of pending threads running jobs
\end{DoxyReturn}
Same as the sum of \hyperlink{group__Ecore__Thread__Group_ga3e32f650cfe811e69bba7825c71b9070}{ecore\+\_\+thread\+\_\+pending\+\_\+get()} and \hyperlink{group__Ecore__Thread__Group_gaa5c56445198f7b03c1f080039499689a}{ecore\+\_\+thread\+\_\+pending\+\_\+feedback\+\_\+get()}. \begin{Desc}
\item[Examples\+: ]\par
\hyperlink{ecore_thread_example_8c-example}{ecore\+\_\+thread\+\_\+example.\+c}.\end{Desc}


References eina\+\_\+list\+\_\+count(), and E\+I\+N\+A\+\_\+\+M\+A\+I\+N\+\_\+\+L\+O\+O\+P\+\_\+\+C\+H\+E\+C\+K\+\_\+\+R\+E\+T\+U\+R\+N\+\_\+\+V\+AL.

\mbox{\Hypertarget{group__Ecore__Thread__Group_gabad7972818b7fb1346ae7a098cd47220}\label{group__Ecore__Thread__Group_gabad7972818b7fb1346ae7a098cd47220}} 
\index{Ecore Thread functions@{Ecore Thread functions}!ecore\+\_\+thread\+\_\+max\+\_\+get@{ecore\+\_\+thread\+\_\+max\+\_\+get}}
\index{ecore\+\_\+thread\+\_\+max\+\_\+get@{ecore\+\_\+thread\+\_\+max\+\_\+get}!Ecore Thread functions@{Ecore Thread functions}}
\subsubsection{\texorpdfstring{ecore\+\_\+thread\+\_\+max\+\_\+get()}{ecore\_thread\_max\_get()}}
{\footnotesize\ttfamily int ecore\+\_\+thread\+\_\+max\+\_\+get (\begin{DoxyParamCaption}\item[{void}]{ }\end{DoxyParamCaption})}



Gets the maximum number of threads that can run simultaneously. 

\begin{DoxyReturn}{Returns}
Max possible number of Ecore\+\_\+\+Thread\textquotesingle{}s running concurrently
\end{DoxyReturn}
This returns the maximum number of Ecore\+\_\+\+Thread\textquotesingle{}s that may be running at the same time. If this number is reached, new jobs started by either \hyperlink{group__Ecore__Thread__Group_gaac9c9933ef0a90ba86f8fd0247e9c7ef}{ecore\+\_\+thread\+\_\+run()} or \hyperlink{group__Ecore__Thread__Group_ga4bde6b50e177f26ab5b2688aa99e3878}{ecore\+\_\+thread\+\_\+feedback\+\_\+run()} will be added to the respective pending queue until one of the running threads finishes its task and becomes available to run a new one.

By default, this will be the number of available C\+P\+Us for the running program (as returned by \hyperlink{group__Eina__Cpu__Group_ga34216ac673d316e4e9813d0f68a321f2}{eina\+\_\+cpu\+\_\+count()}), or 1 if this value could not be fetched.

\begin{DoxySeeAlso}{See also}
\hyperlink{group__Ecore__Thread__Group_gaaf965a46e0cc12857883806812af7693}{ecore\+\_\+thread\+\_\+max\+\_\+set()} 

\hyperlink{group__Ecore__Thread__Group_ga4324944541abf9f84861690b4ff66e18}{ecore\+\_\+thread\+\_\+max\+\_\+reset()} 
\end{DoxySeeAlso}
\begin{Desc}
\item[Examples\+: ]\par
\hyperlink{ecore_thread_example_8c-example}{ecore\+\_\+thread\+\_\+example.\+c}.\end{Desc}


References E\+I\+N\+A\+\_\+\+M\+A\+I\+N\+\_\+\+L\+O\+O\+P\+\_\+\+C\+H\+E\+C\+K\+\_\+\+R\+E\+T\+U\+R\+N\+\_\+\+V\+AL.

\mbox{\Hypertarget{group__Ecore__Thread__Group_gaaf965a46e0cc12857883806812af7693}\label{group__Ecore__Thread__Group_gaaf965a46e0cc12857883806812af7693}} 
\index{Ecore Thread functions@{Ecore Thread functions}!ecore\+\_\+thread\+\_\+max\+\_\+set@{ecore\+\_\+thread\+\_\+max\+\_\+set}}
\index{ecore\+\_\+thread\+\_\+max\+\_\+set@{ecore\+\_\+thread\+\_\+max\+\_\+set}!Ecore Thread functions@{Ecore Thread functions}}
\subsubsection{\texorpdfstring{ecore\+\_\+thread\+\_\+max\+\_\+set()}{ecore\_thread\_max\_set()}}
{\footnotesize\ttfamily void ecore\+\_\+thread\+\_\+max\+\_\+set (\begin{DoxyParamCaption}\item[{int}]{num }\end{DoxyParamCaption})}



Sets the maximum number of threads allowed to run simultaneously. 


\begin{DoxyParams}{Parameters}
{\em num} & The new maximum\\
\hline
\end{DoxyParams}
This sets a new value for the maximum number of concurrently running Ecore\+\_\+\+Thread\textquotesingle{}s. It {\bfseries must} an integer between 1 and (16 $\ast$ {\ttfamily x}), where {\ttfamily x} is the number for C\+P\+Us available.

\begin{DoxySeeAlso}{See also}
\hyperlink{group__Ecore__Thread__Group_gabad7972818b7fb1346ae7a098cd47220}{ecore\+\_\+thread\+\_\+max\+\_\+get()} 

\hyperlink{group__Ecore__Thread__Group_ga4324944541abf9f84861690b4ff66e18}{ecore\+\_\+thread\+\_\+max\+\_\+reset()} 
\end{DoxySeeAlso}
\begin{Desc}
\item[Examples\+: ]\par
\hyperlink{ecore_thread_example_8c-example}{ecore\+\_\+thread\+\_\+example.\+c}.\end{Desc}


References eina\+\_\+cpu\+\_\+count(), and E\+I\+N\+A\+\_\+\+M\+A\+I\+N\+\_\+\+L\+O\+O\+P\+\_\+\+C\+H\+E\+C\+K\+\_\+\+R\+E\+T\+U\+RN.

\mbox{\Hypertarget{group__Ecore__Thread__Group_ga4324944541abf9f84861690b4ff66e18}\label{group__Ecore__Thread__Group_ga4324944541abf9f84861690b4ff66e18}} 
\index{Ecore Thread functions@{Ecore Thread functions}!ecore\+\_\+thread\+\_\+max\+\_\+reset@{ecore\+\_\+thread\+\_\+max\+\_\+reset}}
\index{ecore\+\_\+thread\+\_\+max\+\_\+reset@{ecore\+\_\+thread\+\_\+max\+\_\+reset}!Ecore Thread functions@{Ecore Thread functions}}
\subsubsection{\texorpdfstring{ecore\+\_\+thread\+\_\+max\+\_\+reset()}{ecore\_thread\_max\_reset()}}
{\footnotesize\ttfamily void ecore\+\_\+thread\+\_\+max\+\_\+reset (\begin{DoxyParamCaption}\item[{void}]{ }\end{DoxyParamCaption})}



Resets the maximum number of concurrently running threads to the default. 

This resets the value returned by \hyperlink{group__Ecore__Thread__Group_gabad7972818b7fb1346ae7a098cd47220}{ecore\+\_\+thread\+\_\+max\+\_\+get()} back to its default.

\begin{DoxySeeAlso}{See also}
\hyperlink{group__Ecore__Thread__Group_gabad7972818b7fb1346ae7a098cd47220}{ecore\+\_\+thread\+\_\+max\+\_\+get()} 

\hyperlink{group__Ecore__Thread__Group_gaaf965a46e0cc12857883806812af7693}{ecore\+\_\+thread\+\_\+max\+\_\+set()} 
\end{DoxySeeAlso}


References eina\+\_\+cpu\+\_\+count(), and E\+I\+N\+A\+\_\+\+M\+A\+I\+N\+\_\+\+L\+O\+O\+P\+\_\+\+C\+H\+E\+C\+K\+\_\+\+R\+E\+T\+U\+RN.

\mbox{\Hypertarget{group__Ecore__Thread__Group_ga6e7703b3013d9c872449f6e2ec093b53}\label{group__Ecore__Thread__Group_ga6e7703b3013d9c872449f6e2ec093b53}} 
\index{Ecore Thread functions@{Ecore Thread functions}!ecore\+\_\+thread\+\_\+available\+\_\+get@{ecore\+\_\+thread\+\_\+available\+\_\+get}}
\index{ecore\+\_\+thread\+\_\+available\+\_\+get@{ecore\+\_\+thread\+\_\+available\+\_\+get}!Ecore Thread functions@{Ecore Thread functions}}
\subsubsection{\texorpdfstring{ecore\+\_\+thread\+\_\+available\+\_\+get()}{ecore\_thread\_available\_get()}}
{\footnotesize\ttfamily int ecore\+\_\+thread\+\_\+available\+\_\+get (\begin{DoxyParamCaption}\item[{void}]{ }\end{DoxyParamCaption})}



Gets the number of threads available for running tasks. 

\begin{DoxyReturn}{Returns}
The number of available threads
\end{DoxyReturn}
Same as doing \hyperlink{group__Ecore__Thread__Group_gabad7972818b7fb1346ae7a098cd47220}{ecore\+\_\+thread\+\_\+max\+\_\+get()} -\/ \hyperlink{group__Ecore__Thread__Group_gad7a28588dc26d6af8b6db8abc3ef37ce}{ecore\+\_\+thread\+\_\+active\+\_\+get()}.

This function may return a negative number only in the case the user changed the maximum number of running threads while other tasks are running. \begin{Desc}
\item[Examples\+: ]\par
\hyperlink{ecore_thread_example_8c-example}{ecore\+\_\+thread\+\_\+example.\+c}.\end{Desc}
\mbox{\Hypertarget{group__Ecore__Thread__Group_ga6878f550a9bcc8002c0c709b4b4dca66}\label{group__Ecore__Thread__Group_ga6878f550a9bcc8002c0c709b4b4dca66}} 
\index{Ecore Thread functions@{Ecore Thread functions}!ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+add@{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+add}}
\index{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+add@{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+add}!Ecore Thread functions@{Ecore Thread functions}}
\subsubsection{\texorpdfstring{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+add()}{ecore\_thread\_local\_data\_add()}}
{\footnotesize\ttfamily \hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\+\_\+\+Bool} ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+add (\begin{DoxyParamCaption}\item[{\hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} $\ast$}]{thread,  }\item[{const char $\ast$}]{key,  }\item[{void $\ast$}]{value,  }\item[{\hyperlink{group__Eina__Types__Group_gadbac560ba2bca5c61d97bfbb542018f3}{Eina\+\_\+\+Free\+\_\+\+Cb}}]{cb,  }\item[{\hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\+\_\+\+Bool}}]{direct }\end{DoxyParamCaption})}



Adds some data to a hash local to the thread. 


\begin{DoxyParams}{Parameters}
{\em thread} & The thread context the data belongs to \\
\hline
{\em key} & The name under which the data will be stored \\
\hline
{\em value} & The data to add \\
\hline
{\em cb} & Function to free the data when removed from the hash \\
\hline
{\em direct} & If true, this will not copy the key string (like \hyperlink{group__Eina__Hash__Group_ga50aa7d4303e5efbe8dc7f593b59b9f63}{eina\+\_\+hash\+\_\+direct\+\_\+add()}) \\
\hline
\end{DoxyParams}
\begin{DoxyReturn}{Returns}
{\ttfamily E\+I\+N\+A\+\_\+\+T\+R\+UE} on success, {\ttfamily E\+I\+N\+A\+\_\+\+F\+A\+L\+SE} on failure.
\end{DoxyReturn}
Ecore Thread has a mechanism to share data across several worker functions that run on the same system thread. That is, the data is stored per thread and for a worker function to have access to it, it must be run by the same thread that stored the data.

When there are no more workers pending, the thread will be destroyed along with the internal hash and any data left in it will be freed with the {\ttfamily cb} function given.

This set of functions is useful to share things around several instances of a function when that thing is costly to create and can be reused, but may only be used by one function at a time.

For example, if you have a program doing requisitions to a database, these requisitions can be done in threads so that waiting for the database to respond doesn\textquotesingle{}t block the UI. Each of these threads will run a function, and each function will be dependent on a connection to the database, which may not be able to handle more than one request at a time so for each running function you will need one connection handle. The options then are\+: \begin{DoxyItemize}
\item Each function opens a connection when it\textquotesingle{}s called, does the work and closes the connection when it finishes. This may be costly, wasting a lot of time on resolving hostnames, negotiating permissions and allocating memory. \item Open the connections in the main loop and pass it to the threads using the data pointer. Even worse, it\textquotesingle{}s just as costly as before and now it may even be kept with connections open doing nothing until a thread becomes available to run the function. \item Have a way to share connection handles, so that each instance of the function can check if an available connection exists, and if it doesn\textquotesingle{}t, create one and add it to the pool. When no more connections are needed, they are all closed.\end{DoxyItemize}
The last option is the most efficient, but it requires a lot of work to implement properly. Using thread local data helps to achieve the same result while avoiding doing all the tracking work on your code. The way to use it would be, at the worker function, to ask for the connection with \hyperlink{group__Ecore__Thread__Group_ga1a937d674f1a20162b31b95d0ed100ad}{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+find()} and if it doesn\textquotesingle{}t exist, then open a new one and save it with \hyperlink{group__Ecore__Thread__Group_ga6878f550a9bcc8002c0c709b4b4dca66}{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+add()}. Do the work and forget about the connection handle, when everything is done the function just ends. The next worker to run on that thread will check if a connection exists and find that it does, so the process of opening a new one has been spared. When no more workers exist, the thread is destroyed and the callback used when saving the connection will be called to close it.

This function adds the data {\ttfamily value} to the thread data under the given {\ttfamily key}. No other value in the hash may have the same {\ttfamily key}. If you need to change the value under a {\ttfamily key}, or you don\textquotesingle{}t know if one exists already, you can use \hyperlink{group__Ecore__Thread__Group_ga56a7d8c062f5c42fbc338c9ded4da453}{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+set()}.

Neither {\ttfamily key} nor {\ttfamily value} may be {\ttfamily N\+U\+LL} and {\ttfamily key} will be copied in the hash, unless {\ttfamily direct} is set, in which case the string used should not be freed until the data is removed from the hash.

The {\ttfamily cb} function will be called when the data in the hash needs to be freed, be it because it got deleted with \hyperlink{group__Ecore__Thread__Group_gad3c1d51a24772b885b26486be86c2779}{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+del()} or because {\ttfamily thread} was terminated and the hash destroyed. This parameter may be N\+U\+LL, in which case {\ttfamily value} needs to be manually freed after removing it from the hash with either \hyperlink{group__Ecore__Thread__Group_gad3c1d51a24772b885b26486be86c2779}{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+del()} or \hyperlink{group__Ecore__Thread__Group_ga56a7d8c062f5c42fbc338c9ded4da453}{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+set()}, but it\textquotesingle{}s very unlikely that this is what you want.

This function, and all of the others in the {\ttfamily ecore\+\_\+thread\+\_\+local\+\_\+data} family of functions, can only be called within the worker function running in the thread. Do not call them from the main loop or from a thread other than the one represented by {\ttfamily thread}.

\begin{DoxySeeAlso}{See also}
\hyperlink{group__Ecore__Thread__Group_ga56a7d8c062f5c42fbc338c9ded4da453}{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+set()} 

\hyperlink{group__Ecore__Thread__Group_ga1a937d674f1a20162b31b95d0ed100ad}{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+find()} 

\hyperlink{group__Ecore__Thread__Group_gad3c1d51a24772b885b26486be86c2779}{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+del()} 
\end{DoxySeeAlso}
\begin{Desc}
\item[Examples\+: ]\par
\hyperlink{ecore_thread_example_8c-example}{ecore\+\_\+thread\+\_\+example.\+c}.\end{Desc}


References E\+I\+N\+A\+\_\+\+F\+A\+L\+SE, eina\+\_\+hash\+\_\+add(), eina\+\_\+hash\+\_\+direct\+\_\+add(), and eina\+\_\+hash\+\_\+string\+\_\+small\+\_\+new().

\mbox{\Hypertarget{group__Ecore__Thread__Group_ga56a7d8c062f5c42fbc338c9ded4da453}\label{group__Ecore__Thread__Group_ga56a7d8c062f5c42fbc338c9ded4da453}} 
\index{Ecore Thread functions@{Ecore Thread functions}!ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+set@{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+set}}
\index{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+set@{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+set}!Ecore Thread functions@{Ecore Thread functions}}
\subsubsection{\texorpdfstring{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+set()}{ecore\_thread\_local\_data\_set()}}
{\footnotesize\ttfamily void$\ast$ ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+set (\begin{DoxyParamCaption}\item[{\hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} $\ast$}]{thread,  }\item[{const char $\ast$}]{key,  }\item[{void $\ast$}]{value,  }\item[{\hyperlink{group__Eina__Types__Group_gadbac560ba2bca5c61d97bfbb542018f3}{Eina\+\_\+\+Free\+\_\+\+Cb}}]{cb }\end{DoxyParamCaption})}



Sets some data in the hash local to the given thread. 


\begin{DoxyParams}{Parameters}
{\em thread} & The thread context the data belongs to \\
\hline
{\em key} & The name under which the data will be stored \\
\hline
{\em value} & The data to add \\
\hline
{\em cb} & Function to free the data when removed from the hash\\
\hline
\end{DoxyParams}
If no data exists in the hash under the {\ttfamily key}, this function adds {\ttfamily value} in the hash under the given {\ttfamily key} and returns N\+U\+LL. The key itself is copied.

If the hash already contains something under {\ttfamily key}, the data will be replaced by {\ttfamily value} and the old value will be returned.

{\ttfamily N\+U\+LL} will also be returned if either {\ttfamily key} or {\ttfamily value} are {\ttfamily N\+U\+LL}, or if an error occurred.

This function, and all of the others in the {\ttfamily ecore\+\_\+thread\+\_\+local\+\_\+data} family of functions, can only be called within the worker function running in the thread. Do not call them from the main loop or from a thread other than the one represented by {\ttfamily thread}.

\begin{DoxySeeAlso}{See also}
\hyperlink{group__Ecore__Thread__Group_ga6878f550a9bcc8002c0c709b4b4dca66}{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+add()} 

\hyperlink{group__Ecore__Thread__Group_gad3c1d51a24772b885b26486be86c2779}{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+del()} 

\hyperlink{group__Ecore__Thread__Group_ga1a937d674f1a20162b31b95d0ed100ad}{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+find()} 
\end{DoxySeeAlso}


References eina\+\_\+hash\+\_\+set(), and eina\+\_\+hash\+\_\+string\+\_\+small\+\_\+new().

\mbox{\Hypertarget{group__Ecore__Thread__Group_ga1a937d674f1a20162b31b95d0ed100ad}\label{group__Ecore__Thread__Group_ga1a937d674f1a20162b31b95d0ed100ad}} 
\index{Ecore Thread functions@{Ecore Thread functions}!ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+find@{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+find}}
\index{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+find@{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+find}!Ecore Thread functions@{Ecore Thread functions}}
\subsubsection{\texorpdfstring{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+find()}{ecore\_thread\_local\_data\_find()}}
{\footnotesize\ttfamily void$\ast$ ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+find (\begin{DoxyParamCaption}\item[{\hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} $\ast$}]{thread,  }\item[{const char $\ast$}]{key }\end{DoxyParamCaption})}



Gets data stored in the hash local to the given thread. 


\begin{DoxyParams}{Parameters}
{\em thread} & The thread context the data belongs to \\
\hline
{\em key} & The name under which the data is stored \\
\hline
\end{DoxyParams}
\begin{DoxyReturn}{Returns}
The value under the given key, or {\ttfamily N\+U\+LL} on error.
\end{DoxyReturn}
Finds and return the data stored in the shared hash under the key {\ttfamily key}.

This function, and all of the others in the {\ttfamily ecore\+\_\+thread\+\_\+local\+\_\+data} family of functions, can only be called within the worker function running in the thread. Do not call them from the main loop or from a thread other than the one represented by {\ttfamily thread}.

\begin{DoxySeeAlso}{See also}
\hyperlink{group__Ecore__Thread__Group_ga6878f550a9bcc8002c0c709b4b4dca66}{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+add()} 

ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+wait() 
\end{DoxySeeAlso}
\begin{Desc}
\item[Examples\+: ]\par
\hyperlink{ecore_thread_example_8c-example}{ecore\+\_\+thread\+\_\+example.\+c}.\end{Desc}


References eina\+\_\+hash\+\_\+find().

\mbox{\Hypertarget{group__Ecore__Thread__Group_gad3c1d51a24772b885b26486be86c2779}\label{group__Ecore__Thread__Group_gad3c1d51a24772b885b26486be86c2779}} 
\index{Ecore Thread functions@{Ecore Thread functions}!ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+del@{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+del}}
\index{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+del@{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+del}!Ecore Thread functions@{Ecore Thread functions}}
\subsubsection{\texorpdfstring{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+del()}{ecore\_thread\_local\_data\_del()}}
{\footnotesize\ttfamily \hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\+\_\+\+Bool} ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+del (\begin{DoxyParamCaption}\item[{\hyperlink{group__Ecore__Thread__Group_ga0c2e1f8d562ccf80ecc0009ada72496f}{Ecore\+\_\+\+Thread} $\ast$}]{thread,  }\item[{const char $\ast$}]{key }\end{DoxyParamCaption})}



Deletes from the thread\textquotesingle{}s hash the data corresponding to the given key. 


\begin{DoxyParams}{Parameters}
{\em thread} & The thread context the data belongs to \\
\hline
{\em key} & The name under which the data is stored \\
\hline
\end{DoxyParams}
\begin{DoxyReturn}{Returns}
{\ttfamily E\+I\+N\+A\+\_\+\+T\+R\+UE} on success, {\ttfamily E\+I\+N\+A\+\_\+\+F\+A\+L\+SE} on failure.
\end{DoxyReturn}
If there\textquotesingle{}s any data stored associated with {\ttfamily key} in the global hash, this function will remove it from it and return {\ttfamily E\+I\+N\+A\+\_\+\+T\+R\+UE}. If no data exists or an error occurs, it returns {\ttfamily E\+I\+N\+A\+\_\+\+F\+A\+L\+SE}.

If the data was added to the hash with a free function, then it will also be freed after removing it from the hash, otherwise it requires to be manually freed by the user, which means that if no other reference to it exists before calling this function, it will result in a memory leak.

This function, and all of the others in the {\ttfamily ecore\+\_\+thread\+\_\+local\+\_\+data} family of functions, can only be called within the worker function running in the thread. Do not call them from the main loop or from a thread other than the one represented by {\ttfamily thread}.

\begin{DoxySeeAlso}{See also}
\hyperlink{group__Ecore__Thread__Group_ga6878f550a9bcc8002c0c709b4b4dca66}{ecore\+\_\+thread\+\_\+local\+\_\+data\+\_\+add()} 
\end{DoxySeeAlso}
\begin{Desc}
\item[Examples\+: ]\par
\hyperlink{ecore_thread_example_8c-example}{ecore\+\_\+thread\+\_\+example.\+c}.\end{Desc}


References E\+I\+N\+A\+\_\+\+F\+A\+L\+SE, and eina\+\_\+hash\+\_\+del\+\_\+by\+\_\+key().

\mbox{\Hypertarget{group__Ecore__Thread__Group_ga4e9de7492f8400e19ddd157d8cc21811}\label{group__Ecore__Thread__Group_ga4e9de7492f8400e19ddd157d8cc21811}} 
\index{Ecore Thread functions@{Ecore Thread functions}!ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+add@{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+add}}
\index{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+add@{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+add}!Ecore Thread functions@{Ecore Thread functions}}
\subsubsection{\texorpdfstring{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+add()}{ecore\_thread\_global\_data\_add()}}
{\footnotesize\ttfamily \hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\+\_\+\+Bool} ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+add (\begin{DoxyParamCaption}\item[{const char $\ast$}]{key,  }\item[{void $\ast$}]{value,  }\item[{\hyperlink{group__Eina__Types__Group_gadbac560ba2bca5c61d97bfbb542018f3}{Eina\+\_\+\+Free\+\_\+\+Cb}}]{cb,  }\item[{\hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\+\_\+\+Bool}}]{direct }\end{DoxyParamCaption})}



Adds some data to a hash shared by all threads. 


\begin{DoxyParams}{Parameters}
{\em key} & The name under which the data will be stored \\
\hline
{\em value} & The data to add \\
\hline
{\em cb} & Function to free the data when removed from the hash \\
\hline
{\em direct} & If true, this will not copy the key string (like \hyperlink{group__Eina__Hash__Group_ga50aa7d4303e5efbe8dc7f593b59b9f63}{eina\+\_\+hash\+\_\+direct\+\_\+add()}) \\
\hline
\end{DoxyParams}
\begin{DoxyReturn}{Returns}
{\ttfamily E\+I\+N\+A\+\_\+\+T\+R\+UE} on success, {\ttfamily E\+I\+N\+A\+\_\+\+F\+A\+L\+SE} on failure.
\end{DoxyReturn}
Ecore Thread keeps a hash that can be used to share data across several threads, including the main loop one, without having to manually handle mutexes to do so safely.

This function adds the data {\ttfamily value} to this hash under the given {\ttfamily key}. No other value in the hash may have the same {\ttfamily key}. If you need to change the value under a {\ttfamily key}, or you don\textquotesingle{}t know if one exists already, you can use \hyperlink{group__Ecore__Thread__Group_gace0bfd51f1dceef9d66f620bcffccabd}{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+set()}.

Neither {\ttfamily key} nor {\ttfamily value} may be {\ttfamily N\+U\+LL} and {\ttfamily key} will be copied in the hash, unless {\ttfamily direct} is set, in which case the string used should not be freed until the data is removed from the hash.

The {\ttfamily cb} function will be called when the data in the hash needs to be freed, be it because it got deleted with \hyperlink{group__Ecore__Thread__Group_ga8e53feb974331550744cbc2e40dc9132}{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+del()} or because Ecore Thread was shut down and the hash destroyed. This parameter may be N\+U\+LL, in which case {\ttfamily value} needs to be manually freed after removing it from the hash with either \hyperlink{group__Ecore__Thread__Group_ga8e53feb974331550744cbc2e40dc9132}{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+del()} or \hyperlink{group__Ecore__Thread__Group_gace0bfd51f1dceef9d66f620bcffccabd}{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+set()}.

Manually freeing any data that was added to the hash with a {\ttfamily cb} function is likely to produce a segmentation fault, or any other strange happenings, later on in the program.

\begin{DoxySeeAlso}{See also}
\hyperlink{group__Ecore__Thread__Group_ga8e53feb974331550744cbc2e40dc9132}{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+del()} 

\hyperlink{group__Ecore__Thread__Group_gace0bfd51f1dceef9d66f620bcffccabd}{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+set()} 

\hyperlink{group__Ecore__Thread__Group_ga011eeb2f99aaa950089ddc6ea989da29}{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+find()} 
\end{DoxySeeAlso}
\begin{Desc}
\item[Examples\+: ]\par
\hyperlink{ecore_thread_example_8c-example}{ecore\+\_\+thread\+\_\+example.\+c}.\end{Desc}


References E\+I\+N\+A\+\_\+\+F\+A\+L\+SE, eina\+\_\+hash\+\_\+add(), eina\+\_\+hash\+\_\+direct\+\_\+add(), and eina\+\_\+hash\+\_\+string\+\_\+small\+\_\+new().

\mbox{\Hypertarget{group__Ecore__Thread__Group_gace0bfd51f1dceef9d66f620bcffccabd}\label{group__Ecore__Thread__Group_gace0bfd51f1dceef9d66f620bcffccabd}} 
\index{Ecore Thread functions@{Ecore Thread functions}!ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+set@{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+set}}
\index{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+set@{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+set}!Ecore Thread functions@{Ecore Thread functions}}
\subsubsection{\texorpdfstring{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+set()}{ecore\_thread\_global\_data\_set()}}
{\footnotesize\ttfamily void$\ast$ ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+set (\begin{DoxyParamCaption}\item[{const char $\ast$}]{key,  }\item[{void $\ast$}]{value,  }\item[{\hyperlink{group__Eina__Types__Group_gadbac560ba2bca5c61d97bfbb542018f3}{Eina\+\_\+\+Free\+\_\+\+Cb}}]{cb }\end{DoxyParamCaption})}



Sets some data in the hash shared by all threads. 


\begin{DoxyParams}{Parameters}
{\em key} & The name under which the data will be stored \\
\hline
{\em value} & The data to add \\
\hline
{\em cb} & Function to free the data when removed from the hash\\
\hline
\end{DoxyParams}
If no data exists in the hash under the {\ttfamily key}, this function adds {\ttfamily value} in the hash under the given {\ttfamily key} and returns N\+U\+LL. The key itself is copied.

If the hash already contains something under {\ttfamily key}, the data will be replaced by {\ttfamily value} and the old value will be returned.

{\ttfamily N\+U\+LL} will also be returned if either {\ttfamily key} or {\ttfamily value} are {\ttfamily N\+U\+LL}, or if an error occurred.

\begin{DoxySeeAlso}{See also}
\hyperlink{group__Ecore__Thread__Group_ga4e9de7492f8400e19ddd157d8cc21811}{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+add()} 

\hyperlink{group__Ecore__Thread__Group_ga8e53feb974331550744cbc2e40dc9132}{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+del()} 

\hyperlink{group__Ecore__Thread__Group_ga011eeb2f99aaa950089ddc6ea989da29}{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+find()} 
\end{DoxySeeAlso}


References eina\+\_\+hash\+\_\+set(), and eina\+\_\+hash\+\_\+string\+\_\+small\+\_\+new().

\mbox{\Hypertarget{group__Ecore__Thread__Group_ga011eeb2f99aaa950089ddc6ea989da29}\label{group__Ecore__Thread__Group_ga011eeb2f99aaa950089ddc6ea989da29}} 
\index{Ecore Thread functions@{Ecore Thread functions}!ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+find@{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+find}}
\index{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+find@{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+find}!Ecore Thread functions@{Ecore Thread functions}}
\subsubsection{\texorpdfstring{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+find()}{ecore\_thread\_global\_data\_find()}}
{\footnotesize\ttfamily void$\ast$ ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+find (\begin{DoxyParamCaption}\item[{const char $\ast$}]{key }\end{DoxyParamCaption})}



Gets data stored in the hash shared by all threads. 


\begin{DoxyParams}{Parameters}
{\em key} & The name under which the data is stored \\
\hline
\end{DoxyParams}
\begin{DoxyReturn}{Returns}
The value under the given key, or {\ttfamily N\+U\+LL} on error.
\end{DoxyReturn}
Finds and return the data stored in the shared hash under the key {\ttfamily key}.

Keep in mind that the data returned may be used by more than one thread at the same time and no reference counting is done on it by Ecore. Freeing the data or modifying its contents may require additional precautions to be considered, depending on the application\textquotesingle{}s design.

\begin{DoxySeeAlso}{See also}
\hyperlink{group__Ecore__Thread__Group_ga4e9de7492f8400e19ddd157d8cc21811}{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+add()} 

\hyperlink{group__Ecore__Thread__Group_ga910b00728b8b0201677f7a09e8d44896}{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+wait()} 
\end{DoxySeeAlso}
\begin{Desc}
\item[Examples\+: ]\par
\hyperlink{ecore_thread_example_8c-example}{ecore\+\_\+thread\+\_\+example.\+c}.\end{Desc}


References eina\+\_\+hash\+\_\+find().

\mbox{\Hypertarget{group__Ecore__Thread__Group_ga8e53feb974331550744cbc2e40dc9132}\label{group__Ecore__Thread__Group_ga8e53feb974331550744cbc2e40dc9132}} 
\index{Ecore Thread functions@{Ecore Thread functions}!ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+del@{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+del}}
\index{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+del@{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+del}!Ecore Thread functions@{Ecore Thread functions}}
\subsubsection{\texorpdfstring{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+del()}{ecore\_thread\_global\_data\_del()}}
{\footnotesize\ttfamily \hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\+\_\+\+Bool} ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+del (\begin{DoxyParamCaption}\item[{const char $\ast$}]{key }\end{DoxyParamCaption})}



Deletes from the shared hash the data corresponding to the given key. 


\begin{DoxyParams}{Parameters}
{\em key} & The name under which the data is stored \\
\hline
\end{DoxyParams}
\begin{DoxyReturn}{Returns}
{\ttfamily E\+I\+N\+A\+\_\+\+T\+R\+UE} on success, {\ttfamily E\+I\+N\+A\+\_\+\+F\+A\+L\+SE} on failure.
\end{DoxyReturn}
If there\textquotesingle{}s any data stored associated with {\ttfamily key} in the global hash, this function will remove it from it and return {\ttfamily E\+I\+N\+A\+\_\+\+T\+R\+UE}. If no data exists or an error occurs, it returns {\ttfamily E\+I\+N\+A\+\_\+\+F\+A\+L\+SE}.

If the data was added to the hash with a free function, then it will also be freed after removing it from the hash, otherwise it requires to be manually freed by the user, which means that if no other reference to it exists before calling this function, it will result in a memory leak.

Note, also, that freeing data that other threads may be using will result in a crash, so appropriate care must be taken by the application when that possibility exists.

\begin{DoxySeeAlso}{See also}
\hyperlink{group__Ecore__Thread__Group_ga4e9de7492f8400e19ddd157d8cc21811}{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+add()} 
\end{DoxySeeAlso}
\begin{Desc}
\item[Examples\+: ]\par
\hyperlink{ecore_thread_example_8c-example}{ecore\+\_\+thread\+\_\+example.\+c}.\end{Desc}


References E\+I\+N\+A\+\_\+\+F\+A\+L\+SE, and eina\+\_\+hash\+\_\+del\+\_\+by\+\_\+key().

\mbox{\Hypertarget{group__Ecore__Thread__Group_ga910b00728b8b0201677f7a09e8d44896}\label{group__Ecore__Thread__Group_ga910b00728b8b0201677f7a09e8d44896}} 
\index{Ecore Thread functions@{Ecore Thread functions}!ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+wait@{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+wait}}
\index{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+wait@{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+wait}!Ecore Thread functions@{Ecore Thread functions}}
\subsubsection{\texorpdfstring{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+wait()}{ecore\_thread\_global\_data\_wait()}}
{\footnotesize\ttfamily void$\ast$ ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+wait (\begin{DoxyParamCaption}\item[{const char $\ast$}]{key,  }\item[{double}]{seconds }\end{DoxyParamCaption})}



Gets data stored in the shared hash, or wait for it if it doesn\textquotesingle{}t exist. 


\begin{DoxyParams}{Parameters}
{\em key} & The name under which the data is stored \\
\hline
{\em seconds} & The amount of time in seconds to wait for the data. \\
\hline
\end{DoxyParams}
\begin{DoxyReturn}{Returns}
The value under the given key, or {\ttfamily N\+U\+LL} on error.
\end{DoxyReturn}
Finds and return the data stored in the shared hash under the key {\ttfamily key}.

If there\textquotesingle{}s nothing in the hash under the given {\ttfamily key}, the function will block and wait up to {\ttfamily seconds} seconds for some other thread to add it with either \hyperlink{group__Ecore__Thread__Group_ga4e9de7492f8400e19ddd157d8cc21811}{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+add()} or \hyperlink{group__Ecore__Thread__Group_gace0bfd51f1dceef9d66f620bcffccabd}{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+set()}. If after waiting there\textquotesingle{}s still no data to get, {\ttfamily N\+U\+LL} will be returned.

If {\ttfamily seconds} is 0, then no waiting will happen and this function works like \hyperlink{group__Ecore__Thread__Group_ga011eeb2f99aaa950089ddc6ea989da29}{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+find()}. If {\ttfamily seconds} is less than 0, then the function will wait indefinitely.

Keep in mind that the data returned may be used by more than one thread at the same time and no reference counting is done on it by Ecore. Freeing the data or modifying its contents may require additional precautions to be considered, depending on the application\textquotesingle{}s design.

\begin{DoxySeeAlso}{See also}
\hyperlink{group__Ecore__Thread__Group_ga4e9de7492f8400e19ddd157d8cc21811}{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+add()} 

\hyperlink{group__Ecore__Thread__Group_ga011eeb2f99aaa950089ddc6ea989da29}{ecore\+\_\+thread\+\_\+global\+\_\+data\+\_\+find()} 
\end{DoxySeeAlso}


References ecore\+\_\+time\+\_\+get(), and eina\+\_\+hash\+\_\+find().

