Ticket #54 (reopened defect)

Opened 5 years ago

Last modified 4 years ago

Sporadic "Mutex destroy error (rpt)" with simple Python program

Reported by: josh Owned by: dsmith
Priority: major Milestone:
Component: libcwiid Version:
Keywords: Cc:

Description

I tried testing with the following Python program:

#!/usr/bin/env python
import sys
import cwiid

wiimotes = []

def main(args):
    while len(wiimotes) < 2:
        print "Waiting for wiimote %u" % (len(wiimotes) + 1)
        try:
            wiimotes.append(cwiid.Wiimote())
            if len(wiimotes) <= 4:
                wiimotes[-1].led = 1 << (len(wiimotes) - 1)
            else:
                wiimotes[-1].led = 15
            wiimotes[-1].rpt_mode = cwiid.RPT_BTN
        except RuntimeError, e:
            pass

    print "%u wiimotes connected" % len(wiimotes)

if __name__ == '__main__': sys.exit(main(sys.argv))

The first time I ran it, I got this output:

Waiting for wiimote 1
Waiting for wiimote 2
2 wiimotes connected
Mutex destroy error (rpt)

I have not seen the Mutex destroy error again since, but I wanted to report the problem.

Component "libcwiid" since the error in question comes from libcwiid, and I don't know how the Python module could cause this problem.

Attachments

j54-fix-data-races-and-mutex-destroy-error-I-think.patch Download (6.2 KB) - added by jonaskoelker 4 years ago.
Fix the mutex destroy error

Change History

Changed 5 years ago by josh

  • version 0.5.02 deleted

Changed 5 years ago by nickishappy

  • status changed from new to closed
  • resolution set to worksforme

I haven't been able to reproduce this on any of my machines.

Changed 5 years ago by dsmith

  • status changed from closed to reopened
  • resolution worksforme deleted

The bug is valid - I've duplicated it from time to time when exiting _immediately_ after creating the Wiimote object.

Changed 4 years ago by jonaskoelker

I've managed to reproduce it.

This happens in cwiid_close, where the pthread_mutex_destroy fails with EBUSY (whenever it fails, which is sometimes), indicating that the lock is already in use. I only see it being locked by update_rpt_mode, which is only called by cwiid_set_rpt_mode (and that's all it does).

I've attached a patch which adds a pthread cancellation cleanup handler to update_rpt_mode which unlocks the mutex. If I'm right, this should fix the issue.

The patch also fixes some data races, as reported by helgrind.

Changed 4 years ago by jonaskoelker

Fix the mutex destroy error

Changed 4 years ago by dsmith

Thanks for the patch, it's a start - a couple of comments:

  1. The mutex isn't there to protect the rpt_mode variable, it's there to make sure only one copy of update_rpt_mode is running at a time - note that the status thread also runs update_rpt_mode.
  2. IIRC, cwiid_open doesn't need to lock the mutexes - nothing else will happen in other threads until cwiid_request_status is called, which is the last thing in the cwiid_open.
  3. I agree with your diagnosis, but not your treatment. If update_rpt_mode is called from status thread, we're good, but if from another user thread through set_rpt_mode, we're still screwed.
  4. Who is helgrind, and what data races are these?
Note: See TracTickets for help on using tickets.