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

Proof of Concept: Allow to prevent fork from happening in known fork unsafe API #10864

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

casperisfine
Copy link
Contributor

For better of for worse, fork(2) remain the primary provider of parallelism in Ruby programs. Even though it's frowned uppon in many circles, and a lot of literature will simply state that only async-signal safe APIs are safe to use after fork(), in practice most APIs work well as long as you are careful about not forking while another thread is holding a pthread mutex.

One of the APIs that is known cause fork safety issues is getaddrinfo. If you fork while another thread is inside getaddrinfo, a mutex may be left locked in the child, with no way to unlock it.

I think we could reduce the impact of these problem by preventing in for the most notorious and common cases, by locking around fork(2) and known unsafe APIs with a read-write lock.

FYI: @mame @beauraF

This comment has been minimized.

@@ -498,9 +524,6 @@ rb_getaddrinfo(const char *hostp, const char *portp, const struct addrinfo *hint
errno = err;
return EAI_SYSTEM;
}
pthread_detach(th);

rb_thread_call_without_gvl2(wait_getaddrinfo, arg, cancel_getaddrinfo, arg);
Copy link
Contributor

Choose a reason for hiding this comment

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

Was this deleted on purpose? it seems important to me! (it's the bit that actually waits on the condvar for the lookup to be done, right?)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nah, just a bad rebase I think, let me check.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, fixed it. It should have been replaced by fork_safe_async_getaddrinfo(arg);

…unsafe API

For better of for worse, fork(2) remain the primary provider of
parallelism in Ruby programs. Even though it's frowned uppon in
many circles, and a lot of literature will simply state that only
async-signal safe APIs are safe to use after `fork()`, in practice
most APIs work well as long as you are careful about not forking
while another thread is holding a pthread mutex.

One of the APIs that is known cause fork safety issues is `getaddrinfo`.
If you fork while another thread is inside `getaddrinfo`, a mutex
may be left locked in the child, with no way to unlock it.

I think we could reduce the impact of these problem by preventing
in for the most notorious and common cases, by locking around
`fork(2)` and known unsafe APIs with a read-write lock.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
3 participants