Eina_Bool cancel : 1;
Eina_Bool feedback_run : 1;
Eina_Bool kill : 1;
+ Eina_Bool reschedule : 1;
};
#ifdef EFL_HAVE_THREADS
if (!work->cancel)
work->u.short_run.func_blocking((void *) work->data, (Ecore_Thread*) work);
- ecore_pipe_write(end_pipe, &work, sizeof (Ecore_Pthread_Worker *));
+ if (work->reschedule)
+ {
+ work->reschedule = EINA_FALSE;
+
+ LKL(_ecore_pending_job_threads_mutex);
+ _ecore_pending_job_threads = eina_list_append(_ecore_pending_job_threads, work);
+ LKU(_ecore_pending_job_threads_mutex);
+ }
+ else
+ {
+ ecore_pipe_write(end_pipe, &work, sizeof (Ecore_Pthread_Worker *));
+ }
}
}
if (!work->cancel)
work->u.feedback_run.func_heavy((void *) work->data, (Ecore_Thread *) work);
- ecore_pipe_write(end_pipe, &work, sizeof (Ecore_Pthread_Worker *));
+ if (work->reschedule)
+ {
+ work->reschedule = EINA_FALSE;
+
+ LKL(_ecore_pending_job_threads_mutex);
+ _ecore_pending_job_threads_feedback = eina_list_append(_ecore_pending_job_threads_feedback, work);
+ LKU(_ecore_pending_job_threads_mutex);
+ }
+ else
+ {
+ ecore_pipe_write(end_pipe, &work, sizeof (Ecore_Pthread_Worker *));
+ }
}
}
work->cancel = EINA_FALSE;
work->feedback_run = EINA_FALSE;
work->kill = EINA_FALSE;
+ work->reschedule = EINA_FALSE;
work->data = data;
#ifdef EFL_HAVE_THREADS
If no thread and as we don't want to break app that rely on this
facility, we will lock the interface until we are done.
*/
- func_blocking((void *)data, (Ecore_Thread *) work);
- if (work->cancel == EINA_FALSE) func_end((void *)data, (Ecore_Thread *) work);
- else func_end((void *)data, (Ecore_Thread *) work);
+ do {
+ /* Handle reschedule by forcing it here. That would mean locking the app,
+ * would be better with an idler, but really to complex for a case where
+ * thread should really exist.
+ */
+ work->reschedule = EINA_FALSE;
+
+ func_blocking((void *)data, (Ecore_Thread *) work);
+ if (work->cancel == EINA_FALSE) func_end((void *)data, (Ecore_Thread *) work);
+ else func_end((void *)data, (Ecore_Thread *) work);
+
+ } while (work->reschedule == EINA_TRUE);
free(work);
* parallel thread. You should provide four functions. The first one, func_heavy,
* that will do the heavy work in another thread (so you should not use the
* EFL in it except Eina and Eet if you are careful). The second one, func_notify,
- * will receive the data send from the thread function (func_heavy) by ecore_thread_notify
+ * will receive the data send from the thread function (func_heavy) by ecore_thread_feedback
* in the main loop (and so, can use all the EFL). The third, func_end,
* that will be called in Ecore main loop when func_heavy is done. So you
* can use all the EFL inside this function. The last one, func_cancel, will
worker->cancel = EINA_FALSE;
worker->feedback_run = EINA_TRUE;
worker->kill = EINA_FALSE;
+ worker->reschedule = EINA_FALSE;
+
worker->u.feedback_run.send = 0;
worker->u.feedback_run.received = 0;
worker.feedback_run = EINA_TRUE;
worker.kill = EINA_FALSE;
- func_heavy((void *)data, (Ecore_Thread *) &worker);
+ do {
+ worker.reschedule = EINA_FALSE;
- if (worker.cancel) func_cancel((void *)data, (Ecore_Thread *) &worker);
- else func_end((void *)data, (Ecore_Thread *) &worker);
+ func_heavy((void *)data, (Ecore_Thread *) &worker);
+
+ if (worker.cancel) func_cancel((void *)data, (Ecore_Thread *) &worker);
+ else func_end((void *)data, (Ecore_Thread *) &worker);
+ } while (worker.reschedule == EINA_FALSE);
return NULL;
#endif
}
/**
+ * @brief Plan to recall the heavy function once it exist it.
+ * @param thread The current Ecore_Thread context to reschedule
+ * @return EINA_TRUE if data was successfully send to main loop,
+ * EINA_FALSE if anything goes wrong.
+ *
+ * After a succesfull call, you can still do what you want in your thread, it
+ * will only reschedule it once you exit the heavy loop.
+ *
+ * You should use this function only in the func_heavy call.
+ */
+EAPI Eina_Bool
+ecore_thread_reschedule(Ecore_Thread *thread)
+{
+ Ecore_Pthread_Worker *worker = (Ecore_Pthread_Worker *) thread;
+
+ if (!worker) return EINA_FALSE;
+
+#ifdef EFL_HAVE_THREADS
+ if (!PHE(worker->self, PHS())) return EINA_FALSE;
+#endif
+
+ worker->reschedule = EINA_TRUE;
+ return EINA_TRUE;
+}
+
+/**
* @brief Get number of active thread jobs
* @return Number of active threads running jobs
* This returns the number of threads currently running jobs through the