mirror of
				https://github.com/Ryujinx/SDL.git
				synced 2025-11-04 15:04:51 +00:00 
			
		
		
		
	Hold the joystick lock while opening the HID device on non-Android platforms
On Windows the main thread can be enumerating DirectInput devices while the Windows.Gaming.Input thread is calling back with a new controller available, and in this case HIDAPI_IsDevicePresent() returned false since the controller initialization hadn't completed yet, creating a duplicate controller. Fixes https://github.com/libsdl-org/SDL/issues/7304 (cherry picked from commit ece8a7bb8e2dae9cb53115980cea9ef1213a0160)
This commit is contained in:
		
							parent
							
								
									d948e6c3c5
								
							
						
					
					
						commit
						e86f494317
					
				| 
						 | 
					@ -380,44 +380,65 @@ static void HIDAPI_SetupDeviceDriver(SDL_HIDAPI_Device *device, SDL_bool *remove
 | 
				
			||||||
    if (HIDAPI_GetDeviceDriver(device)) {
 | 
					    if (HIDAPI_GetDeviceDriver(device)) {
 | 
				
			||||||
        /* We might have a device driver for this device, try opening it and see */
 | 
					        /* We might have a device driver for this device, try opening it and see */
 | 
				
			||||||
        if (device->num_children == 0) {
 | 
					        if (device->num_children == 0) {
 | 
				
			||||||
 | 
					            SDL_hid_device *dev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /* Wait a little bit for the device to initialize */
 | 
				
			||||||
 | 
					            SDL_Delay(10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __ANDROID__
 | 
				
			||||||
            /* On Android we need to leave joysticks unlocked because it calls
 | 
					            /* On Android we need to leave joysticks unlocked because it calls
 | 
				
			||||||
             * out to the main thread for permissions and the main thread can
 | 
					             * out to the main thread for permissions and the main thread can
 | 
				
			||||||
             * be in the process of handling controller input.
 | 
					             * be in the process of handling controller input.
 | 
				
			||||||
             *
 | 
					             *
 | 
				
			||||||
             * See https://github.com/libsdl-org/SDL/issues/6347 for details
 | 
					             * See https://github.com/libsdl-org/SDL/issues/6347 for details
 | 
				
			||||||
             */
 | 
					             */
 | 
				
			||||||
            int lock_count = 0;
 | 
					            {
 | 
				
			||||||
            SDL_HIDAPI_Device *curr;
 | 
					                SDL_HIDAPI_Device *curr;
 | 
				
			||||||
            SDL_hid_device *dev;
 | 
					                int lock_count = 0;
 | 
				
			||||||
            char *path = SDL_strdup(device->path);
 | 
					                char *path = SDL_strdup(device->path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /* Wait a little bit for the device to initialize */
 | 
					                /* Wait a little bit for the device to initialize */
 | 
				
			||||||
            SDL_Delay(10);
 | 
					                SDL_Delay(10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            SDL_AssertJoysticksLocked();
 | 
					                SDL_AssertJoysticksLocked();
 | 
				
			||||||
            while (SDL_JoysticksLocked()) {
 | 
					                while (SDL_JoysticksLocked()) {
 | 
				
			||||||
                ++lock_count;
 | 
					                    ++lock_count;
 | 
				
			||||||
                SDL_UnlockJoysticks();
 | 
					                    SDL_UnlockJoysticks();
 | 
				
			||||||
            }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            dev = SDL_hid_open_path(path, 0);
 | 
					                dev = SDL_hid_open_path(path, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            while (lock_count > 0) {
 | 
					                while (lock_count > 0) {
 | 
				
			||||||
                --lock_count;
 | 
					                    --lock_count;
 | 
				
			||||||
                SDL_LockJoysticks();
 | 
					                    SDL_LockJoysticks();
 | 
				
			||||||
            }
 | 
					                }
 | 
				
			||||||
            SDL_free(path);
 | 
					                SDL_free(path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /* Make sure the device didn't get removed while opening the HID path */
 | 
					                /* Make sure the device didn't get removed while opening the HID path */
 | 
				
			||||||
            for (curr = SDL_HIDAPI_devices; curr && curr != device; curr = curr->next) {
 | 
					                for (curr = SDL_HIDAPI_devices; curr && curr != device; curr = curr->next) {
 | 
				
			||||||
            }
 | 
					                    continue;
 | 
				
			||||||
            if (curr == NULL) {
 | 
					                }
 | 
				
			||||||
                *removed = SDL_TRUE;
 | 
					                if (curr == NULL) {
 | 
				
			||||||
                if (dev) {
 | 
					                    *removed = SDL_TRUE;
 | 
				
			||||||
                    SDL_hid_close(dev);
 | 
					                    if (dev) {
 | 
				
			||||||
 | 
					                        SDL_hid_close(dev);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                return;
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					            /* On other platforms we want to keep the lock so other threads wait for
 | 
				
			||||||
 | 
					             * us to finish opening the controller before checking to see whether the
 | 
				
			||||||
 | 
					             * HIDAPI driver is handling the device.
 | 
				
			||||||
 | 
					             *
 | 
				
			||||||
 | 
					             * On Windows, for example, the main thread can be enumerating DirectInput
 | 
				
			||||||
 | 
					             * devices while the Windows.Gaming.Input thread is calling back with a new
 | 
				
			||||||
 | 
					             * controller available.
 | 
				
			||||||
 | 
					             *
 | 
				
			||||||
 | 
					             * See https://github.com/libsdl-org/SDL/issues/7304 for details.
 | 
				
			||||||
 | 
					             */
 | 
				
			||||||
 | 
					            dev = SDL_hid_open_path(device->path, 0);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (dev == NULL) {
 | 
					            if (dev == NULL) {
 | 
				
			||||||
                SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
 | 
					                SDL_LogDebug(SDL_LOG_CATEGORY_INPUT,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue