Thomas Heller <[EMAIL PROTECTED]> added the comment:
roudkerk schrieb:
> roudkerk <[EMAIL PROTECTED]> added the comment:
>
> This patch to sharedctypes should fix the problem by adding a
> __reduce_ex__() method to a shared ctype object instead of using copy_reg.
I can confirm that the patch fixes the problem on Windows (running test_ctypes
before test_multiprocessing).
However, the patch did not apply cleanly to current SVN trunk - I had to
manually
patch the code. I'll attach the patch that I have now when I run 'svn diff' as
multiprocessing.patch (hope it works, sending as email attachment).
Added file: http://bugs.python.org/file10654/multiprocessing.patch
_______________________________________
Python tracker <[EMAIL PROTECTED]>
<http://bugs.python.org/issue3125>
_______________________________________
Index: Lib/multiprocessing/sharedctypes.py
===================================================================
--- Lib/multiprocessing/sharedctypes.py (revision 64378)
+++ Lib/multiprocessing/sharedctypes.py (working copy)
@@ -9,7 +9,6 @@
import sys
import ctypes
import weakref
-import copy_reg
from multiprocessing import heap, RLock
from multiprocessing.forking import assert_spawning
@@ -33,17 +32,13 @@
#
#
-def _new_value(type_):
- size = ctypes.sizeof(type_)
- wrapper = heap.BufferWrapper(size)
- return rebuild_ctype(type_, wrapper, None)
-
def RawValue(typecode_or_type, *args):
'''
Returns a ctypes object allocated from shared memory
'''
type_ = typecode_to_type.get(typecode_or_type, typecode_or_type)
- obj = _new_value(type_)
+ type_size = ctypes.sizeof(type_)
+ obj = build_ctype(type_, heap.BufferWrapper(type_size), None)
ctypes.memset(ctypes.addressof(obj), 0, ctypes.sizeof(obj))
obj.__init__(*args)
return obj
@@ -53,14 +48,16 @@
Returns a ctypes array allocated from shared memory
'''
type_ = typecode_to_type.get(typecode_or_type, typecode_or_type)
+ type_size = ctypes.sizeof(type_)
if isinstance(size_or_initializer, int):
- type_ = type_ * size_or_initializer
- return _new_value(type_)
+ size = size_or_initializer
+ obj = build_ctype(type_, heap.BufferWrapper(type_size*size), size)
+ ctypes.memset(ctypes.addressof(obj), 0, ctypes.sizeof(obj))
else:
- type_ = type_ * len(size_or_initializer)
- result = _new_value(type_)
- result.__init__(*size_or_initializer)
- return result
+ size = len(size_or_initializer)
+ obj = build_ctype(type_, heap.BufferWrapper(type_size*size), size)
+ obj.__init__(*size_or_initializer)
+ return obj
def Value(typecode_or_type, *args, **kwds):
'''
@@ -117,20 +114,18 @@
# Functions for pickling/unpickling
#
-def reduce_ctype(obj):
- assert_spawning(obj)
- if isinstance(obj, ctypes.Array):
- return rebuild_ctype, (obj._type_, obj._wrapper, obj._length_)
- else:
- return rebuild_ctype, (type(obj), obj._wrapper, None)
-
-def rebuild_ctype(type_, wrapper, length):
+def build_ctype(type_, wrapper, length):
if length is not None:
- type_ = type_ * length
- if sys.platform == 'win32' and type_ not in copy_reg.dispatch_table:
- copy_reg.pickle(type_, reduce_ctype)
- obj = type_.from_address(wrapper.get_address())
+ obj = (type_ * length).from_address(wrapper.get_address())
+ else:
+ obj = type_.from_address(wrapper.get_address())
obj._wrapper = wrapper
+ if sys.platform == 'win32':
+ def __reduce_ex__(proto):
+ return build_ctype, (type_, wrapper, length)
+ # It appears that assigning to obj.__reduce_ex__ will override
+ # type(obj).__reduce__, but that assigning to obj.__reduce__ will not.
+ obj.__reduce_ex__ = __reduce_ex__
return obj
#
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com