Make SDL_VideoInit cleanup when errors occur before video driver creation.

This commit is contained in:
Erik Soma 2021-11-23 17:56:46 -05:00 committed by Sam Lantinga
parent 8ed0cc4300
commit 71e3998d6c
1 changed files with 42 additions and 7 deletions

View File

@ -465,6 +465,10 @@ SDL_VideoInit(const char *driver_name)
SDL_VideoDevice *video; SDL_VideoDevice *video;
int index; int index;
int i; int i;
SDL_bool init_events = SDL_FALSE;
SDL_bool init_keyboard = SDL_FALSE;
SDL_bool init_mouse = SDL_FALSE;
SDL_bool init_touch = SDL_FALSE;
/* Check to make sure we don't overwrite '_this' */ /* Check to make sure we don't overwrite '_this' */
if (_this != NULL) { if (_this != NULL) {
@ -476,12 +480,22 @@ SDL_VideoInit(const char *driver_name)
#endif #endif
/* Start the event loop */ /* Start the event loop */
if (SDL_InitSubSystem(SDL_INIT_EVENTS) < 0 || if (SDL_InitSubSystem(SDL_INIT_EVENTS) < 0) {
SDL_KeyboardInit() < 0 || goto pre_driver_error;
SDL_MouseInit() < 0 ||
SDL_TouchInit() < 0) {
return -1;
} }
init_events = SDL_TRUE;
if (SDL_KeyboardInit() < 0) {
goto pre_driver_error;
}
init_keyboard = SDL_TRUE;
if (SDL_MouseInit() < 0) {
goto pre_driver_error;
}
init_mouse = SDL_TRUE;
if (SDL_TouchInit() < 0) {
goto pre_driver_error;
}
init_touch = SDL_TRUE;
/* Select the proper video driver */ /* Select the proper video driver */
i = index = 0; i = index = 0;
@ -516,10 +530,15 @@ SDL_VideoInit(const char *driver_name)
} }
if (video == NULL) { if (video == NULL) {
if (driver_name) { if (driver_name) {
return SDL_SetError("%s not available", driver_name); SDL_SetError("%s not available", driver_name);
goto pre_driver_error;
} }
return SDL_SetError("No available video device"); SDL_SetError("No available video device");
goto pre_driver_error;
} }
/* From this point on, use SDL_VideoQuit to cleanup on error, rather than
pre_driver_error. */
_this = video; _this = video;
_this->name = bootstrap[i]->name; _this->name = bootstrap[i]->name;
_this->next_object_id = 1; _this->next_object_id = 1;
@ -575,6 +594,22 @@ SDL_VideoInit(const char *driver_name)
/* We're ready to go! */ /* We're ready to go! */
return 0; return 0;
pre_driver_error:
SDL_assert(_this == NULL);
if (init_touch) {
SDL_TouchQuit();
}
if (init_mouse) {
SDL_MouseQuit();
}
if (init_keyboard) {
SDL_KeyboardQuit();
}
if (init_events) {
SDL_QuitSubSystem(SDL_INIT_EVENTS);
}
return -1;
} }
const char * const char *