From: Christopher John Purnell Date: Thu, 11 Dec 2003 21:29:43 +0000 (+0000) Subject: The deferred window destruction code was destroying the windows in reverse X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=commitdiff_plain;h=612f817ef1b975ede61b5cd6b880822b66207b76;hp=3395341640d3cbea619843270da92edfca0cb324;p=freeglut 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: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@396 7f0cb862-5218-0410-a997-914c9d46530a --- diff --git a/src/freeglut_internal.h b/src/freeglut_internal.h index 03296e0..7ffb4b6 100644 --- a/src/freeglut_internal.h +++ b/src/freeglut_internal.h @@ -546,8 +546,8 @@ struct tagSFG_Window typedef struct tagSFG_WindowList SFG_WindowList ; struct tagSFG_WindowList { + SFG_Node node; SFG_Window *window ; - SFG_WindowList *next ; }; /* @@ -558,6 +558,7 @@ struct tagSFG_Structure { SFG_List Windows; /* The global windows list */ SFG_List Menus; /* The global menus list */ + SFG_List WindowsToDestroy; SFG_Window* Window; /* The currently active win. */ SFG_Menu* Menu; /* Same, but menu... */ diff --git a/src/freeglut_structure.c b/src/freeglut_structure.c index 6aa02fd..2c5f1fe 100644 --- a/src/freeglut_structure.c +++ b/src/freeglut_structure.c @@ -42,6 +42,7 @@ SFG_Structure fgStructure = { { NULL, NULL }, /* The list of windows */ { NULL, NULL }, /* The list of menus */ + { NULL, NULL }, /* Windows to Destroy list */ NULL, /* The current window */ NULL, /* The current menu */ NULL, /* The menu OpenGL context */ @@ -172,14 +173,6 @@ SFG_Menu* fgCreateMenu( FGCBMenu menuCallback ) } /* - * 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. * Subwindows are automatically added because they hang from the window * structure. @@ -189,8 +182,7 @@ void fgAddToWindowDestroyList( SFG_Window* window ) SFG_WindowList *new_list_entry = ( SFG_WindowList* )malloc( sizeof(SFG_WindowList ) ); new_list_entry->window = window; - new_list_entry->next = WindowsToDestroy; - WindowsToDestroy = new_list_entry; + fgListAppend( &fgStructure.WindowsToDestroy, &new_list_entry->node ); /* * Check if the window is the current one... @@ -218,22 +210,13 @@ void fgAddToWindowDestroyList( SFG_Window* window ) */ void fgCloseWindows( ) { - SFG_WindowList *window_ptr = WindowsToDestroy; - WindowsToDestroy = ( SFG_WindowList* )NULL; - /* In case the destroy callbacks cause more windows to be closed */ + SFG_WindowList *window_ptr; - while( window_ptr ) + while( window_ptr = fgStructure.WindowsToDestroy.First ) { - SFG_WindowList *next = window_ptr->next; fgDestroyWindow( window_ptr->window ); + fgListRemove( &fgStructure.WindowsToDestroy, &window_ptr->node ); 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.Menus); + fgListInit(&fgStructure.WindowsToDestroy); } /* @@ -419,6 +403,11 @@ void fgDestroyStructure( void ) freeglut_assert_ready; /* + * Clean up the WindowsToDestroy list. + */ + fgCloseWindows(); + + /* * Make sure all windows and menus have been deallocated */ while( menu = ( SFG_Menu * )fgStructure.Menus.First )