Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GCAdapter: improve thread safety #3805

Merged
merged 2 commits into from
May 19, 2016

Conversation

mathieui
Copy link
Member

@mathieui mathieui commented Apr 30, 2016

make sure Reset() can’t be run concurrently with AddGCAdapter(), which can cause crashes (issue #9462).

As the crash happens only on windows, I can’t test this.


This change is Reviewable

@phire
Copy link
Member

phire commented Apr 30, 2016

Well it fixes the crash.

But the multithreading code still looks a bit messy.

@mathieui
Copy link
Member Author

Well, the multithreading code is a bit spotty but I don’t see any easy way around it as we can’t block the CPU thread and need another thread to fetch data from the controller; doing away with the scanning thread is kind of difficult if we don’t want users to have a manual interaction (we probably could make it run only when there is no adapter detected, although it may cause issues).

We could put everything which isn’t on the CPU thread behind a mutex, but it may be a brutal thing to do.

@phire
Copy link
Member

phire commented Apr 30, 2016

What's worrying me is I looked up libusb, and it's supposed to be thread safe.

Yet somehow we are getting errors. Also s_handle and s_detected are set/accessed on multiple threads and should be atomic.

@Sonicadvance1
Copy link
Contributor

Maybe you should glean some ideas of how to make it stable by looking at my Android implementation? :P

@JMC47
Copy link
Contributor

JMC47 commented Apr 30, 2016

Fixes my crash finally. I'm happy.

@@ -37,6 +37,7 @@ static std::atomic<int> s_controller_payload_size = {0};
static std::thread s_adapter_thread;
static Common::Flag s_adapter_thread_running;

static std::recursive_mutex s_init_mutex;

This comment was marked as off-topic.

This comment was marked as off-topic.

@Parlane Parlane added the WIP / do not merge Work in progress (do not merge) label May 3, 2016
@JMC47
Copy link
Contributor

JMC47 commented May 4, 2016

Are we going to review/merge this, or pursue a better solution?

@mimimi085181
Copy link
Contributor

@mathieui: Is this still WIP?

@mathieui
Copy link
Member Author

@mimimi085181 This should be fine now, one last code review to make sure I haven’t missed a spot, and maybe another test from @JMC47 before merging.

@mathieui mathieui changed the title [WIP] GCAdapter: improve thread safety GCAdapter: improve thread safety May 12, 2016
@Parlane Parlane removed the WIP / do not merge Work in progress (do not merge) label May 12, 2016
@JMC47
Copy link
Contributor

JMC47 commented May 12, 2016

It's crashed in master about 6 more times since I last reviewed it. I really need to just generally use this build in master to know for sure the crash is completely gone. I think it is though.

@JMC47
Copy link
Contributor

JMC47 commented May 14, 2016

Is this ready for review?

@JMC47
Copy link
Contributor

JMC47 commented May 14, 2016

This actually fixes both of my GC Adapter crashes. The one running two dolphin's and closing the first one that has the GC adapter used to crash the second Dolphin. It no longer does that in this pull request.

@RisingFog
Copy link
Member

Review status: 0 of 1 files reviewed at latest revision, 2 unresolved discussions.


Source/Core/InputCommon/GCAdapter.cpp, line 476 [r3] (raw file):

  DEBUG_LOG(SERIALINTERFACE, "Rumble state reset");
}

Unnecessary extra line.


Comments from Reviewable

@mathieui
Copy link
Member Author

Review status: 0 of 1 files reviewed at latest revision, 2 unresolved discussions.


Source/Core/InputCommon/GCAdapter.cpp, line 476 [r3] (raw file):

Previously, RisingFog (Chris Burgener) wrote…

Unnecessary extra line.


Done.


Comments from Reviewable

@RisingFog
Copy link
Member

Reviewed 1 of 1 files at r4.
Review status: all files reviewed at latest revision, 1 unresolved discussion.


Comments from Reviewable

@JMC47
Copy link
Contributor

JMC47 commented May 14, 2016

LGTM

@RisingFog
Copy link
Member

Anything holding this up from merge?

@degasus
Copy link
Member

degasus commented May 18, 2016

