← Back to team overview

cairo-dock-team team mailing list archive

[Merge] lp:~matttbe/cairo-dock-core/task-one-thread-async-2 into lp:cairo-dock-core

 

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;
 };


Follow ups