Skip to content

Commit ecb620c

Browse files
committed
Make pressedButtons more thread-safe
I'm not sure if this is 100% thread safe, but it's better than before. In the worst case, a button is stuck pressed down, and the user has to press it again to unstuck it.
1 parent 540aa63 commit ecb620c

File tree

1 file changed

+8
-6
lines changed

1 file changed

+8
-6
lines changed

osu.Framework/Platform/SDL3/SDL3Window_Input.cs

+8-6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Collections.Generic;
66
using System.Diagnostics;
77
using System.Drawing;
8+
using System.Threading;
89
using osu.Framework.Bindables;
910
using osu.Framework.Configuration;
1011
using osu.Framework.Extensions.EnumExtensions;
@@ -151,11 +152,12 @@ private void enqueueJoystickButtonInput(JoystickButton button, bool isPressed)
151152

152153
private PointF previousPolledPoint = PointF.Empty;
153154

154-
private SDL_MouseButtonFlags pressedButtons;
155+
private volatile uint pressedButtons;
155156

156157
private void pollMouse()
157158
{
158159
float x, y;
160+
var pressed = (SDL_MouseButtonFlags)pressedButtons;
159161
SDL_MouseButtonFlags globalButtons = SDL_GetGlobalMouseState(&x, &y);
160162

161163
if (previousPolledPoint.X != x || previousPolledPoint.Y != y)
@@ -170,18 +172,18 @@ private void pollMouse()
170172
}
171173

172174
// a button should be released if it was pressed and its current global state differs (its bit in globalButtons is set to 0)
173-
SDL_MouseButtonFlags buttonsToRelease = pressedButtons & (globalButtons ^ pressedButtons);
175+
SDL_MouseButtonFlags buttonsToRelease = pressed & (globalButtons ^ pressed);
174176

175177
// the outer if just optimises for the common case that there are no buttons to release.
176178
if (buttonsToRelease != 0)
177179
{
180+
Interlocked.And(ref pressedButtons, (uint)~buttonsToRelease);
181+
178182
if (buttonsToRelease.HasFlagFast(SDL_MouseButtonFlags.SDL_BUTTON_LMASK)) MouseUp?.Invoke(MouseButton.Left);
179183
if (buttonsToRelease.HasFlagFast(SDL_MouseButtonFlags.SDL_BUTTON_MMASK)) MouseUp?.Invoke(MouseButton.Middle);
180184
if (buttonsToRelease.HasFlagFast(SDL_MouseButtonFlags.SDL_BUTTON_RMASK)) MouseUp?.Invoke(MouseButton.Right);
181185
if (buttonsToRelease.HasFlagFast(SDL_MouseButtonFlags.SDL_BUTTON_X1MASK)) MouseUp?.Invoke(MouseButton.Button1);
182186
if (buttonsToRelease.HasFlagFast(SDL_MouseButtonFlags.SDL_BUTTON_X2MASK)) MouseUp?.Invoke(MouseButton.Button2);
183-
184-
pressedButtons &= ~buttonsToRelease;
185187
}
186188
}
187189

@@ -465,12 +467,12 @@ private void handleMouseButtonEvent(SDL_MouseButtonEvent evtButton)
465467
switch (evtButton.type)
466468
{
467469
case SDL_EventType.SDL_EVENT_MOUSE_BUTTON_DOWN:
468-
pressedButtons |= mask;
469470
MouseDown?.Invoke(button);
471+
Interlocked.Or(ref pressedButtons, (uint)mask);
470472
break;
471473

472474
case SDL_EventType.SDL_EVENT_MOUSE_BUTTON_UP:
473-
pressedButtons &= ~mask;
475+
Interlocked.And(ref pressedButtons, (uint)~mask);
474476
MouseUp?.Invoke(button);
475477
break;
476478
}

0 commit comments

Comments
 (0)