diff --git a/Src/IronPython.Modules/_multiprocessing.cs b/Src/IronPython.Modules/_multiprocessing.cs new file mode 100644 index 000000000..2be9ac543 --- /dev/null +++ b/Src/IronPython.Modules/_multiprocessing.cs @@ -0,0 +1,49 @@ +using Microsoft.Win32.SafeHandles; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Sockets; +using System.Runtime.InteropServices; + +using IronPython.Runtime; + +[assembly: PythonModule("_multiprocessing_ipy", typeof(IronPython.Modules.MultiProcessing))] +namespace IronPython.Modules { + public static class MultiProcessing { + [DllImport("ws2_32.dll", ExactSpelling = true, SetLastError = true)] + private static extern SocketError closesocket([In] IntPtr socketHandle); + + public static object closesocket(int handle) { + var error = closesocket(new IntPtr(handle)); + // TODO: raise error + return null; + } + + [DllImport("ws2_32.dll", SetLastError = true)] + private static extern int recv( + [In] IntPtr socketHandle, + [In] byte[] pinnedBuffer, + [In] int len, + [In] SocketFlags socketFlags + ); + + public static IList recv(int handle, int size) { + var buf = new byte[size]; + recv(new IntPtr(handle), buf, size, 0); + return buf; + } + + [DllImport("ws2_32.dll", SetLastError = true)] + private static extern int send( + [In] IntPtr socketHandle, + [In] byte[] pinnedBuffer, + [In] int len, + [In] SocketFlags socketFlags + ); + + public static int send(int handle, [BytesConversion]IList buf) { + return send(new IntPtr(handle), buf.ToArray(), buf.Count, 0); + } + + } +} diff --git a/Src/IronPython.Modules/_multiprocessing_win32.cs b/Src/IronPython.Modules/_multiprocessing_win32.cs new file mode 100644 index 000000000..93acf639a --- /dev/null +++ b/Src/IronPython.Modules/_multiprocessing_win32.cs @@ -0,0 +1,39 @@ +using IronPython.Runtime; +using Microsoft.Win32.SafeHandles; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +[assembly: PythonModule("_multiprocessing_win32", typeof(IronPython.Modules.MultiProcessingWin32))] +namespace IronPython.Modules { + public static class MultiProcessingWin32 { + public const int WAIT_OBJECT_0 = 0; + public const int WAIT_ABANDONED_0 = 0x80; + public const int WAIT_TIMEOUT = 0x102; + public const int INFINITE = -1; + + public const int ERROR_IO_PENDING = 997; + public const int ERROR_MORE_DATA = 0xEA; + public const int ERROR_BROKEN_PIPE = 0x6D; + + [return: MarshalAs(UnmanagedType.Bool)] + [DllImport("kernel32.dll", SetLastError = true, EntryPoint = "CloseHandle")] + public static extern bool CloseHandle(IntPtr hObject); + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern int WriteFile(SafeFileHandle handle, byte[] bytes, int numBytesToWrite, out int numBytesWritten, IntPtr mustBeZero); + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern int ReadFile(SafeFileHandle handle, byte[] bytes, int numBytesToRead, out int numBytesRead, IntPtr mustBeZero); + + [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)] + public static extern int WaitForMultipleObjects(uint handle, IntPtr[] handles, bool waitAll, uint milliseconds); + + [DllImport("kernel32.dll")] + public static extern void ExitProcess(uint uExitCode); + } + +} diff --git a/Src/StdLib/Lib/multiprocessing/connection.py b/Src/StdLib/Lib/multiprocessing/connection.py index 645a26f06..0ac380969 100644 --- a/Src/StdLib/Lib/multiprocessing/connection.py +++ b/Src/StdLib/Lib/multiprocessing/connection.py @@ -42,6 +42,8 @@ import tempfile import itertools +is_win32 = sys.platform == "win32" or sys.platform == "cli" and os.name == "nt" + import _multiprocessing from multiprocessing import current_process, AuthenticationError from multiprocessing.util import get_temp_dir, Finalize, sub_debug, debug @@ -65,7 +67,7 @@ default_family = 'AF_UNIX' families += ['AF_UNIX'] -if sys.platform == 'win32': +if is_win32: default_family = 'AF_PIPE' families += ['AF_PIPE'] @@ -178,7 +180,7 @@ def Client(address, family=None, authkey=None): return c -if sys.platform != 'win32': +if not is_win32: def Pipe(duplex=True): ''' @@ -326,7 +328,7 @@ def SocketClient(address): # Definitions for connections based on named pipes # -if sys.platform == 'win32': +if is_win32: class PipeListener(object): ''' diff --git a/Src/StdLib/Lib/multiprocessing/forking.py b/Src/StdLib/Lib/multiprocessing/forking.py index 9412eb1ef..9a174c2d1 100644 --- a/Src/StdLib/Lib/multiprocessing/forking.py +++ b/Src/StdLib/Lib/multiprocessing/forking.py @@ -37,6 +37,8 @@ import signal import errno +is_win32 = sys.platform == "win32" or sys.platform == "cli" and os.name == "nt" + from multiprocessing import util, process __all__ = ['Popen', 'assert_spawning', 'exit', 'duplicate', 'close', 'ForkingPickler'] @@ -56,16 +58,7 @@ def assert_spawning(self): # Try making some callable types picklable # -from pickle import Pickler -class ForkingPickler(Pickler): - dispatch = Pickler.dispatch.copy() - - @classmethod - def register(cls, type, reduce): - def dispatcher(self, obj): - rv = reduce(obj) - self.save_reduce(obj=obj, *rv) - cls.dispatch[type] = dispatcher +from _multiprocessing import ForkingPickler def _reduce_method(m): if m.im_self is None: @@ -99,7 +92,7 @@ def _rebuild_partial(func, args, keywords): # Unix # -if sys.platform != 'win32': +if not is_win32: import time exit = os._exit @@ -203,7 +196,7 @@ def dump(obj, file, protocol=None): # TERMINATE = 0x10000 - WINEXE = (sys.platform == 'win32' and getattr(sys, 'frozen', False)) + WINEXE = (is_win32 and getattr(sys, 'frozen', False)) WINSERVICE = sys.executable.lower().endswith("pythonservice.exe") exit = win32.ExitProcess