Skip to content

Conversation

@ngoldbaum
Copy link

@ngoldbaum ngoldbaum commented Sep 8, 2025

Closes #467

This adds support for Python 3.14 and 3.14t as well as supporting free-threaded Python.

I've opted to add a threading.RLock member to the SoundFile object. I also made it so all the public methods of SoundFile that access the _file handle need to acquire the lock via a new with_lock decorator.

I'm using an RLock to avoid the need to refactor to avoid possibly reentrancy. I can probably use a threading.Lock instead but it will be trickier to get right.

Also adds tests for supported workflows (each thread has its own SoundFile) as well as unsupported workflows.

You could also support the free-threaded build without adding the locking. IMO the locking is a nicer user experience. With this approach if you try to use a SoundFile object in more than one thread simultaneously, you will see a RuntimeError if there is any concurrent use. Since I'm using the non-blocking variant of RLock.acquire(), it's impossible for this to introduce new scaling issues. Acquiring an uncontended lock is very low-overhead so I don't expect this to add much overhead.

I ran the tests under TSan and didn't see any issues besides a known race in BytesIO in 3.14 that should be fixed in 3.14.1. I can add TSan CI as a followup if you'd like.

@ngoldbaum
Copy link
Author

@bastibe gentle ping on this. If you'd like any help on my end with other maintenance tasks on the repo I'm also happy to do that, especially if that makes you more likely to help me ship this!

@bastibe
Copy link
Owner

bastibe commented Oct 15, 2025

I'm sorry for not being able to work on this at the moment. Fall is a very busy time for me. I hope I'll be able to have a look on the weekend.

@bastibe
Copy link
Owner

bastibe commented Jan 10, 2026

Sorry for not responding for so long. It was indeed an incredibly busy time for me.

At any rate, I've had a look now. This pull request adds a lock to each soundfile object, thereby preventing any concurrent use. This prevents crashes if you write code that accesses the same soundfile object from multiple threads.

However, I am a bit hesitant about this, as it doesn't fix concurrency, but merely prevents it. It's certainly a better user experience to throw an exception instead of crashing with a segfault, but I'm not sure if this is actually helping.

I've not followed the multi-threaded python development particularly closely. What is the common pattern for dealing with non-thread-safe code? Do we expect all non-thread-safe code to secure itself?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support the Python 3.14t free-threaded build

2 participants