The deferred window destruction code was destroying the windows in reverse

order.  This cased a crash when the call to glutDestroyWindow() for a sub
windows was immediately followed by a call to glutDestroyWindow() for it's
parent. fgCloseWindows() would call fgDestroyWindow() for the parent first
fgDestroyWindws() would recurse over the children and then fgCloseWindows()
would call fgDestroyWindow() again for the child.

I've replaced the single linked list with one of our two way link list
structures.  I've also moved it into fgStructure because that seemed the
consistent thing to do.

I said the the deferred windows destruction causes more problems then it
solves.


git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@396 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
cjp 2003-12-11 21:29:43 +00:00
parent a28a6de82f
commit 103f7e8d87
2 changed files with 13 additions and 23 deletions

View File

@ -546,8 +546,8 @@ struct tagSFG_Window
typedef struct tagSFG_WindowList SFG_WindowList ; typedef struct tagSFG_WindowList SFG_WindowList ;
struct tagSFG_WindowList struct tagSFG_WindowList
{ {
SFG_Node node;
SFG_Window *window ; SFG_Window *window ;
SFG_WindowList *next ;
}; };
/* /*
@ -558,6 +558,7 @@ struct tagSFG_Structure
{ {
SFG_List Windows; /* The global windows list */ SFG_List Windows; /* The global windows list */
SFG_List Menus; /* The global menus list */ SFG_List Menus; /* The global menus list */
SFG_List WindowsToDestroy;
SFG_Window* Window; /* The currently active win. */ SFG_Window* Window; /* The currently active win. */
SFG_Menu* Menu; /* Same, but menu... */ SFG_Menu* Menu; /* Same, but menu... */

View File

@ -42,6 +42,7 @@
SFG_Structure fgStructure = { { NULL, NULL }, /* The list of windows */ SFG_Structure fgStructure = { { NULL, NULL }, /* The list of windows */
{ NULL, NULL }, /* The list of menus */ { NULL, NULL }, /* The list of menus */
{ NULL, NULL }, /* Windows to Destroy list */
NULL, /* The current window */ NULL, /* The current window */
NULL, /* The current menu */ NULL, /* The current menu */
NULL, /* The menu OpenGL context */ NULL, /* The menu OpenGL context */
@ -171,14 +172,6 @@ SFG_Menu* fgCreateMenu( FGCBMenu menuCallback )
return menu; return menu;
} }
/*
* Linked list of windows to destroy ... this is so we don't destroy a
* window from the middle of its callback. Some C compilers take an
* extremely dim view of this.
*/
static SFG_WindowList* WindowsToDestroy = ( SFG_WindowList* )NULL;
/* /*
* Function to add a window to the linked list of windows to destroy. * Function to add a window to the linked list of windows to destroy.
* Subwindows are automatically added because they hang from the window * Subwindows are automatically added because they hang from the window
@ -189,8 +182,7 @@ void fgAddToWindowDestroyList( SFG_Window* window )
SFG_WindowList *new_list_entry = SFG_WindowList *new_list_entry =
( SFG_WindowList* )malloc( sizeof(SFG_WindowList ) ); ( SFG_WindowList* )malloc( sizeof(SFG_WindowList ) );
new_list_entry->window = window; new_list_entry->window = window;
new_list_entry->next = WindowsToDestroy; fgListAppend( &fgStructure.WindowsToDestroy, &new_list_entry->node );
WindowsToDestroy = new_list_entry;
/* /*
* Check if the window is the current one... * Check if the window is the current one...
@ -218,22 +210,13 @@ void fgAddToWindowDestroyList( SFG_Window* window )
*/ */
void fgCloseWindows( ) void fgCloseWindows( )
{ {
SFG_WindowList *window_ptr = WindowsToDestroy; SFG_WindowList *window_ptr;
WindowsToDestroy = ( SFG_WindowList* )NULL;
/* In case the destroy callbacks cause more windows to be closed */
while( window_ptr ) while( window_ptr = fgStructure.WindowsToDestroy.First )
{ {
SFG_WindowList *next = window_ptr->next;
fgDestroyWindow( window_ptr->window ); fgDestroyWindow( window_ptr->window );
fgListRemove( &fgStructure.WindowsToDestroy, &window_ptr->node );
free( window_ptr ); free( window_ptr );
window_ptr = next;
if( !window_ptr )
{
window_ptr = WindowsToDestroy;
WindowsToDestroy = ( SFG_WindowList* )NULL;
}
} }
} }
@ -404,6 +387,7 @@ void fgCreateStructure( void )
fgListInit(&fgStructure.Windows); fgListInit(&fgStructure.Windows);
fgListInit(&fgStructure.Menus); fgListInit(&fgStructure.Menus);
fgListInit(&fgStructure.WindowsToDestroy);
} }
/* /*
@ -418,6 +402,11 @@ void fgDestroyStructure( void )
freeglut_assert_ready; freeglut_assert_ready;
/*
* Clean up the WindowsToDestroy list.
*/
fgCloseWindows();
/* /*
* Make sure all windows and menus have been deallocated * Make sure all windows and menus have been deallocated
*/ */