mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-10-31 00:12:19 +01:00 
			
		
		
		
	Go back to the old logic in set_expiration
It was more complicated, but also more correct... Also add a test to ensure that our rounding works as expected. https://bugzilla.gnome.org/show_bug.cgi?id=643795
This commit is contained in:
		
							
								
								
									
										10
									
								
								glib/gmain.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								glib/gmain.c
									
									
									
									
									
								
							| @@ -3801,6 +3801,7 @@ g_timeout_set_expiration (GTimeoutSource *timeout_source, | ||||
|  | ||||
|   if (timeout_source->seconds) | ||||
|     { | ||||
|       gint64 remainder; | ||||
|       static gint timer_perturb = -1; | ||||
|  | ||||
|       if (timer_perturb == -1) | ||||
| @@ -3825,11 +3826,14 @@ g_timeout_set_expiration (GTimeoutSource *timeout_source, | ||||
|        * always only *increase* the expiration time by adding a full | ||||
|        * second in the case that the microsecond portion decreases. | ||||
|        */ | ||||
|       if (timer_perturb < timeout_source->expiration % 1000000) | ||||
|       timeout_source->expiration -= timer_perturb; | ||||
|  | ||||
|       remainder = timeout_source->expiration % 1000000; | ||||
|       if (remainder >= 1000000/4) | ||||
|         timeout_source->expiration += 1000000; | ||||
|  | ||||
|       timeout_source->expiration = | ||||
|         ((timeout_source->expiration / 1000000) * 1000000) + timer_perturb; | ||||
|       timeout_source->expiration -= remainder; | ||||
|       timeout_source->expiration += timer_perturb; | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| #include <glib.h> | ||||
| #include <unistd.h> | ||||
|  | ||||
| static GMainLoop *loop; | ||||
|  | ||||
| @@ -42,12 +43,52 @@ test_seconds (void) | ||||
|   g_main_loop_run (loop); | ||||
| } | ||||
|  | ||||
| static gint64 last_time; | ||||
| static gint count; | ||||
|  | ||||
| static gboolean | ||||
| test_func (gpointer data) | ||||
| { | ||||
|   gint64 current_time; | ||||
|  | ||||
|   current_time = g_get_monotonic_time (); | ||||
|  | ||||
|   g_assert (current_time / 1000000 - last_time / 1000000 == 1); | ||||
|  | ||||
|   last_time = current_time; | ||||
|   count++; | ||||
|  | ||||
|   /* Make the timeout take up to 0.1 seconds. | ||||
|    * We should still get scheduled for the next second. | ||||
|    */ | ||||
|   usleep (count * 10000); | ||||
|  | ||||
|   if (count < 10) | ||||
|     return TRUE; | ||||
|  | ||||
|   g_main_loop_quit (loop); | ||||
|  | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| static void | ||||
| test_rounding (void) | ||||
| { | ||||
|   loop = g_main_loop_new (NULL, FALSE); | ||||
|  | ||||
|   last_time = g_get_monotonic_time (); | ||||
|   g_timeout_add_seconds (1, test_func, NULL); | ||||
|  | ||||
|   g_main_loop_run (loop); | ||||
| } | ||||
|  | ||||
| int | ||||
| main (int argc, char *argv[]) | ||||
| { | ||||
|   g_test_init (&argc, &argv, NULL); | ||||
|  | ||||
|   g_test_add_func ("/timeout/seconds", test_seconds); | ||||
|   g_test_add_func ("/timeout/rounding", test_rounding); | ||||
|  | ||||
|   return g_test_run (); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user