Ecore_Thread_Heavy_Cb func_heavy;
Ecore_Thread_Notify_Cb func_notify;
Ecore_Pipe *notify;
+
+ int send;
+ int received;
} feedback_run;
} u;
-
+
Ecore_Cb func_cancel;
Ecore_Cb func_end;
#ifdef EFL_HAVE_PTHREAD
pthread_cond_t cond;
pthread_mutex_t mutex;
#endif
-
+
const void *data;
-
+
Eina_Bool cancel : 1;
Eina_Bool feedback_run : 1;
+ Eina_Bool kill : 1;
};
#ifdef EFL_HAVE_PTHREAD
}
static void
-_ecore_thread_handler(void *data __UNUSED__, void *buffer, unsigned int nbyte)
+_ecore_thread_kill(Ecore_Pthread_Worker *work)
{
- Ecore_Pthread_Worker *work;
-
- if (nbyte != sizeof (Ecore_Pthread_Worker *)) return ;
-
- work = *(Ecore_Pthread_Worker **)buffer;
-
if (work->cancel)
{
if (work->func_cancel)
}
if (work->feedback_run)
- ecore_pipe_del(work->u.feedback_run.notify);
+ ecore_pipe_del(work->u.feedback_run.notify);
pthread_cond_destroy(&work->cond);
pthread_mutex_destroy(&work->mutex);
if (work->hash)
}
static void
+_ecore_thread_handler(void *data __UNUSED__, void *buffer, unsigned int nbyte)
+{
+ Ecore_Pthread_Worker *work;
+
+ if (nbyte != sizeof (Ecore_Pthread_Worker *)) return ;
+
+ work = *(Ecore_Pthread_Worker **)buffer;
+
+ if (work->feedback_run)
+ {
+ if (work->u.feedback_run.send != work->u.feedback_run.received)
+ {
+ work->kill = EINA_TRUE;
+ return ;
+ }
+ }
+
+ _ecore_thread_kill(work);
+}
+
+static void
_ecore_notify_handler(void *data, void *buffer, unsigned int nbyte)
{
Ecore_Pthread_Worker *work = data;
if (nbyte != sizeof (Ecore_Pthread_Worker *)) return ;
user_data = *(void **)buffer;
+ work->u.feedback_run.received++;
if (work->u.feedback_run.func_notify)
work->u.feedback_run.func_notify((Ecore_Thread *) work, user_data, (void *) work->data);
+
+ /* Force reading all notify event before killing the thread */
+ if (work->kill && work->u.feedback_run.send == work->u.feedback_run.received)
+ {
+ _ecore_thread_kill(work);
+ }
}
static void
work->func_cancel = NULL;
work->cancel = EINA_FALSE;
work->feedback_run = EINA_FALSE;
+ work->kill = EINA_FALSE;
work->hash = NULL;
pthread_cond_init(&work->cond, NULL);
pthread_mutex_init(&work->mutex, NULL);
work->func_cancel = NULL;
work->cancel = EINA_FALSE;
work->feedback_run = EINA_FALSE;
+ work->kill = EINA_FALSE;
work->hash = NULL;
pthread_cond_init(&work->cond, NULL);
pthread_mutex_init(&work->mutex, NULL);
work->func_cancel = func_cancel;
work->cancel = EINA_FALSE;
work->feedback_run = EINA_FALSE;
+ work->kill = EINA_FALSE;
work->data = data;
pthread_mutex_lock(&_ecore_pending_job_threads_mutex);
if (work->cancel)
return EINA_FALSE;
+ if (work->feedback_run)
+ {
+ if (work->kill)
+ return EINA_TRUE;
+ if (work->u.feedback_run.send != work->u.feedback_run.received)
+ goto on_exit;
+ }
+
pthread_mutex_lock(&_ecore_pending_job_threads_mutex);
if ((have_main_loop_thread) &&
pthread_mutex_unlock(&_ecore_pending_job_threads_mutex);
/* Delay the destruction */
- ((Ecore_Pthread_Worker *)thread)->cancel = EINA_TRUE;
+ on_exit:
+ work->cancel = EINA_TRUE;
return EINA_FALSE;
#else
return EINA_TRUE;
worker->data = data;
worker->cancel = EINA_FALSE;
worker->feedback_run = EINA_TRUE;
+ worker->kill = EINA_FALSE;
+ worker->u.feedback_run.send = 0;
+ worker->u.feedback_run.received = 0;
worker->u.feedback_run.notify = ecore_pipe_add(_ecore_notify_handler, worker);
worker.u.feedback_run.func_heavy = func_heavy;
worker.u.feedback_run.func_notify = func_notify;
worker.u.feedback_run.notify = NULL;
+ worker.u.feedback_run.send = 0;
+ worker.u.feedback_run.received = 0;
worker.func_cancel = func_cancel;
worker.func_end = func_end;
worker.data = data;
worker.cancel = EINA_FALSE;
worker.feedback_run = EINA_TRUE;
+ worker.kill = EINA_FALSE;
func_heavy((Ecore_Thread *) &worker, (void *)data);
#ifdef EFL_HAVE_PTHREAD
if (!pthread_equal(worker->self, pthread_self())) return EINA_FALSE;
+ worker->u.feedback_run.send++;
ecore_pipe_write(worker->u.feedback_run.notify, &data, sizeof (void *));
return EINA_TRUE;