-
Notifications
You must be signed in to change notification settings - Fork 792
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
Make gil tests not racy #2190
Make gil tests not racy #2190
Conversation
While the extend test case looks basically sound to me, it is also quite complex. I wonder whether these test cases are special enough to be put into a separate integration test so that it would be known that only test case is executed in the process and the previous much simpler implementation could be used? (This would also close some more theoretical objects, for example in the current implementation, another test case could acquire the GIL between this test case releasing it and the background thread created by it acquiring thereby masking if one or more acquisitions of the GIL happened between the synchronization points.) (If a single integration test per test case is too much, maybe it could be a an integration test with only a few test cases all of which hold a common mutex for their whole duration thereby having single-threaded test execution independently of the number of test threads.) |
These tests don't use unsafe anymore, what do you mean with "unsound"?
I don't think they are any more or less special than the other tests so I'm not sure. Fwiw,
Other threads shouldn't be able to interfere with these tests, I think I got the synchronization right so that the GIL is always held during the critical sections (I hope I didn't mess up). |
I did not mean the technical term "soundness" w.r.t. the type system but rather the colloquial form just meaning "correct."
I also think the synchronization is correct insofar the GIL will have been dropped after 2. and re-acquired after 3., but I think it is still possible that another thread might acquire and release the GIL between 2. and 3. so that 3. is not really checking that acquiring the GIL once will immediately update the reference. (As said, I think this is a rather theoretical concern as it would only mask a failure mode where the GIL would need to be acquired multiple times instead of just once to update the reference counts. And mask it unreliably at that.) |
Hhhmmm, I think that the // The pointer should appear once in the incref pool, and once in the
// decref pool (for the clone being created and also dropped)
assert_eq!(&*POOL.pointer_ops.lock().0, &[ptr]);
assert_eq!(&*POOL.pointer_ops.lock().1, &[ptr]); and // Acquiring the gil clears the pool
assert!(POOL.pointer_ops.lock().0.is_empty());
assert!(POOL.pointer_ops.lock().1.is_empty()); and probably too strict as other test threads could use Which brings me back to thinking that isolating these tests within a separate process would really simplify this stuff. Of course, I also do not want to make what is essentially a bug fix unnecessarily complex and would not oppose merging this as-is. One more idea to make process isolation simpler: Instead of integration tests, we could "just" execute the test binary using |
Hmm, that is true...
Right, that's what I'm thinking too. I just don't want to give the impression (to anyone looking at the tests) that reading the refcount while not holding the GIL is okay. |
What's the plan here? Sounds like we didn't want to overcomplicate... should I merge as-is? |
Almost. I think we should still fix the assertions on the content of |
Changes the refcount checking to happen from a thread that's actually holding the GIL.
Per #2181 (comment)