1

I have a thread that captures controller input. This is the only thing this thread does - it calls XInputGetState() every x milliseconds and stores the result in a synchronized circular buffer. I have another thread that reacts to this input by vibrating the controller via XInputSetState() when a certain condition has been reached.

In other words, one thread only ever calls XInputGetState(), while the other thread only ever calls XInputSetState(). Theoretically, there can be no point at which either function is being called multiple times simultaneously. Is it still unsafe to do this without synchronization?

Note: These two functions work on an entirely different set of data, but the implementation most likely reads/writes to something that isn't synchronized.

NmdMystery
  • 2,778
  • 3
  • 32
  • 60

2 Answers2

2

Yes in this case, because the XInput API takes a critical section lock on each external entry-point call.

BTW, as you are using XInput take a look at this blog post. With just those two APIs, you can use XInput 9.1.0 which is built-in to the Windows Vista and later OS, the headers for it are in the Windows 8.x SDK, and it avoids any need to mess with the legacy DirectSetup to deploy XInput 1.3. Of course, if you are using Windows Store apps, you'd just use XInput 1.4 which is part of the Windows 8.x OS and the headers are in the Windows 8.x SDK. The only situation where you need the use the legacy DirectX SDK is to get audio capture/playback support on Windows 7 or earlier.

Chuck Walbourn
  • 38,259
  • 2
  • 58
  • 81
  • If I understand correctly, XInput is then doing the synchronization for me. Doesn't that make it safe? – NmdMystery Jul 25 '14 at 23:25
  • 1
    "Thread-safe" yes, but not contention free depending on how you use them. – Chuck Walbourn Jul 26 '14 at 00:07
  • Ah, I see. I guess I'll use both functions on the input thread, and synchronize a vibration struct instead (Also, in regards to your edit, I'm using 9.1.0 since those two are all I ever need). – NmdMystery Jul 26 '14 at 00:12
0

"... and stores the result in a synchronized circular buffer. I have another thread that reacts to this input by..." directly contradicts your other statement: "there can be no point at which either function is being called simultaneously" because you are not guaranteed by the OS that your thread will finish processing whatever it is doing before it is pushed back into a waiting state.

In other words: in theory (and in practice, too!) your reading thread may be in the middle of pushing data into your shared buffer and be swapped out by the scheduler and a writing thread scheduled to run while the shared buffer is in the middle of being updated.

Generally speaking once you have more than one independent access to a shared resource (in your case - "a synchronized circular buffer") you are better off doing things right :)

If, in your scenario, you still decide to go with the unsafe solution you may end up having those pesky once-a-month-strange-thing-happened bugs that are next to impossible to debug.

YePhIcK
  • 5,816
  • 2
  • 27
  • 52
  • The way its synchronized makes it irrelevant whether or not the input thread is interrupted - I have a condition variable at the end of the frame, synchronized with a critical section, telling the other thread whether or not it can process any more input. I'm not worried about the buffer, though - I'm asking if XInputGetState and XInputSetState can safely be called at the same time, and by "neither function called simultaneously" I mean there are never two calls to XInputGetState happening at once, nor two calls to XInputSetState happening at once. – NmdMystery Jul 25 '14 at 23:14