cp -rf py3.8/examples .
cp -rf py3.8/doc .
cp -f py3.8/index.html .
cp -rf py3.8/_multiprocess _multiprocess
cp -rf py3.8/multiprocess multiprocess 
cp -rf py3.8/Modules Modules 
cp Python-3.9.2/Lib/test/mp_*py multiprocess/tests
cp Python-3.9.2/Lib/test/_test_multiprocessing.py multiprocess/tests/__init__.py

# ----------------------------------------------------------------------
diff Python-3.8.1/Modules/_multiprocessing/multiprocessing.h Python-3.9.0a2/Modules/_multiprocessing/multiprocessing.h
30,37d29
< #  define HANDLE int
< #  define SOCKET int
< #  define BOOL int
< #  define UINT32 uint32_t
< #  define INT32 int32_t
< #  define TRUE 1
< #  define FALSE 0
< #  define INVALID_HANDLE_VALUE (-1)
75,76d66
< #  define F_DWORD "k"
< #  define T_DWORD T_ULONG
# ----------------------------------------------------------------------
diff Python-3.8.1/Lib/multiprocessing/managers.py Python-3.9.0a2/Lib/multiprocessing/managers.py
251c251
<                     except KeyError as second_ke:
---
>                     except KeyError:
299c299
<                 except Exception as e:
---
>                 except Exception:
363c363
<     def create(*args, **kwds):
---
>     def create(self, c, typeid, /, *args, **kwds):
367,392d366
<         if len(args) >= 3:
<             self, c, typeid, *args = args
<         elif not args:
<             raise TypeError("descriptor 'create' of 'Server' object "
<                             "needs an argument")
<         else:
<             if 'typeid' not in kwds:
<                 raise TypeError('create expected at least 2 positional '
<                                 'arguments, got %d' % (len(args)-1))
<             typeid = kwds.pop('typeid')
<             if len(args) >= 2:
<                 self, c, *args = args
<                 import warnings
<                 warnings.warn("Passing 'typeid' as keyword argument is deprecated",
<                               DeprecationWarning, stacklevel=2)
<             else:
<                 if 'c' not in kwds:
<                     raise TypeError('create expected at least 2 positional '
<                                     'arguments, got %d' % (len(args)-1))
<                 c = kwds.pop('c')
<                 self, *args = args
<                 import warnings
<                 warnings.warn("Passing 'c' as keyword argument is deprecated",
<                               DeprecationWarning, stacklevel=2)
<         args = tuple(args)
< 
424d397
<     create.__text_signature__ = '($self, c, typeid, /, *args, **kwds)'
1296c1269
<         def create(*args, **kwargs):
---
>         def create(self, c, typeid, /, *args, **kwargs):
1302,1311d1274
<             if len(args) >= 3:
<                 typeod = args[2]
<             elif 'typeid' in kwargs:
<                 typeid = kwargs['typeid']
<             elif not args:
<                 raise TypeError("descriptor 'create' of 'SharedMemoryServer' "
<                                 "object needs an argument")
<             else:
<                 raise TypeError('create expected at least 2 positional '
<                                 'arguments, got %d' % (len(args)-1))
1314,1315c1277
<             return Server.create(*args, **kwargs)
<         create.__text_signature__ = '($self, c, typeid, /, *args, **kwargs)'
---
>             return Server.create(self, c, typeid, *args, **kwargs)
diff Python-3.8.1/Lib/multiprocessing/popen_fork.py Python-3.9.0a2/Lib/multiprocessing/popen_fork.py
28c28
<             except OSError as e:
---
>             except OSError:
diff Python-3.8.1/Lib/multiprocessing/util.py Python-3.9.0a2/Lib/multiprocessing/util.py
432c432
<             False, False, None)
---
>             False, False, None, None, None, -1, None)
# ----------------------------------------------------------------------
diff Python-3.9.0a2/Modules/_multiprocessing/posixshmem.c Python-3.9.0b1/Modules/_multiprocessing/posixshmem.c
8d7
< #include "structmember.h"
diff Python-3.9.0a2/Modules/_multiprocessing/semaphore.c Python-3.9.0b1/Modules/_multiprocessing/semaphore.c
271d270
<     double timeout;
274,275d272
<     struct timeval now;
<     long sec, nsec;
288,290c285,288
<     if (timeout_obj != Py_None) {
<         timeout = PyFloat_AsDouble(timeout_obj);
<         if (PyErr_Occurred())
---
>     int use_deadline = (timeout_obj != Py_None);
>     if (use_deadline) {
>         double timeout = PyFloat_AsDouble(timeout_obj);
>         if (PyErr_Occurred()) {
292c290,291
<         if (timeout < 0.0)
---
>         }
>         if (timeout < 0.0) {
293a293
>         }
294a295
>         struct timeval now;
299,300c300,301
<         sec = (long) timeout;
<         nsec = (long) (1e9 * (timeout - sec) + 0.5);
---
>         long sec = (long) timeout;
>         long nsec = (long) (1e9 * (timeout - sec) + 0.5);
318c319
<             if (timeout_obj == Py_None) {
---
>             if (!use_deadline) {
diff Python-3.9.0a2/Lib/multiprocessing/connection.py Python-3.9.0b1/Lib/multiprocessing/connection.py
75a76,80
>         # Prefer abstract sockets if possible to avoid problems with the address
>         # size.  When coding portable applications, some implementations have
>         # sun_path as short as 92 bytes in the sockaddr_un struct.
>         if util.abstract_sockets_supported:
>             return f"\0listener-{os.getpid()}-{next(_mmap_counter)}"
105c110
<     elif type(address) is str:
---
>     elif type(address) is str or util.is_abstract_socket_namespace(address):
600c605,606
<         if family == 'AF_UNIX':
---
>         if family == 'AF_UNIX' and not util.is_abstract_socket_namespace(address):
>             # Linux abstract socket namespaces do not need to be explicitly unlinked
diff Python-3.9.0a2/Lib/multiprocessing/forkserver.py Python-3.9.0b1/Lib/multiprocessing/forkserver.py
58c58,59
<         os.unlink(self._forkserver_address)
---
>         if not util.is_abstract_socket_namespace(self._forkserver_address):
>             os.unlink(self._forkserver_address)
138c139,140
<                 os.chmod(address, 0o600)
---
>                 if not util.is_abstract_socket_namespace(address):
>                     os.chmod(address, 0o600)
238,245c240,241
<                             if os.WIFSIGNALED(sts):
<                                 returncode = -os.WTERMSIG(sts)
<                             else:
<                                 if not os.WIFEXITED(sts):
<                                     raise AssertionError(
<                                         "Child {0:n} status is {1:n}".format(
<                                             pid,sts))
<                                 returncode = os.WEXITSTATUS(sts)
---
>                             returncode = os.waitstatus_to_exitcode(sts)
> 
diff Python-3.9.0a2/Lib/multiprocessing/managers.py Python-3.9.0b1/Lib/multiprocessing/managers.py
23a24
> import types
62c63
<     Type to uniquely indentify a shared object
---
>     Type to uniquely identify a shared object
797c798
<         Try to call a method of the referrent and return a copy of the result
---
>         Try to call a method of the referent and return a copy of the result
1131a1133,1134
>     __class_getitem__ = classmethod(types.GenericAlias)
> 
1264a1268,1271
>             address = self.address
>             # The address of Linux abstract namespaces can be bytes
>             if isinstance(address, bytes):
>                 address = os.fsdecode(address)
1266c1273
<                 _SharedMemoryTracker(f"shmm_{self.address}_{getpid()}")
---
>                 _SharedMemoryTracker(f"shm_{address}_{getpid()}")
diff Python-3.9.0a2/Lib/multiprocessing/pool.py Python-3.9.0b1/Lib/multiprocessing/pool.py
22a23
> import types
24d24
< from queue import Empty
654,655d653
<         self._worker_handler._state = TERMINATE
<         self._change_notifier.put(None)
684a683,685
>         # Notify that the worker_handler state has been changed so the
>         # _handle_workers loop can be unblocked (and exited) in order to
>         # send the finalization sentinel all the workers.
685a687,688
>         change_notifier.put(None)
> 
779a783,784
>     __class_getitem__ = classmethod(types.GenericAlias)
> 
diff Python-3.9.0a2/Lib/multiprocessing/popen_fork.py Python-3.9.0b1/Lib/multiprocessing/popen_fork.py
33,37c33
<                 if os.WIFSIGNALED(sts):
<                     self.returncode = -os.WTERMSIG(sts)
<                 else:
<                     assert os.WIFEXITED(sts), "Status is {:n}".format(sts)
<                     self.returncode = os.WEXITSTATUS(sts)
---
>                 self.returncode = os.waitstatus_to_exitcode(sts)
diff Python-3.9.0a2/Lib/multiprocessing/process.py Python-3.9.0b1/Lib/multiprocessing/process.py
320,323c320,323
<             if not e.args:
<                 exitcode = 1
<             elif isinstance(e.args[0], int):
<                 exitcode = e.args[0]
---
>             if e.code is None:
>                 exitcode = 0
>             elif isinstance(e.code, int):
>                 exitcode = e.code
325c325
<                 sys.stderr.write(str(e.args[0]) + '\n')
---
>                 sys.stderr.write(str(e.code) + '\n')
diff Python-3.9.0a2/Lib/multiprocessing/queues.py Python-3.9.0b1/Lib/multiprocessing/queues.py
16a17
> import types
51,52c52
< 
<         self._after_fork()
---
>         self._reset()
65c65
<         self._after_fork()
---
>         self._reset()
69c69,75
<         self._notempty = threading.Condition(threading.Lock())
---
>         self._reset(after_fork=True)
> 
>     def _reset(self, after_fork=False):
>         if after_fork:
>             self._notempty._at_fork_reinit()
>         else:
>             self._notempty = threading.Condition(threading.Lock())
342a349,352
>     def close(self):
>         self._reader.close()
>         self._writer.close()
> 
368a379,380
> 
>     __class_getitem__ = classmethod(types.GenericAlias)
diff Python-3.9.0a2/Lib/multiprocessing/resource_sharer.py Python-3.9.0b1/Lib/multiprocessing/resource_sharer.py
66d65
<         self._old_locks = []
116,119c115
<         # If self._lock was locked at the time of the fork, it may be broken
<         # -- see issue 6721.  Replace it without letting it be gc'ed.
<         self._old_locks.append(self._lock)
<         self._lock = threading.Lock()
---
>         self._lock._at_fork_reinit()
diff Python-3.9.0a2/Lib/multiprocessing/shared_memory.py Python-3.9.0b1/Lib/multiprocessing/shared_memory.py
16a17
> import types
253a255,263
>     # The shared memory area is organized as follows:
>     # - 8 bytes: number of items (N) as a 64-bit integer
>     # - (N + 1) * 8 bytes: offsets of each element from the start of the
>     #                      data area
>     # - K bytes: the data area storing item values (with encoding and size
>     #            depending on their respective types)
>     # - N * 8 bytes: `struct` format string for each element
>     # - N bytes: index into _back_transforms_mapping for each element
>     #            (for reconstructing the corresponding Python value)
285c295,296
<         if sequence is not None:
---
>         if name is None or sequence is not None:
>             sequence = sequence or ()
296,299c307,314
<             self._allocated_bytes = tuple(
<                     self._alignment if fmt[-1] != "s" else int(fmt[:-1])
<                     for fmt in _formats
<             )
---
>             offset = 0
>             # The offsets of each list element into the shared memory's
>             # data area (0 meaning the start of the data area, not the start
>             # of the shared memory area).
>             self._allocated_offsets = [0]
>             for fmt in _formats:
>                 offset += self._alignment if fmt[-1] != "s" else int(fmt[:-1])
>                 self._allocated_offsets.append(offset)
309a325
>             self.shm = SharedMemory(name, create=True, size=requested_size)
311,313d326
<             requested_size = 8  # Some platforms require > 0.
< 
<         if name is not None and sequence is None:
315,316d327
<         else:
<             self.shm = SharedMemory(name, create=True, size=requested_size)
325c336
<                 *(self._allocated_bytes)
---
>                 *(self._allocated_offsets)
348,351c359,364
<             self._allocated_bytes = struct.unpack_from(
<                 self._format_size_metainfo,
<                 self.shm.buf,
<                 1 * 8
---
>             self._allocated_offsets = list(
>                 struct.unpack_from(
>                     self._format_size_metainfo,
>                     self.shm.buf,
>                     1 * 8
>                 )
373d385
<         position = position if position >= 0 else position + self._list_len
390d401
<         position = position if position >= 0 else position + self._list_len
409a421
>         position = position if position >= 0 else position + self._list_len
411,412c423
<             offset = self._offset_data_start \
<                      + sum(self._allocated_bytes[:position])
---
>             offset = self._offset_data_start + self._allocated_offsets[position]
426a438
>         position = position if position >= 0 else position + self._list_len
428,429c440,441
<             offset = self._offset_data_start \
<                      + sum(self._allocated_bytes[:position])
---
>             item_offset = self._allocated_offsets[position]
>             offset = self._offset_data_start + item_offset
435a448
>             encoded_value = value
437,438c450,455
<             if len(value) > self._allocated_bytes[position]:
<                 raise ValueError("exceeds available storage for existing str")
---
>             allocated_length = self._allocated_offsets[position + 1] - item_offset
> 
>             encoded_value = (value.encode(_encoding)
>                              if isinstance(value, str) else value)
>             if len(encoded_value) > allocated_length:
>                 raise ValueError("bytes/str item exceeds available storage")
443c460
<                     self._allocated_bytes[position],
---
>                     allocated_length,
451,452c468
<         value = value.encode(_encoding) if isinstance(value, str) else value
<         struct.pack_into(new_format, self.shm.buf, offset, value)
---
>         struct.pack_into(new_format, self.shm.buf, offset, encoded_value)
465c481
<         "The struct packing format used by all currently stored values."
---
>         "The struct packing format used by all currently stored items."
472,473c488,489
<         "The struct packing format used for metainfo on storage sizes."
<         return f"{self._list_len}q"
---
>         "The struct packing format used for the items' storage offsets."
>         return "q" * (self._list_len + 1)
477c493
<         "The struct packing format used for the values' packing formats."
---
>         "The struct packing format used for the items' packing formats."
482c498
<         "The struct packing format used for the values' back transforms."
---
>         "The struct packing format used for the items' back transforms."
487c503,505
<         return (self._list_len + 1) * 8  # 8 bytes per "q"
---
>         # - 8 bytes for the list length
>         # - (N + 1) * 8 bytes for the element offsets
>         return (self._list_len + 2) * 8
491c509
<         return self._offset_data_start + sum(self._allocated_bytes)
---
>         return self._offset_data_start + self._allocated_offsets[-1]
510a529,530
> 
>     __class_getitem__ = classmethod(types.GenericAlias)
diff Python-3.9.0a2/Lib/multiprocessing/spawn.py Python-3.9.0b1/Lib/multiprocessing/spawn.py
39c39
<     _python_exe = sys._base_executable
---
>     _python_exe = sys.executable
diff Python-3.9.0a2/Lib/multiprocessing/util.py Python-3.9.0b1/Lib/multiprocessing/util.py
104a105,127
> 
> # Abstract socket support
> 
> def _platform_supports_abstract_sockets():
>     if sys.platform == "linux":
>         return True
>     if hasattr(sys, 'getandroidapilevel'):
>         return True
>     return False
> 
> 
> def is_abstract_socket_namespace(address):
>     if not address:
>         return False
>     if isinstance(address, bytes):
>         return address[0] == 0
>     elif isinstance(address, str):
>         return address[0] == "\0"
>     raise TypeError('address type of {address!r} unrecognized')
> 
> 
> abstract_sockets_supported = _platform_supports_abstract_sockets()
> 
347,350d369
<         self._reset()
<         register_after_fork(self, ForkAwareThreadLock._reset)
< 
<     def _reset(self):
353a373,376
>         register_after_fork(self, ForkAwareThreadLock._at_fork_reinit)
> 
>     def _at_fork_reinit(self):
>         self._lock._at_fork_reinit()
# ----------------------------------------------------------------------
diff Python-3.9.0b1/Lib/multiprocessing/context.py Python-3.9.0/Lib/multiprocessing/context.py
259a260
>             methods = ['spawn', 'fork'] if sys.platform == 'darwin' else ['fork', 'spawn']
261,263c262,264
<                 return ['fork', 'spawn', 'forkserver']
<             else:
<                 return ['fork', 'spawn']
---
>                 methods.append('forkserver')
>             return methods
> 
Common subdirectories: Python-3.9.0b1/Lib/multiprocessing/dummy and Python-3.9.0/Lib/multiprocessing/dummy
diff Python-3.9.0b1/Lib/multiprocessing/shared_memory.py Python-3.9.0/Lib/multiprocessing/shared_memory.py
78a79,80
>             if size == 0:
>                 raise ValueError("'size' must be a positive number different from zero")
diff Python-3.9.0b1/Lib/multiprocessing/synchronize.py Python-3.9.0/Lib/multiprocessing/synchronize.py
273c273
<             False), ('notify: Should not have been able to acquire'
---
>             False), ('notify: Should not have been able to acquire '
# ----------------------------------------------------------------------
diff Python-3.9.2/Lib/test/_test_multiprocessing.py multiprocess/tests/__init__.py 
23c23
< import pickle
---
> import pickle #XXX: use dill?
36c36
< support.skip_if_broken_multiprocessing_synchronize()
---
> test.support.import_module('multiprocess.synchronize')
39,44c39,45
< import multiprocessing.connection
< import multiprocessing.dummy
< import multiprocessing.heap
< import multiprocessing.managers
< import multiprocessing.pool
< import multiprocessing.queues
---
> import multiprocess as multiprocessing
> import multiprocess.connection
> import multiprocess.dummy
> import multiprocess.heap
> import multiprocess.managers
> import multiprocess.pool
> import multiprocess.queues
46c47
< from multiprocessing import util
---
> from multiprocess import util
49c50
<     from multiprocessing import reduction
---
>     from multiprocess import reduction
55c56
<     from multiprocessing.sharedctypes import Value, copy
---
>     from multiprocess.sharedctypes import Value, copy
61c62
<     from multiprocessing import shared_memory
---
>     from multiprocess import shared_memory
89c90
<     from multiprocessing import resource_tracker
---
>     from multiprocess import resource_tracker
117c118
< from multiprocessing.connection import wait
---
> from multiprocess.connection import wait
130c131
< PRELOAD = ['__main__', 'test.test_multiprocessing_forkserver']
---
> PRELOAD = ['__main__', 'test_multiprocessing_forkserver']
169c170
<         t = time.monotonic()
---
>         t = getattr(time,'monotonic',time.time)()
173c174
<             self.elapsed = time.monotonic() - t
---
>             self.elapsed = getattr(time,'monotonic',time.time)() - t
285c286
<         from multiprocessing.process import parent_process
---
>         from multiprocess.process import parent_process
288c289
<     def test_parent_process(self):
---
>     def _test_parent_process(self):
321c322
<         from multiprocessing.process import parent_process
---
>         from multiprocess.process import parent_process
488a490
>     @unittest.skipIf(True, "fails with is_dill(obj, child=True)")
740c742
<         from multiprocessing.forkserver import _forkserver
---
>         from multiprocess.forkserver import _forkserver
829c831
<             self.assertIn("test_multiprocessing.py", err)
---
>             self.assertIn("__init__.py", err)
1119c1121
<                     import multiprocessing
---
>                     import multiprocess as multiprocessing
1137c1139
<         start = time.monotonic()
---
>         start = getattr(time,'monotonic',time.time)()
1139c1141
<         delta = time.monotonic() - start
---
>         delta = getattr(time,'monotonic',time.time)() - start
1541c1543
<             dt = time.monotonic()
---
>             dt = getattr(time,'monotonic',time.time)()
1543c1545
<             dt = time.monotonic() - dt
---
>             dt = getattr(time,'monotonic',time.time)() - dt
2012c2014
<             self.skipTest("requires multiprocessing.sharedctypes")
---
>             self.skipTest("requires multiprocess.sharedctypes")
2578a2581
>     @unittest.skipIf(True, "fails with is_dill(obj, child=True)")
2620a2624
>     @unittest.skipIf(True, "fails with is_dill(obj, child=True)")
2634c2638
<         t_start = time.monotonic()
---
>         t_start = getattr(time,'monotonic',time.time)()
2646c2650
<         self.assertGreater(time.monotonic() - t_start, 0.9)
---
>         self.assertGreater(getattr(time,'monotonic',time.time)() - t_start, 0.9)
2718,2719c2722,2723
<     def test_unpickleable_result(self):
<         from multiprocessing.pool import MaybeEncodingError
---
>     def _test_unpickleable_result(self):
>         from multiprocess.pool import MaybeEncodingError
2807c2811
< from multiprocessing.managers import BaseManager, BaseProxy, RemoteError
---
> from multiprocess.managers import BaseManager, BaseProxy, RemoteError
3450c3454
<         from multiprocessing import resource_sharer
---
>         from multiprocess import resource_sharer
3695c3699
<             self.skipTest("requires multiprocessing.sharedctypes")
---
>             self.skipTest("requires multiprocess.sharedctypes")
3745c3749
< @unittest.skipUnless(HAS_SHMEM, "requires multiprocessing.shared_memory")
---
> @unittest.skipUnless(HAS_SHMEM, "requires multiprocess.shared_memory")
4123c4127
<             deadline = time.monotonic() + support.LONG_TIMEOUT
---
>             deadline = getattr(time,'monotonic',time.time)() + support.LONG_TIMEOUT
4125c4129
<             while time.monotonic() < deadline:
---
>             while getattr(time,'monotonic',time.time)() < deadline:
4277,4279c4281,4283
<         modules = ['multiprocessing.' + m for m in modules]
<         modules.remove('multiprocessing.__init__')
<         modules.append('multiprocessing')
---
>         modules = ['multiprocess.' + m for m in modules]
>         modules.remove('multiprocess.__init__')
>         modules.append('multiprocess')
4285,4287c4289,4291
<             modules.remove('multiprocessing.popen_fork')
<             modules.remove('multiprocessing.popen_forkserver')
<             modules.remove('multiprocessing.popen_spawn_posix')
---
>             modules.remove('multiprocess.popen_fork')
>             modules.remove('multiprocess.popen_forkserver')
>             modules.remove('multiprocess.popen_spawn_posix')
4289c4293
<             modules.remove('multiprocessing.popen_spawn_win32')
---
>             modules.remove('multiprocess.popen_spawn_win32')
4291c4295
<                 modules.remove('multiprocessing.popen_forkserver')
---
>                 modules.remove('multiprocess.popen_forkserver')
4295c4299
<             modules.remove('multiprocessing.sharedctypes')
---
>             modules.remove('multiprocess.sharedctypes')
4577c4581
<         from multiprocessing.connection import wait
---
>         from multiprocess.connection import wait
4617c4621
<         from multiprocessing.connection import wait
---
>         from multiprocess.connection import wait
4658c4662
<         from multiprocessing.connection import wait
---
>         from multiprocess.connection import wait
4663c4667
<         start = time.monotonic()
---
>         start = getattr(time,'monotonic',time.time)()
4665c4669
<         delta = time.monotonic() - start
---
>         delta = getattr(time,'monotonic',time.time)() - start
4673c4677
<         start = time.monotonic()
---
>         start = getattr(time,'monotonic',time.time)()
4675c4679
<         delta = time.monotonic() - start
---
>         delta = getattr(time,'monotonic',time.time)() - start
4686c4690
<         from multiprocessing.connection import wait
---
>         from multiprocess.connection import wait
4699c4703
<         start = time.monotonic()
---
>         start = getattr(time,'monotonic',time.time)()
4701c4705
<         delta = time.monotonic() - start
---
>         delta = getattr(time,'monotonic',time.time)() - start
4709c4713
<         start = time.monotonic()
---
>         start = getattr(time,'monotonic',time.time)()
4711c4715
<         delta = time.monotonic() - start
---
>         delta = getattr(time,'monotonic',time.time)() - start
4718c4722
<         start = time.monotonic()
---
>         start = getattr(time,'monotonic',time.time)()
4720c4724
<         delta = time.monotonic() - start
---
>         delta = getattr(time,'monotonic',time.time)() - start
4729c4733
<         from multiprocessing.connection import wait
---
>         from multiprocess.connection import wait
4731c4735
<         t = time.monotonic()
---
>         t = getattr(time,'monotonic',time.time)()
4733c4737
<         t = time.monotonic() - t
---
>         t = getattr(time,'monotonic',time.time)() - t
4777c4781
<     def test_flags(self):
---
>     def _test_flags(self):
4780c4784
<         prog = ('from test._test_multiprocessing import TestFlags; ' +
---
>         prog = ('from multiprocess.tests import TestFlags; ' +
5082c5086
<     def test_resource_tracker(self):
---
>     def _test_resource_tracker(self):
5088,5090c5092,5094
<             import multiprocessing as mp
<             from multiprocessing import resource_tracker
<             from multiprocessing.shared_memory import SharedMemory
---
>             import multiprocess as mp
>             from multiprocess import resource_tracker
>             from multiprocess.shared_memory import SharedMemory
5134,5135c5138,5139
<                 deadline = time.monotonic() + support.LONG_TIMEOUT
<                 while time.monotonic() < deadline:
---
>                 deadline = getattr(time,'monotonic',time.time)() + support.LONG_TIMEOUT
>                 while getattr(time,'monotonic',time.time)() < deadline:
5159c5163
<         from multiprocessing.resource_tracker import _resource_tracker
---
>         from multiprocess.resource_tracker import _resource_tracker
5207c5211
<         from multiprocessing.resource_tracker import _resource_tracker
---
>         from multiprocess.resource_tracker import _resource_tracker
5216c5220
<         from multiprocessing.resource_tracker import _resource_tracker
---
>         from multiprocess.resource_tracker import _resource_tracker
5375c5379
<         start_time = time.monotonic()
---
>         start_time = getattr(time,'monotonic',time.time)()
5380c5384
<             dt = time.monotonic() - start_time
---
>             dt = getattr(time,'monotonic',time.time)() - start_time
5383c5387
<                 support.print_warning(f"multiprocessing.Manager still has "
---
>                 support.print_warning(f"multiprocess.Manager still has "
5651c5655
<         start_time = time.monotonic()
---
>         start_time = getattr(time,'monotonic',time.time)()
5656c5660
<             dt = time.monotonic() - start_time
---
>             dt = getattr(time,'monotonic',time.time)() - start_time
5659c5663
<                 support.print_warning(f"multiprocessing.Manager still has "
---
>                 support.print_warning(f"multiprocess.Manager still has "
# ----------------------------------------------------------------------
diff Python-3.9.4/Lib/test/_test_multiprocessing.py Python-3.9.7/Lib/test/_test_multiprocessing.py 
609a610
>         gc.collect()  # For PyPy or other GCs.
2284a2286,2295
>     def test_nested_queue(self):
>         a = self.list() # Test queue inside list
>         a.append(self.Queue())
>         a[0].put(123)
>         self.assertEqual(a[0].get(), 123)
>         b = self.dict() # Test queue inside dict
>         b[0] = self.Queue()
>         b[0].put(456)
>         self.assertEqual(b[0].get(), 456)
> 
2655a2667
>         gc.collect()  # For PyPy or other GCs.
4157a4170
>         gc.collect()  # For PyPy or other GCs.
4168a4182
>         gc.collect()  # For PyPy or other GCs.
4174a4189
>         gc.collect()  # For PyPy or other GCs.
# ----------------------------------------------------------------------
diff Python-3.9.4/Lib/multiprocessing/managers.py Python-3.9.7/Lib/multiprocessing/managers.py
11,12c11
< __all__ = [ 'BaseManager', 'SyncManager', 'BaseProxy', 'Token',
<             'SharedMemoryManager' ]
---
> __all__ = [ 'BaseManager', 'SyncManager', 'BaseProxy', 'Token' ]
38d36
<     HAS_SHMEM = True
40a39,41
> else:
>     HAS_SHMEM = True
>     __all__.append('SharedMemoryManager')
962c963
<               exposed=None, incref=True):
---
>               exposed=None, incref=True, manager_owned=False):
982c983
<                       incref=incref)
---
>                       incref=incref, manager_owned=manager_owned)
# ----------------------------------------------------------------------
dude@borel>$ diff Python-3.9.7/Lib/test/_test_multiprocessing.py Python-3.9.9/Lib/test/_test_multiprocessing.py 
3771a3772,3778
>     def _new_shm_name(self, prefix):
>         # Add a PID to the name of a POSIX shared memory object to allow
>         # running multiprocessing tests (test_multiprocessing_fork,
>         # test_multiprocessing_spawn, etc) in parallel.
>         return prefix + str(os.getpid())
> 
>     @unittest.skipIf(sys.platform == "win32", "test is broken on Windows")
>     @unittest.skipIf(True, "fails with is_dill(obj, child=True)")
3773c3780,3781
<         sms = shared_memory.SharedMemory('test01_tsmb', create=True, size=512)
---
>         name_tsmb = self._new_shm_name('test01_tsmb')
>         sms = shared_memory.SharedMemory(name_tsmb, create=True, size=512)
3777c3785
<         self.assertEqual(sms.name, 'test01_tsmb')
---
>         self.assertEqual(sms.name, name_tsmb)
3786c3794
<         also_sms = shared_memory.SharedMemory('test01_tsmb')
---
>         also_sms = shared_memory.SharedMemory(name_tsmb)
3791c3799
<         same_sms = shared_memory.SharedMemory('test01_tsmb', size=20*sms.size)
---
>         same_sms = shared_memory.SharedMemory(name_tsmb, size=20*sms.size)
3809c3817
<             names = ['test01_fn', 'test02_fn']
---
>             names = [self._new_shm_name('test01_fn'), self._new_shm_name('test02_fn')]
3830a3839,3844
>             name_dblunlink = self._new_shm_name('test01_dblunlink')
>             sms_uno = shared_memory.SharedMemory(
>                 name_dblunlink,
>                 create=True,
>                 size=5000
>             )
3832,3837d3845
<                 sms_uno = shared_memory.SharedMemory(
<                     'test01_dblunlink',
<                     create=True,
<                     size=5000
<                 )
< 
3841c3849
<                     sms_duo = shared_memory.SharedMemory('test01_dblunlink')
---
>                     sms_duo = shared_memory.SharedMemory(name_dblunlink)
3853c3861
<                 'test01_tsmb',
---
>                 name_tsmb,
3867c3875
<             ok_if_exists_sms = OptionalAttachSharedMemory('test01_tsmb')
---
>             ok_if_exists_sms = OptionalAttachSharedMemory(name_tsmb)
4055c4063,4064
<         sl_copy = shared_memory.ShareableList(sl, name='test03_duplicate')
---
>         name_duplicate = self._new_shm_name('test03_duplicate')
>         sl_copy = shared_memory.ShareableList(sl, name=name_duplicate)
4058c4067
<             self.assertEqual('test03_duplicate', sl_copy.shm.name)
---
>             self.assertEqual(name_duplicate, sl_copy.shm.name)
4148a4158,4164
>                 # Without this line it was raising warnings like:
>                 #   UserWarning: resource_tracker:
>                 #   There appear to be 1 leaked shared_memory
>                 #   objects to clean up at shutdown
>                 # See: https://bugs.python.org/issue45209
>                 resource_tracker.unregister(f"/{name}", "shared_memory")
> 
# ----------------------------------------------------------------------
$ diff Python-3.9.10/Lib/test/_test_multiprocessing.py Python-3.9.12/Lib/test/_test_multiprocessing.py 
71a72,77
> if support.check_sanitizer(address=True):
>     # bpo-45200: Skip multiprocessing tests if Python is built with ASAN to
>     # work around a libasan race condition: dead lock in pthread_create().
>     raise unittest.SkipTest("libasan has a pthread_create() dead lock")
> 
> 
# ----------------------------------------------------------------------
diff Python-3.9.12/Lib/multiprocessing/managers.py Python-3.9.13/Lib/multiprocessing/managers.py
672c672
<                     process.join(timeout=0.1)
---
>                     process.join(timeout=1.0)
diff Python-3.9.12/Lib/multiprocessing/queues.py Python-3.9.13/Lib/multiprocessing/queues.py
142,148c142,145
<         try:
<             self._reader.close()
<         finally:
<             close = self._close
<             if close:
<                 self._close = None
<                 close()
---
>         close = self._close
>         if close:
>             self._close = None
>             close()
172,173c169,171
<                   self._wlock, self._writer.close, self._ignore_epipe,
<                   self._on_queue_feeder_error, self._sem),
---
>                   self._wlock, self._reader.close, self._writer.close,
>                   self._ignore_epipe, self._on_queue_feeder_error,
>                   self._sem),
214,215c212,213
<     def _feed(buffer, notempty, send_bytes, writelock, close, ignore_epipe,
<               onerror, queue_sem):
---
>     def _feed(buffer, notempty, send_bytes, writelock, reader_close,
>               writer_close, ignore_epipe, onerror, queue_sem):
241c239,240
<                             close()
---
>                             reader_close()
>                             writer_close()
diff Python-3.9.12/Lib/multiprocessing/util.py Python-3.9.13/Lib/multiprocessing/util.py
123c123
<     raise TypeError('address type of {address!r} unrecognized')
---
>     raise TypeError(f'address type of {address!r} unrecognized')
# ----------------------------------------------------------------------
diff Python-3.9.13/Lib/multiprocessing/connection.py Python-3.9.16/Lib/multiprocessing/connection.py
76,80d75
<         # Prefer abstract sockets if possible to avoid problems with the address
<         # size.  When coding portable applications, some implementations have
<         # sun_path as short as 92 bytes in the sockaddr_un struct.
<         if util.abstract_sockets_supported:
<             return f"\0listener-{os.getpid()}-{next(_mmap_counter)}"

