2009/7/16 Dominique Pellé wrote:
> ...
> I don't know how complicated it is to fix it the way you describe.
>
> But how about simply avoiding recursive calls of the callback
> find_replace_cb()?
>
> With the attached patch, I can no longer reproduce the crash
> (whereas I could easily reproduce the crash without the patch).
> Can you also check whether it works for you?

I cannot reproduce the crash with the patch. Valgrind does not report
anymore the errors, while these errors were occuring on each test run
without the patch.


> Perhaps there are other such callbacks that would require the
> same fix.

There is also the case where a callback is invoked from the gui while
another callback from a different type, is already running, but I am
not sure that such a case can be found and can be run, where both
callbacks are running functions from the syntax module.

Anyway, following your tracks, I have tried to fix this case with a
global flag (see the attached patch) that prevents find_replace_cb to
run anywhere except from the first gtk_main() event loop started by
vim.  The global flag and gtk_main_level() could be tested at the
beginning of each callback that runs non reentrant code (such as the
code in syntax.c). This new patch also fixes the crash and Valgrind
does not produce errors anymore, but it is more complex than your
patch, so I just add it here for the sake of discussion.


Xavier

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Index: src/gui_gtk.c
===================================================================
--- src/gui_gtk.c	(revision 1567)
+++ src/gui_gtk.c	(working copy)
@@ -1350,7 +1350,11 @@
 
     gtk_widget_show(gui.filedlg);
     while (gui.filedlg && GTK_WIDGET_DRAWABLE(gui.filedlg))
+    {
+        in_gtk_main_iteration = TRUE;;
 	gtk_main_iteration_do(TRUE);
+        in_gtk_main_iteration = FALSE;;
+    }
 #endif
 
 # ifdef HAVE_GTK2
@@ -1946,7 +1950,11 @@
     /* loop here until the dialog goes away */
     while (dialog_status == -1 && !dialog_destroyed
 					       && GTK_WIDGET_DRAWABLE(dialog))
+    {
+        in_gtk_main_iteration = TRUE;;
 	gtk_main_iteration_do(TRUE);
+        in_gtk_main_iteration = FALSE;;
+    }
 
     if (dialog_status < 0)
 	dialog_status = 0;
@@ -2959,6 +2967,9 @@
     SharedFindReplace	*sfr;
     int			rc;
 
+    if (gtk_main_level() > 1 || in_gtk_main_iteration)
+        return;
+
     flags = (int)(long)data;	    /* avoid a lint warning here */
 
     /* Get the search/replace strings from the dialog */
Index: src/gui_gtk_x11.c
===================================================================
--- src/gui_gtk_x11.c	(revision 1567)
+++ src/gui_gtk_x11.c	(working copy)
@@ -4751,7 +4751,11 @@
 
     /* Wait for the font dialog to be closed. */
     while (gui.fontdlg && GTK_WIDGET_DRAWABLE(gui.fontdlg))
+    {
+        in_gtk_main_iteration = TRUE;;
 	gtk_main_iteration_do(TRUE);
+        in_gtk_main_iteration = FALSE;;
+    }
 
     if (gui.fontname != NULL)
     {
@@ -6434,7 +6438,11 @@
 gui_mch_update(void)
 {
     while (gtk_events_pending() && !vim_is_input_buf_full())
+    {
+        in_gtk_main_iteration = TRUE;;
 	gtk_main_iteration_do(FALSE);
+        in_gtk_main_iteration = FALSE;;
+    }
 }
 
     static gint
Index: src/globals.h
===================================================================
--- src/globals.h	(revision 1567)
+++ src/globals.h	(working copy)
@@ -477,6 +477,9 @@
 
 /* "-fg" or "-foreground" command line argument */
 EXTERN char	*foreground_argument INIT(= NULL);
+
+/* gtk_main_iteration reentrant flag */
+EXTERN int	 in_gtk_main_iteration INIT(= FALSE);
 # endif
 
 /*

Raspunde prin e-mail lui