Make SDL_VideoInit cleanup when errors occur before video driver creation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index accba17..ff55308 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -465,6 +465,10 @@ SDL_VideoInit(const char *driver_name)
SDL_VideoDevice *video;
int index;
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' */
if (_this != NULL) {
@@ -476,12 +480,22 @@ SDL_VideoInit(const char *driver_name)
#endif
/* Start the event loop */
- if (SDL_InitSubSystem(SDL_INIT_EVENTS) < 0 ||
- SDL_KeyboardInit() < 0 ||
- SDL_MouseInit() < 0 ||
- SDL_TouchInit() < 0) {
- return -1;
+ if (SDL_InitSubSystem(SDL_INIT_EVENTS) < 0) {
+ goto pre_driver_error;
+ }
+ 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 */
i = index = 0;
@@ -516,10 +530,15 @@ SDL_VideoInit(const char *driver_name)
}
if (video == NULL) {
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->name = bootstrap[i]->name;
_this->next_object_id = 1;
@@ -575,6 +594,22 @@ SDL_VideoInit(const char *driver_name)
/* We're ready to go! */
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 *