Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Doc/c-api/init.rst
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ Additionally, when extending or embedding Python, calling :c:func:`fork`
directly rather than through :func:`os.fork` (and returning to or calling
into Python) may result in a deadlock by one of Python's internal locks
being held by a thread that is defunct after the fork.
:c:func:`PyOS_AfterFork` tries to reset the necessary locks, but is not
:c:func:`PyOS_AfterFork_Child` tries to reset the necessary locks, but is not
Copy link
Member

Choose a reason for hiding this comment

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

Is it worth to update the first part of this paragraph according to new API?

Copy link
Member Author

Choose a reason for hiding this comment

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

Which part exactly?

Copy link
Member

Choose a reason for hiding this comment

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

"there is no way to inform Python of additional (non-Python) locks that need to be acquired before or reset after a fork" and mentioning pthread_atfork.

always able to.


Expand Down Expand Up @@ -675,9 +675,9 @@ code, or when embedding the Python interpreter:

.. c:function:: void PyEval_ReInitThreads()

This function is called from :c:func:`PyOS_AfterFork` to ensure that newly
created child processes don't hold locks referring to threads which
are not running in the child process.
This function is called from :c:func:`PyOS_AfterFork_Child` to ensure
that newly created child processes don't hold locks referring to threads
which are not running in the child process.


The following functions use thread-local storage, and are not compatible
Expand Down
9 changes: 9 additions & 0 deletions Doc/whatsnew/3.7.rst
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ Serhiy Storchaka in :issue:`28682`.)
Added support for :ref:`file descriptors <path_fd>` in :func:`~os.scandir`
on Unix. (Contributed by Serhiy Storchaka in :issue:`25996`.)

New function :func:`os.register_at_fork` allows registering Python callbacks
to be executed on a process fork. (Contributed by Antoine Pitrou in
:issue:`16500`.)

unittest.mock
-------------

Expand Down Expand Up @@ -243,6 +247,11 @@ Build and C API Changes
* Added functions :c:func:`PySlice_Unpack` and :c:func:`PySlice_AdjustIndices`.
(Contributed by Serhiy Storchaka in :issue:`27867`.)

* :c:func:`PyOS_AfterFork` is deprecated in favour of the new functions
:c:func:`PyOS_BeforeFork`, :c:func:`PyOS_AfterFork_Parent` and
:c:func:`PyOS_AfterFork_Child`. (Contributed by Antoine Pitrou in
:issue:`16500`.)


Deprecated
==========
Expand Down
4 changes: 2 additions & 2 deletions Lib/threading.py
Original file line number Diff line number Diff line change
Expand Up @@ -1320,8 +1320,8 @@ def main_thread():

def _after_fork():
# This function is called by Python/ceval.c:PyEval_ReInitThreads which
# is called from PyOS_AfterFork. Here we cleanup threading module state
# that should not exist after a fork.
# is called from PyOS_AfterFork_Child. Here we cleanup threading module
# state that should not exist after a fork.

# Reset _active_limbo_lock, in case we forked while the lock was held
# by another (non-forked) thread. http://bugs.python.org/issue874900
Expand Down
3 changes: 3 additions & 0 deletions Misc/NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -1052,6 +1052,9 @@ Windows
C API
-----

- bpo-16500: Deprecate PyOS_AfterFork() and add PyOS_BeforeFork(),
PyOS_AfterFork_Parent() and PyOS_AfterFork_Child().

- bpo-6532: The type of results of PyThread_start_new_thread() and
PyThread_get_thread_ident(), and the id parameter of
PyThreadState_SetAsyncExc() changed from "long" to "unsigned long".
Expand Down
8 changes: 4 additions & 4 deletions Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,10 +232,10 @@ PyEval_ReleaseThread(PyThreadState *tstate)
drop_gil(tstate);
}

/* This function is called from PyOS_AfterFork to destroy all threads which are
* not running in the child process, and clear internal locks which might be
* held by those threads. (This could also be done using pthread_atfork
* mechanism, at least for the pthreads implementation.) */
/* This function is called from PyOS_AfterFork_Child to destroy all threads
* which are not running in the child process, and clear internal locks
* which might be held by those threads.
*/

void
PyEval_ReInitThreads(void)
Expand Down
2 changes: 1 addition & 1 deletion Python/import.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ _PyImport_ReleaseLock(void)
return 1;
}

/* This function is called from PyOS_AfterFork to ensure that newly
/* This function is called from PyOS_AfterFork_Child to ensure that newly
created child processes do not share locks with the parent.
We now acquire the import lock around fork() calls but on some platforms
(Solaris 9 and earlier? see isue7242) that still left us with problems. */
Expand Down
2 changes: 1 addition & 1 deletion Python/pystate.c
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,7 @@ _PyGILState_Fini(void)
autoInterpreterState = NULL;
}

/* Reset the TLS key - called by PyOS_AfterFork().
/* Reset the TLS key - called by PyOS_AfterFork_Child().
* This should not be necessary, but some - buggy - pthread implementations
* don't reset TLS upon fork(), see issue #10517.
*/
Expand Down
2 changes: 1 addition & 1 deletion Python/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ PyThread_delete_key_value(int key)
}

/* Forget everything not associated with the current thread id.
* This function is called from PyOS_AfterFork(). It is necessary
* This function is called from PyOS_AfterFork_Child(). It is necessary
* because other thread ids which were in use at the time of the fork
* may be reused for new threads created in the forked process.
*/
Expand Down