Review status: all files reviewed at latest revision, 2 unresolved discussions.


Source/Core/InputCommon/GCAdapter.cpp, line 454 [r4] (raw file):

void ResetRumble()
{
  if (!s_init_mutex.try_lock())

May you add a comment why this is required? eg in which path is it already locked, and why it's not needed to call this function here.


Comments from Reviewable

@degasus
Copy link
Member

degasus commented May 18, 2016

Reviewed 1 of 1 files at r4.
Review status: all files reviewed at latest revision, 2 unresolved discussions.


Comments from Reviewable

@lioncash
Copy link
Member

Source/Core/InputCommon/GCAdapter.cpp, line 456 [r4] (raw file):

  if (!s_init_mutex.try_lock())
      return;
  ResetRumbleNoLock();

This name is kind of misleading. It has "NoLock" in the name, yet is being used between a mutex that is trying to be locked, effectively stating the opposite of what the function name intends.


Comments from Reviewable

@lioncash
Copy link
Member

Review status: all files reviewed at latest revision, 5 unresolved discussions.


Source/Core/InputCommon/GCAdapter.cpp, line 338 [r4] (raw file):

void Reset()
{
  if (!s_init_mutex.try_lock())

Now that I look at this again, this can just be:

std::unique_lock<std::mutex> lock(s_init_mutex, std::defer_lock);
if (!lock.try_lock())
    return;

which would let you get rid of the explicit locking and unlocking elsewhere.


Source/Core/InputCommon/GCAdapter.cpp, line 454 [r4] (raw file):

void ResetRumble()
{
  if (!s_init_mutex.try_lock())

This can also be:

std::unique_lock<std::mutex> lock(s_init_mutex, std::defer_lock);
if (!lock.try_lock())
    return;

Comments from Reviewable

make sure Reset() can’t be run concurrently with AddGCAdapter() or
ResetRumble() (which is called on other threads) which can cause
crashes (issue dolphin-emu#9462)
@mathieui
Copy link
Member Author

Review status: 0 of 1 files reviewed at latest revision, 5 unresolved discussions.


Source/Core/InputCommon/GCAdapter.cpp, line 338 [r4] (raw file):

Previously, lioncash (Mat M.) wrote…

Now that I look at this again, this can just be:

std::unique_lock<std::mutex> lock(s_init_mutex, std::defer_lock);
if (!lock.try_lock())
    return;

which would let you get rid of the explicit locking and unlocking elsewhere.

Thanks for the tip, done.

Source/Core/InputCommon/GCAdapter.cpp, line 454 [r4] (raw file):

Previously, lioncash (Mat M.) wrote…

This can also be:

std::unique_lock<std::mutex> lock(s_init_mutex, std::defer_lock);
if (!lock.try_lock())
    return;
Done.

Source/Core/InputCommon/GCAdapter.cpp, line 454 [r4] (raw file):

Previously, degasus (Markus Wick) wrote…

May you add a comment why this is required? eg in which path is it already locked, and why it's not needed to call this function here.

Done in the comment for ResetRumbleLockNeeded()

Source/Core/InputCommon/GCAdapter.cpp, line 456 [r4] (raw file):

Previously, lioncash (Mat M.) wrote…

This name is kind of misleading. It has "NoLock" in the name, yet is being used between a mutex that is trying to be locked, effectively stating the opposite of what the function name intends.

Done.

Comments from Reviewable

@RisingFog
Copy link
Member

Reviewed 1 of 1 files at r6.
Review status: all files reviewed at latest revision, 1 unresolved discussion.


Comments from Reviewable

Reset() and Setup() are not used outside of this namespace
@degasus
Copy link
Member

degasus commented May 19, 2016

:lgtm:

Previously, RisingFog (Chris Burgener) wrote…

Anything holding this up from merge?


Reviewed 2 of 2 files at r7, 2 of 2 files at r8.
Review status: all files reviewed at latest revision, all discussions resolved.


Comments from Reviewable

@degasus degasus added this to the Dolphin Release 5.0 milestone May 19, 2016
@degasus degasus merged commit bb6604d into dolphin-emu:master May 19, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
9 participants