Don't delete GLX's extensionInitCallback list during a reset.
When a callback list is initialized using CreateCallbackList via AddCallback, the list gets added to the listsToCleanup array, and as a result the list gets deleted at the end of the server generation. But, vendor libraries add themselves to that callback list only once, not once per generation, so if you delete the list, then no vendor will register itself on the next generation, and GLX breaks. Instead, use a static CallbackListRec for the extensionInitCallback list. That way, it doesn't get added to listsToCleanup, and doesn't get deleted during a reset. Reviewed-by: Adam Jackson <ajax@redhat.com>
This commit is contained in:
		
							parent
							
								
									7004a7c3c9
								
							
						
					
					
						commit
						16639ab77d
					
				
							
								
								
									
										15
									
								
								glx/vndext.c
								
								
								
								
							
							
						
						
									
										15
									
								
								glx/vndext.c
								
								
								
								
							| 
						 | 
					@ -40,7 +40,8 @@
 | 
				
			||||||
#include "vndservervendor.h"
 | 
					#include "vndservervendor.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int GlxErrorBase = 0;
 | 
					int GlxErrorBase = 0;
 | 
				
			||||||
static CallbackListPtr vndInitCallbackList;
 | 
					static CallbackListRec vndInitCallbackList;
 | 
				
			||||||
 | 
					static CallbackListPtr vndInitCallbackListPtr = &vndInitCallbackList;
 | 
				
			||||||
static DevPrivateKeyRec glvXGLVScreenPrivKey;
 | 
					static DevPrivateKeyRec glvXGLVScreenPrivKey;
 | 
				
			||||||
static DevPrivateKeyRec glvXGLVClientPrivKey;
 | 
					static DevPrivateKeyRec glvXGLVClientPrivKey;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -187,6 +188,14 @@ GLXReset(ExtensionEntry *extEntry)
 | 
				
			||||||
    GlxVendorExtensionReset(extEntry);
 | 
					    GlxVendorExtensionReset(extEntry);
 | 
				
			||||||
    GlxDispatchReset();
 | 
					    GlxDispatchReset();
 | 
				
			||||||
    GlxMappingReset();
 | 
					    GlxMappingReset();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((dispatchException & DE_TERMINATE) == DE_TERMINATE) {
 | 
				
			||||||
 | 
					        while (vndInitCallbackList.list != NULL) {
 | 
				
			||||||
 | 
					            CallbackPtr next = vndInitCallbackList.list->next;
 | 
				
			||||||
 | 
					            free(vndInitCallbackList.list);
 | 
				
			||||||
 | 
					            vndInitCallbackList.list = next;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
| 
						 | 
					@ -220,7 +229,7 @@ GlxExtensionInit(void)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    GlxErrorBase = extEntry->errorBase;
 | 
					    GlxErrorBase = extEntry->errorBase;
 | 
				
			||||||
    CallCallbacks(&vndInitCallbackList, extEntry);
 | 
					    CallCallbacks(&vndInitCallbackListPtr, extEntry);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
| 
						 | 
					@ -280,7 +289,7 @@ _X_EXPORT const GlxServerExports glxServer = {
 | 
				
			||||||
    .majorVersion = 0,
 | 
					    .majorVersion = 0,
 | 
				
			||||||
    .minorVersion = 0,
 | 
					    .minorVersion = 0,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .extensionInitCallback = &vndInitCallbackList,
 | 
					    .extensionInitCallback = &vndInitCallbackListPtr,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .allocateServerImports = GlxAllocateServerImports,
 | 
					    .allocateServerImports = GlxAllocateServerImports,
 | 
				
			||||||
    .freeServerImports = GlxFreeServerImports,
 | 
					    .freeServerImports = GlxFreeServerImports,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue