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

Fix parallel access crashes and misbehavior #136

Merged
merged 9 commits into from
Jun 26, 2024

Conversation

jmid
Copy link
Contributor

@jmid jmid commented Apr 16, 2024

Parallel usage is memory unsafe (read: may crash) as documented in #120, ocaml/ocaml#11607, and ocaml/ocaml#13046.

This PR goes for the simplest possible fix: adding a single global lock by dusting off the first commit of https://github.com/dra27/flexdll/tree/sledgehammer and suitable rebasing, renaming, and error handling.
Author credit thus goes to @dra27 - any errors are mine.

For the error handling, I've tried to make it fit with @shym's TLS-based error handling from #112.
I'm unsure how to test these error code paths though without explicitly mocking with the source code to create an invalid lock handle.

With the fix

(these have been tested under MinGW in a Cygwin-shell)

flexdll.c Show resolved Hide resolved
flexdll.c Outdated Show resolved Hide resolved
flexdll.c Outdated Show resolved Hide resolved
flexdll.c Outdated
goto again;
}
} else {
if (WaitForSingleObject(units_mutex, INFINITE) == WAIT_FAILED) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (WaitForSingleObject(units_mutex, INFINITE) == WAIT_FAILED) {
if (WaitForSingleObject(units_mutex, INFINITE) != WAIT_OBJECT_0) {

This would cover the improbable (impossible?) case of the mutex having been abandoned.
https://learn.microsoft.com/en-us/windows/win32/sync/using-mutex-objects

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ended up reverting this one.

WAIT_ABANDONED does not offer GetLastError-integration, so I started adding an explicit error message case for it - only to then hit it during testing.

I therefore suppose these two cases were written to handle both WAIT_OBJECT_0 and WAIT_ABANDONED as success-cases (WAIT_TIMEOUT should not happen with INFINITE...)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My reasoning I think is that WAIT_ABANDONED should be treated like success?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(i.e. I agree with @jmid's assessment!)

err = get_tls_error(TLS_ERROR_NOP);
if(err == NULL) return NULL;

if (WaitForSingleObject(units_mutex, INFINITE) == WAIT_FAILED) {
Copy link
Contributor

@MisterDA MisterDA Apr 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (WaitForSingleObject(units_mutex, INFINITE) == WAIT_FAILED) {
if (WaitForSingleObject(units_mutex, INFINITE) != WAIT_OBJECT_0) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(same for this one)

flexdll.c Outdated Show resolved Hide resolved
flexdll.c Outdated Show resolved Hide resolved
@jmid jmid force-pushed the single-global-lock-par-fix branch from 217db5d to 67efa7d Compare April 18, 2024 17:06
Copy link
Contributor

@MisterDA MisterDA left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tested an finally understood why the code is correct, thanks Jan! I think this is good to go.
Minor suggestion still.

flexdll.c Outdated Show resolved Hide resolved
@jmid jmid force-pushed the single-global-lock-par-fix branch from 47480bc to 4950924 Compare May 16, 2024 12:35
@jmid
Copy link
Contributor Author

jmid commented May 16, 2024

I've addressed the last minor comment, added a CHANGES entry, and rebased on master.

@dra27 dra27 merged commit 5719f5a into ocaml:master Jun 26, 2024
1 check passed
@dra27
Copy link
Member

dra27 commented Jun 26, 2024

Thank you both for your work on this, and sorry for taking quite so long to merge it!

@jmid jmid deleted the single-global-lock-par-fix branch June 26, 2024 08:53
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.

3 participants