mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-10-31 08:22:16 +01:00 
			
		
		
		
	Use the atomic integer operations for GMainContext and GMainLoop reference
2004-03-04 Sebastian Wilhelmi <seppi@seppi.de> * glib/gmain.c: Use the atomic integer operations for GMainContext and GMainLoop reference counting. * glib/gmain.c: Hold the main_context_list lock, when iterating the list. Only call g_main_context_wakeup for positive reference count.
This commit is contained in:
		
				
					committed by
					
						 Sebastian Wilhelmi
						Sebastian Wilhelmi
					
				
			
			
				
	
			
			
			
						parent
						
							6e521087ad
						
					
				
				
					commit
					c40b15fc6b
				
			| @@ -1,3 +1,12 @@ | ||||
| 2004-03-04  Sebastian Wilhelmi  <seppi@seppi.de> | ||||
|  | ||||
| 	* glib/gmain.c: Use the atomic integer operations for GMainContext | ||||
| 	and GMainLoop reference counting. | ||||
|  | ||||
| 	* glib/gmain.c: Hold the main_context_list lock, when iterating | ||||
| 	the list. Only call g_main_context_wakeup for positive reference | ||||
| 	count. | ||||
|  | ||||
| 2004-03-03  Tor Lillqvist  <tml@iki.fi> | ||||
|  | ||||
| 	* glibconfig.h.win32.in: Update to match a configure-generated | ||||
|   | ||||
| @@ -1,3 +1,12 @@ | ||||
| 2004-03-04  Sebastian Wilhelmi  <seppi@seppi.de> | ||||
|  | ||||
| 	* glib/gmain.c: Use the atomic integer operations for GMainContext | ||||
| 	and GMainLoop reference counting. | ||||
|  | ||||
| 	* glib/gmain.c: Hold the main_context_list lock, when iterating | ||||
| 	the list. Only call g_main_context_wakeup for positive reference | ||||
| 	count. | ||||
|  | ||||
| 2004-03-03  Tor Lillqvist  <tml@iki.fi> | ||||
|  | ||||
| 	* glibconfig.h.win32.in: Update to match a configure-generated | ||||
|   | ||||
| @@ -1,3 +1,12 @@ | ||||
| 2004-03-04  Sebastian Wilhelmi  <seppi@seppi.de> | ||||
|  | ||||
| 	* glib/gmain.c: Use the atomic integer operations for GMainContext | ||||
| 	and GMainLoop reference counting. | ||||
|  | ||||
| 	* glib/gmain.c: Hold the main_context_list lock, when iterating | ||||
| 	the list. Only call g_main_context_wakeup for positive reference | ||||
| 	count. | ||||
|  | ||||
| 2004-03-03  Tor Lillqvist  <tml@iki.fi> | ||||
|  | ||||
| 	* glibconfig.h.win32.in: Update to match a configure-generated | ||||
|   | ||||
| @@ -1,3 +1,12 @@ | ||||
| 2004-03-04  Sebastian Wilhelmi  <seppi@seppi.de> | ||||
|  | ||||
| 	* glib/gmain.c: Use the atomic integer operations for GMainContext | ||||
| 	and GMainLoop reference counting. | ||||
|  | ||||
| 	* glib/gmain.c: Hold the main_context_list lock, when iterating | ||||
| 	the list. Only call g_main_context_wakeup for positive reference | ||||
| 	count. | ||||
|  | ||||
| 2004-03-03  Tor Lillqvist  <tml@iki.fi> | ||||
|  | ||||
| 	* glibconfig.h.win32.in: Update to match a configure-generated | ||||
|   | ||||
| @@ -1,3 +1,12 @@ | ||||
| 2004-03-04  Sebastian Wilhelmi  <seppi@seppi.de> | ||||
|  | ||||
| 	* glib/gmain.c: Use the atomic integer operations for GMainContext | ||||
| 	and GMainLoop reference counting. | ||||
|  | ||||
| 	* glib/gmain.c: Hold the main_context_list lock, when iterating | ||||
| 	the list. Only call g_main_context_wakeup for positive reference | ||||
| 	count. | ||||
|  | ||||
| 2004-03-03  Tor Lillqvist  <tml@iki.fi> | ||||
|  | ||||
| 	* glibconfig.h.win32.in: Update to match a configure-generated | ||||
|   | ||||
| @@ -1,3 +1,12 @@ | ||||
| 2004-03-04  Sebastian Wilhelmi  <seppi@seppi.de> | ||||
|  | ||||
| 	* glib/gmain.c: Use the atomic integer operations for GMainContext | ||||
| 	and GMainLoop reference counting. | ||||
|  | ||||
| 	* glib/gmain.c: Hold the main_context_list lock, when iterating | ||||
| 	the list. Only call g_main_context_wakeup for positive reference | ||||
| 	count. | ||||
|  | ||||
| 2004-03-03  Tor Lillqvist  <tml@iki.fi> | ||||
|  | ||||
| 	* glibconfig.h.win32.in: Update to match a configure-generated | ||||
|   | ||||
							
								
								
									
										121
									
								
								glib/gmain.c
									
									
									
									
									
								
							
							
						
						
									
										121
									
								
								glib/gmain.c
									
									
									
									
									
								
							| @@ -103,7 +103,7 @@ struct _GMainContext | ||||
