Matthieu Baerts has proposed merging lp:~matttbe/cairo-dock-core/task-one-thread-async-2 into lp:cairo-dock-core.
Requested reviews: Fabounet (fabounet03) For more details, see: https://code.launchpad.net/~matttbe/cairo-dock-core/task-one-thread-async-2/+merge/119282 Hello, The same as the previous one but now with the use of g_idle_add function. -- https://code.launchpad.net/~matttbe/cairo-dock-core/task-one-thread-async-2/+merge/119282 Your team Cairo-Dock Team is subscribed to branch lp:cairo-dock-core.
=== modified file 'src/gldit/cairo-dock-task.c' --- src/gldit/cairo-dock-task.c 2012-08-02 17:43:50 +0000 +++ src/gldit/cairo-dock-task.c 2012-08-12 23:23:19 +0000 @@ -25,98 +25,158 @@ #include "cairo-dock-task.h" -#define cairo_dock_schedule_next_iteration(pTask) do {\ - if (pTask->iSidTimer == 0 && pTask->iPeriod)\ - pTask->iSidTimer = g_timeout_add_seconds (pTask->iPeriod, (GSourceFunc) _cairo_dock_timer, pTask); } while (0) - -#define cairo_dock_cancel_next_iteration(pTask) do {\ - if (pTask->iSidTimer != 0) {\ - g_source_remove (pTask->iSidTimer);\ - pTask->iSidTimer = 0; } } while (0) - -#define cairo_dock_perform_task_update(pTask) do {\ - gboolean bContinue = pTask->update (pTask->pSharedMemory);\ - if (! bContinue) {\ - cairo_dock_cancel_next_iteration (pTask); }\ - else {\ - pTask->iFrequencyState = CAIRO_DOCK_FREQUENCY_NORMAL;\ - cairo_dock_schedule_next_iteration (pTask); } } while (0) - -#define cairo_dock_set_elapsed_time(pTask) do {\ - pTask->fElapsedTime = g_timer_elapsed (pTask->pClock, NULL);\ - g_timer_start (pTask->pClock); } while (0) - -#define _free_task(pTask) do {\ - if (pTask->free_data)\ - pTask->free_data (pTask->pSharedMemory);\ - g_timer_destroy (pTask->pClock);\ - g_free (pTask); } while (0) - static gboolean _cairo_dock_timer (CairoDockTask *pTask) { cairo_dock_launch_task (pTask); return TRUE; } -static gpointer _cairo_dock_threaded_calculation (CairoDockTask *pTask) -{ - //\_______________________ On obtient nos donnees. - cairo_dock_set_elapsed_time (pTask); - pTask->get_data (pTask->pSharedMemory); - - //\_______________________ On indique qu'on a fini. - g_atomic_int_set (&pTask->iThreadIsRunning, 0); - return NULL; -} + +static void cairo_dock_schedule_next_iteration (CairoDockTask *pTask) +{ + if (pTask->iSidTimer == 0 && pTask->iPeriod) + pTask->iSidTimer = g_timeout_add_seconds (pTask->iPeriod, (GSourceFunc) _cairo_dock_timer, pTask); +} + +static void cairo_dock_cancel_next_iteration (CairoDockTask *pTask) +{ + if (pTask->iSidTimer != 0) + { + g_source_remove (pTask->iSidTimer); + pTask->iSidTimer = 0; + } + if (pTask->get_data != NULL) + { + g_atomic_int_set (&pTask->iThreadCanRun, 0); + cd_debug ("Task: Unlock thread if it's running (%p)", pTask); + if (g_atomic_int_get (&pTask->iThreadIsRunning) == 0) // the thread is waiting + g_mutex_unlock (&pTask->aMutex); // unlock to stop the thread + g_mutex_unlock (&pTask->aMutex); // locked at the beginning of the thread + } +} + +static void cairo_dock_perform_task_update (CairoDockTask *pTask) +{ + gboolean bContinue = pTask->update (pTask->pSharedMemory); + if (! bContinue) + cairo_dock_cancel_next_iteration (pTask); + else + { + pTask->iFrequencyState = CAIRO_DOCK_FREQUENCY_NORMAL; + cairo_dock_schedule_next_iteration (pTask); + } +} + +static void cairo_dock_set_elapsed_time (CairoDockTask *pTask) +{ + pTask->fElapsedTime = g_timer_elapsed (pTask->pClock, NULL); + g_timer_start (pTask->pClock); +} + +static void _free_task (CairoDockTask *pTask) +{ + if (pTask->free_data) + pTask->free_data (pTask->pSharedMemory); + if (pTask->get_data != NULL) + { + #if (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 32) + g_mutex_free (&pTask->aMutex); + #else + + (&pTask->aMutex); + #endif + } + g_timer_destroy (pTask->pClock); + g_free (pTask); +} + static gboolean _cairo_dock_check_for_update (CairoDockTask *pTask) { - int iThreadIsRunning = g_atomic_int_get (&pTask->iThreadIsRunning); - if (! iThreadIsRunning) // le thread a fini. + if (g_atomic_int_get (&pTask->iThreadIsRunning) == 0) // data have been produced by the thread { - if (pTask->bDiscard) // la tache s'est faite abandonnee. + cd_debug ("Task: Perform task update (%p)", pTask); + if (pTask->bDiscard) // task has been discarded { //g_print ("free discared task...\n"); _free_task (pTask); //g_print ("done.\n"); return FALSE; } - - // On met a jour avec ces nouvelles donnees et on lance/arrete le timer. - pTask->iSidTimerUpdate = 0; + + pTask->iSidTimerUpdate = 0; // timer for the update + // We can perform task update and continue/stop the task's timer. cairo_dock_perform_task_update (pTask); - + return FALSE; } - return TRUE; -} + return TRUE; // continue to check if it's possible to perform task update +} + +static gpointer _cairo_dock_threaded_calculation (CairoDockTask *pTask) +{ + cd_debug ("Task: Start a new thread (%p)", pTask); + if (! g_mutex_trylock (&pTask->aMutex) + && ! g_atomic_int_compare_and_exchange (&pTask->iThreadIsRunning, 0, 1)) + return NULL; // was locked and is running: should not happen... + while (g_atomic_int_get (&pTask->iThreadCanRun) == 1) + { + //\_______________________ Get data + cairo_dock_set_elapsed_time (pTask); + pTask->get_data (pTask->pSharedMemory); + g_atomic_int_set (&pTask->iUpdateIsEnded, 1); + + // we launch the update in the main loop + pTask->iSidTimerUpdate = g_idle_add ((GSourceFunc) _cairo_dock_check_for_update, pTask); + + if (g_atomic_int_get (&pTask->iThreadCanRun) == 0) + break; // if the task has been cancelled, we should not wait... we should stop ! + + g_atomic_int_set (&pTask->iThreadIsRunning, 0); + + //\_______________________ We lock to wait for the next update + if (g_atomic_int_get (&pTask->iUpdateIsEnded) == 1) + g_mutex_lock (&pTask->aMutex); + } + g_atomic_int_set (&pTask->iThreadIsRunning, 0); + cd_debug ("Task: Stop the thread (%p)", pTask); + return NULL; +} + void cairo_dock_launch_task (CairoDockTask *pTask) { g_return_if_fail (pTask != NULL); - if (pTask->get_data == NULL) // pas de thread, tout est dans la fonction d'update. + if (pTask->get_data == NULL) // no threads, only update { cairo_dock_set_elapsed_time (pTask); cairo_dock_perform_task_update (pTask); } else { - if (g_atomic_int_compare_and_exchange (&pTask->iThreadIsRunning, 0, 1)) // il etait egal a 0, on lui met 1 et on lance le thread. + if (g_atomic_int_compare_and_exchange (&pTask->iThreadCanRun, 0, 1)) // if was 0, now 1 => we can launch a new thread { - GError *erreur = NULL; + GError *error = NULL; #if (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 32) - GThread* pThread = g_thread_create ((GThreadFunc) _cairo_dock_threaded_calculation, pTask, FALSE, &erreur); + GThread* pThread = g_thread_create ((GThreadFunc) _cairo_dock_threaded_calculation, pTask, FALSE, &error); #else - GThread* pThread = g_thread_try_new ("Cairo-Dock Task", (GThreadFunc) _cairo_dock_threaded_calculation, pTask, &erreur); + GThread* pThread = g_thread_try_new ("Task", (GThreadFunc) _cairo_dock_threaded_calculation, pTask, &error); g_thread_unref (pThread); #endif - if (erreur != NULL) // on n'a pas pu lancer le thread. + if (error != NULL) { - cd_warning (erreur->message); - g_error_free (erreur); - g_atomic_int_set (&pTask->iThreadIsRunning, 0); + cd_warning (error->message); + g_error_free (error); + g_atomic_int_set (&pTask->iThreadCanRun, 0); } } + else if (g_atomic_int_compare_and_exchange (&pTask->iThreadIsRunning, 0, 1) + && pTask->iSidTimerUpdate == 0) + { + // the thread is launched but it's not running + g_mutex_unlock (&pTask->aMutex); // unlock to get new data + g_atomic_int_set (&pTask->iUpdateIsEnded, 0); + } - if (pTask->iSidTimerUpdate == 0) - pTask->iSidTimerUpdate = g_timeout_add (MAX (100, MIN (0.10 * pTask->iPeriod, 333)), (GSourceFunc) _cairo_dock_check_for_update, pTask); + /* if (pTask->iSidTimerUpdate == 0) + pTask->iSidTimerUpdate = g_timeout_add (MAX (100, MIN (0.10 * pTask->iPeriod, 333)), (GSourceFunc) _cairo_dock_check_for_update, pTask);*/ } } @@ -127,6 +187,7 @@ cairo_dock_launch_task (pTask); return FALSE; } + void cairo_dock_launch_task_delayed (CairoDockTask *pTask, double fDelay) { cairo_dock_cancel_next_iteration (pTask); @@ -146,6 +207,15 @@ pTask->free_data = free_data; pTask->pSharedMemory = pSharedMemory; pTask->pClock = g_timer_new (); + if (get_data != NULL) + { + #if (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 32) + GMutex *pMutex = g_mutex_new (); + pTask->aMutex = &pMutex; + #else + g_mutex_init (&pTask->aMutex); + #endif + } return pTask; } @@ -263,7 +333,7 @@ break ; } - cd_message ("degradation de la mesure (etat <- %d/%d)", pTask->iFrequencyState, CAIRO_DOCK_NB_FREQUENCIES-1); + cd_message ("degradation of the frequency (state <- %d/%d)", pTask->iFrequencyState, CAIRO_DOCK_NB_FREQUENCIES-1); _cairo_dock_restart_timer_with_frequency (pTask, iNewPeriod); } } === modified file 'src/gldit/cairo-dock-task.h' --- src/gldit/cairo-dock-task.h 2010-10-31 00:14:40 +0000 +++ src/gldit/cairo-dock-task.h 2012-08-12 23:23:19 +0000 @@ -60,7 +60,7 @@ /// ID of the timer to check the end of the thread. gint iSidTimerUpdate; /// Atomic value, set to 1 when the thread is running. - gint iThreadIsRunning; + volatile gint iThreadIsRunning; /// function carrying out the heavy job. CairoDockGetDataAsyncFunc get_data; /// function carrying out the update of the dock. Returns TRUE to continue, FALSE to stop. @@ -79,6 +79,12 @@ GFreeFunc free_data; /// TRUE when the task has been discarded. gboolean bDiscard; + /// Mutex to know if the thread can receive data + GMutex aMutex; + /// Atomic value, set to 1 when the thread can run + volatile gint iThreadCanRun; + /// Atomic value, set to 1 when the main-loop is doing the update + volatile gint iUpdateIsEnded; } ; === modified file 'src/implementations/cairo-dock-graph.c' --- src/implementations/cairo-dock-graph.c 2012-07-19 23:59:06 +0000 +++ src/implementations/cairo-dock-graph.c 2012-08-12 23:23:19 +0000 @@ -40,7 +40,6 @@ gdouble fBackGroundColor[4]; cairo_surface_t *pBackgroundSurface; GLuint iBackgroundTexture; - gint iRadius; // deprecated gint iMargin; gboolean bMixGraphs; } Graph; === modified file 'src/implementations/cairo-dock-graph.h' --- src/implementations/cairo-dock-graph.h 2011-09-13 00:07:51 +0000 +++ src/implementations/cairo-dock-graph.h 2012-08-12 23:23:19 +0000 @@ -58,8 +58,6 @@ gdouble *fLowColor; /// color of the background. gdouble fBackGroundColor[4]; - // radius of the corners of the background. - gint iRadius; // deprecated /// TRUE to draw all the values on the same graph. gboolean bMixGraphs; };
_______________________________________________ Mailing list: https://launchpad.net/~cairo-dock-team Post to : cairo-dock-team@lists.launchpad.net Unsubscribe : https://launchpad.net/~cairo-dock-team More help : https://help.launchpad.net/ListHelp