|   GSList *waiters; | ||||
| #endif   | ||||
|  | ||||
|   guint ref_count; | ||||
|   gint ref_count; | ||||
|  | ||||
|   GPtrArray *pending_dispatches; | ||||
|   gint timeout;			/* Timeout for current iteration */ | ||||
| @@ -153,7 +153,7 @@ struct _GMainLoop | ||||
| { | ||||
|   GMainContext *context; | ||||
|   gboolean is_running; | ||||
|   guint ref_count; | ||||
|   gint ref_count; | ||||
| }; | ||||
|  | ||||
| struct _GTimeoutSource | ||||
| @@ -171,8 +171,8 @@ struct _GChildWatchSource | ||||
| #ifdef G_OS_WIN32 | ||||
|   GPollFD     poll; | ||||
| #else /* G_OS_WIN32 */ | ||||
|    gint        count; | ||||
|    gboolean    child_exited; | ||||
|   gint        count; | ||||
|   gboolean    child_exited; | ||||
| #endif /* G_OS_WIN32 */ | ||||
| }; | ||||
|  | ||||
| @@ -589,13 +589,9 @@ void | ||||
| g_main_context_ref (GMainContext *context) | ||||
| { | ||||
|   g_return_if_fail (context != NULL); | ||||
|   g_return_if_fail (context->ref_count > 0);  | ||||
|   g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);  | ||||
|  | ||||
|   LOCK_CONTEXT (context); | ||||
|    | ||||
|   context->ref_count++; | ||||
|  | ||||
|   UNLOCK_CONTEXT (context); | ||||
|   g_atomic_int_inc (&context->ref_count); | ||||
| } | ||||
|  | ||||
| /* If DISABLE_MEM_POOLS is defined, then freeing the | ||||
| @@ -618,18 +614,22 @@ poll_rec_list_free (GMainContext *context, | ||||
| } | ||||
| #endif /* DISABLE_MEM_POOLS */ | ||||
|  | ||||
| static void | ||||
| g_main_context_unref_and_unlock (GMainContext *context) | ||||
| /** | ||||
|  * g_main_context_unref: | ||||
|  * @context: a #GMainContext | ||||
|  *  | ||||
|  * Decreases the reference count on a #GMainContext object by one. If | ||||
|  * the result is zero, free the context and free all associated memory. | ||||
|  **/ | ||||
| void | ||||
| g_main_context_unref (GMainContext *context) | ||||
| { | ||||
|   GSource *source; | ||||
|   g_return_if_fail (context != NULL); | ||||
|   g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);  | ||||
|  | ||||
|   context->ref_count--; | ||||
|  | ||||
|   if (context->ref_count != 0) | ||||
|     { | ||||
|       UNLOCK_CONTEXT (context); | ||||
|       return; | ||||
|     } | ||||
|   if (!g_atomic_int_dec_and_test (&context->ref_count)) | ||||
|     return; | ||||
|  | ||||
|   G_LOCK (main_context_list); | ||||
|   main_context_list = g_slist_remove (main_context_list, context); | ||||
| @@ -642,7 +642,6 @@ g_main_context_unref_and_unlock (GMainContext *context) | ||||
|       g_source_destroy_internal (source, context, TRUE); | ||||
|       source = next; | ||||
|     } | ||||
|   UNLOCK_CONTEXT (context); | ||||
|  | ||||
| #ifdef G_THREADS_ENABLED   | ||||
|   g_static_mutex_free (&context->mutex); | ||||
| @@ -677,23 +676,6 @@ g_main_context_unref_and_unlock (GMainContext *context) | ||||
|   g_free (context); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * g_main_context_unref: | ||||
|  * @context: a #GMainContext | ||||
|  *  | ||||
|  * Decreases the reference count on a #GMainContext object by one. If | ||||
|  * the result is zero, free the context and free all associated memory. | ||||
|  **/ | ||||
| void | ||||
| g_main_context_unref (GMainContext *context) | ||||
| { | ||||
|   g_return_if_fail (context != NULL); | ||||
|   g_return_if_fail (context->ref_count > 0);  | ||||
|  | ||||
|   LOCK_CONTEXT (context); | ||||
|   g_main_context_unref_and_unlock (context); | ||||
| } | ||||
|  | ||||
| #ifdef G_THREADS_ENABLED | ||||
| static void  | ||||
| g_main_context_init_pipe (GMainContext *context) | ||||
| @@ -2636,31 +2618,13 @@ GMainLoop * | ||||
| g_main_loop_ref (GMainLoop *loop) | ||||
| { | ||||
|   g_return_val_if_fail (loop != NULL, NULL); | ||||
|   g_return_val_if_fail (loop->ref_count > 0, NULL); | ||||
|   g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, NULL); | ||||
|  | ||||
|   LOCK_CONTEXT (loop->context); | ||||
|   loop->ref_count++; | ||||
|   UNLOCK_CONTEXT (loop->context); | ||||
|   g_atomic_int_inc (&loop->ref_count); | ||||
|  | ||||
|   return loop; | ||||
| } | ||||
|  | ||||
| static void | ||||
| g_main_loop_unref_and_unlock (GMainLoop *loop) | ||||
| { | ||||
|   loop->ref_count--; | ||||
|   if (loop->ref_count == 0) | ||||
|     { | ||||
|       /* When the ref_count is 0, there can be nobody else using the | ||||
|        * loop, so it is safe to unlock before destroying. | ||||
|        */ | ||||
|       g_main_context_unref_and_unlock (loop->context); | ||||
|   g_free (loop); | ||||
|     } | ||||
|   else | ||||
|     UNLOCK_CONTEXT (loop->context); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * g_main_loop_unref: | ||||
|  * @loop: a #GMainLoop | ||||
| @@ -2672,11 +2636,13 @@ void | ||||
| g_main_loop_unref (GMainLoop *loop) | ||||
| { | ||||
|   g_return_if_fail (loop != NULL); | ||||
|   g_return_if_fail (loop->ref_count > 0); | ||||
|   g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0); | ||||
|  | ||||
|   LOCK_CONTEXT (loop->context); | ||||
|    | ||||
|   g_main_loop_unref_and_unlock (loop); | ||||
|   if (!g_atomic_int_dec_and_test (&loop->ref_count)) | ||||
|     return; | ||||
|  | ||||
|   g_main_context_unref (loop->context); | ||||
|   g_free (loop); | ||||
| } | ||||
|  | ||||
| /** | ||||
| @@ -2694,7 +2660,7 @@ g_main_loop_run (GMainLoop *loop) | ||||
|   GThread *self = G_THREAD_SELF; | ||||
|  | ||||
|   g_return_if_fail (loop != NULL); | ||||
|   g_return_if_fail (loop->ref_count > 0); | ||||
|   g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0); | ||||
|  | ||||
| #ifdef G_THREADS_ENABLED | ||||
|   if (!g_main_context_acquire (loop->context)) | ||||
| @@ -2711,7 +2677,7 @@ g_main_loop_run (GMainLoop *loop) | ||||
|        | ||||
|       LOCK_CONTEXT (loop->context); | ||||
|  | ||||
|       loop->ref_count++; | ||||
|       g_atomic_int_inc (&loop->ref_count); | ||||
|  | ||||
|       if (!loop->is_running) | ||||
| 	loop->is_running = TRUE; | ||||
| @@ -2746,7 +2712,7 @@ g_main_loop_run (GMainLoop *loop) | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   loop->ref_count++; | ||||
|   g_atomic_int_inc (&loop->ref_count); | ||||
|   loop->is_running = TRUE; | ||||
|   while (loop->is_running) | ||||
|     g_main_context_iterate (loop->context, TRUE, TRUE, self); | ||||
| @@ -2771,7 +2737,7 @@ void | ||||
| g_main_loop_quit (GMainLoop *loop) | ||||
| { | ||||
|   g_return_if_fail (loop != NULL); | ||||
|   g_return_if_fail (loop->ref_count > 0); | ||||
|   g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0); | ||||
|  | ||||
|   LOCK_CONTEXT (loop->context); | ||||
|   loop->is_running = FALSE; | ||||
| @@ -2797,7 +2763,7 @@ gboolean | ||||
| g_main_loop_is_running (GMainLoop *loop) | ||||
| { | ||||
|   g_return_val_if_fail (loop != NULL, FALSE); | ||||
|   g_return_val_if_fail (loop->ref_count > 0, FALSE); | ||||
|   g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, FALSE); | ||||
|  | ||||
|   return loop->is_running; | ||||
| } | ||||
| @@ -2814,7 +2780,7 @@ GMainContext * | ||||
| g_main_loop_get_context (GMainLoop *loop) | ||||
| { | ||||
|   g_return_val_if_fail (loop != NULL, NULL); | ||||
|   g_return_val_if_fail (loop->ref_count > 0, NULL); | ||||
|   g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, NULL); | ||||
|   | ||||
|   return loop->context; | ||||
| } | ||||
| @@ -2920,7 +2886,7 @@ g_main_context_add_poll (GMainContext *context, | ||||
|   if (!context) | ||||
|     context = g_main_context_default (); | ||||
|    | ||||
|   g_return_if_fail (context->ref_count > 0); | ||||
|   g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0); | ||||
|   g_return_if_fail (fd); | ||||
|  | ||||
|   LOCK_CONTEXT (context); | ||||
| @@ -2992,7 +2958,7 @@ g_main_context_remove_poll (GMainContext *context, | ||||
|   if (!context) | ||||
|     context = g_main_context_default (); | ||||
|    | ||||
|   g_return_if_fail (context->ref_count > 0); | ||||
|   g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0); | ||||
|   g_return_if_fail (fd); | ||||
|  | ||||
|   LOCK_CONTEXT (context); | ||||
| @@ -3094,7 +3060,7 @@ g_main_context_set_poll_func (GMainContext *context, | ||||
|   if (!context) | ||||
|     context = g_main_context_default (); | ||||
|    | ||||
|   g_return_if_fail (context->ref_count > 0); | ||||
|   g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0); | ||||
|  | ||||
|   LOCK_CONTEXT (context); | ||||
|    | ||||
| @@ -3128,7 +3094,7 @@ g_main_context_get_poll_func (GMainContext *context) | ||||
|   if (!context) | ||||
|     context = g_main_context_default (); | ||||
|    | ||||
|   g_return_val_if_fail (context->ref_count > 0, NULL); | ||||
|   g_return_val_if_fail (g_atomic_int_get (&context->ref_count) > 0, NULL); | ||||
|  | ||||
|   LOCK_CONTEXT (context); | ||||
|   result = context->poll_func; | ||||
| @@ -3168,7 +3134,7 @@ g_main_context_wakeup (GMainContext *context) | ||||
|   if (!context) | ||||
|     context = g_main_context_default (); | ||||
|    | ||||
|   g_return_if_fail (context->ref_count > 0); | ||||
|   g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0); | ||||
|  | ||||
|   LOCK_CONTEXT (context); | ||||
|   g_main_context_wakeup_unlocked (context); | ||||
| @@ -3571,15 +3537,20 @@ child_watch_helper_thread (gpointer data) | ||||
|       read (child_watch_wake_up_pipe[0], b, 20); | ||||
|  | ||||
|       /* We were woken up.  Wake up all other contexts in all other threads */ | ||||
|       G_UNLOCK (main_context_list); | ||||
|       G_LOCK (main_context_list); | ||||
|       for (list = main_context_list; list; list = list->next) | ||||
| 	{ | ||||
| 	  GMainContext *context; | ||||
|  | ||||
| 	  context = list->data; | ||||
| 	  g_main_context_wakeup (context); | ||||
| 	  if (g_atomic_int_get (&context->ref_count) > 0) | ||||
| 	    /* Due to racing conditions we can find ref_count == 0, in | ||||
| 	     * that case, however, the context is still not destroyed | ||||
| 	     * and no poll can be active, otherwise the ref_count | ||||
| 	     * wouldn't be 0 */ | ||||
| 	    g_main_context_wakeup (context); | ||||
| 	} | ||||
|       G_LOCK (main_context_list); | ||||
|       G_UNLOCK (main_context_list); | ||||
|     } | ||||
|   return NULL; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user