Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
dfd79494
Commit
dfd79494
authored
Jun 13, 2008
by
Benjamin Peterson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
convert multiprocessing to unix line endings
parent
c9798fc7
Changes
19
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
3201 additions
and
3201 deletions
+3201
-3201
Lib/multiprocessing/__init__.py
Lib/multiprocessing/__init__.py
+6
-6
Lib/multiprocessing/connection.py
Lib/multiprocessing/connection.py
+7
-7
Lib/multiprocessing/dummy/__init__.py
Lib/multiprocessing/dummy/__init__.py
+143
-143
Lib/multiprocessing/dummy/connection.py
Lib/multiprocessing/dummy/connection.py
+61
-61
Lib/multiprocessing/forking.py
Lib/multiprocessing/forking.py
+10
-10
Lib/multiprocessing/heap.py
Lib/multiprocessing/heap.py
+201
-201
Lib/multiprocessing/managers.py
Lib/multiprocessing/managers.py
+25
-25
Lib/multiprocessing/pool.py
Lib/multiprocessing/pool.py
+30
-30
Lib/multiprocessing/process.py
Lib/multiprocessing/process.py
+6
-6
Lib/multiprocessing/queues.py
Lib/multiprocessing/queues.py
+17
-17
Lib/multiprocessing/reduction.py
Lib/multiprocessing/reduction.py
+8
-8
Lib/multiprocessing/sharedctypes.py
Lib/multiprocessing/sharedctypes.py
+18
-18
Lib/multiprocessing/synchronize.py
Lib/multiprocessing/synchronize.py
+7
-7
Lib/multiprocessing/util.py
Lib/multiprocessing/util.py
+1
-1
Lib/test/test_multiprocessing.py
Lib/test/test_multiprocessing.py
+1791
-1791
Modules/_multiprocessing/multiprocessing.c
Modules/_multiprocessing/multiprocessing.c
+311
-311
Modules/_multiprocessing/multiprocessing.h
Modules/_multiprocessing/multiprocessing.h
+163
-163
Modules/_multiprocessing/pipe_connection.c
Modules/_multiprocessing/pipe_connection.c
+136
-136
Modules/_multiprocessing/win32_functions.c
Modules/_multiprocessing/win32_functions.c
+260
-260
No files found.
Lib/multiprocessing/__init__.py
View file @
dfd79494
...
...
@@ -68,10 +68,10 @@ from multiprocessing.process import Process, current_process, active_children
class
ProcessError
(
Exception
):
pass
class
BufferTooShort
(
ProcessError
):
pass
class
TimeoutError
(
ProcessError
):
pass
...
...
@@ -123,7 +123,7 @@ def cpu_count():
num
=
os
.
sysconf
(
'SC_NPROCESSORS_ONLN'
)
except
(
ValueError
,
OSError
,
AttributeError
):
num
=
0
if
num
>=
1
:
return
num
else
:
...
...
@@ -151,13 +151,13 @@ def log_to_stderr(level=None):
'''
from
multiprocessing.util
import
log_to_stderr
return
log_to_stderr
(
level
)
def
allow_connection_pickling
():
'''
Install support for sending connections and sockets between processes
'''
from
multiprocessing
import
reduction
#
# Definitions depending on native semaphores
#
...
...
@@ -263,7 +263,7 @@ if sys.platform == 'win32':
'''
Sets the path to a python.exe or pythonw.exe binary used to run
child processes on Windows instead of sys.executable.
Useful for people embedding Python.
Useful for people embedding Python.
'''
from
multiprocessing.forking
import
set_executable
set_executable
(
executable
)
...
...
Lib/multiprocessing/connection.py
View file @
dfd79494
...
...
@@ -50,7 +50,7 @@ def arbitrary_address(family):
'''
if
family
==
'AF_INET'
:
return
(
'localhost'
,
0
)
elif
family
==
'AF_UNIX'
:
elif
family
==
'AF_UNIX'
:
return
tempfile
.
mktemp
(
prefix
=
'listener-'
,
dir
=
get_temp_dir
())
elif
family
==
'AF_PIPE'
:
return
tempfile
.
mktemp
(
prefix
=
r'\\.\
pipe
\pyc-%d-%d-'
%
...
...
@@ -160,7 +160,7 @@ if sys.platform != 'win32':
c2
=
_multiprocessing
.
Connection
(
fd2
,
readable
=
False
)
return
c1
,
c2
else
:
from
._multiprocessing
import
win32
...
...
@@ -200,7 +200,7 @@ else:
c1
=
_multiprocessing
.
PipeConnection
(
h1
,
writable
=
duplex
)
c2
=
_multiprocessing
.
PipeConnection
(
h2
,
readable
=
duplex
)
return
c1
,
c2
#
...
...
@@ -290,14 +290,14 @@ if sys.platform == 'win32':
)
self
.
_handle_queue
=
[
handle
]
self
.
_last_accepted
=
None
sub_debug
(
'listener created with address=%r'
,
self
.
_address
)
self
.
close
=
Finalize
(
self
,
PipeListener
.
_finalize_pipe_listener
,
args
=
(
self
.
_handle_queue
,
self
.
_address
),
exitpriority
=
0
)
def
accept
(
self
):
newhandle
=
win32
.
CreateNamedPipe
(
self
.
_address
,
win32
.
PIPE_ACCESS_DUPLEX
,
...
...
@@ -320,7 +320,7 @@ if sys.platform == 'win32':
sub_debug
(
'closing listener with address=%r'
,
address
)
for
handle
in
queue
:
close
(
handle
)
def
PipeClient
(
address
):
'''
Return a connection object connected to the pipe given by `address`
...
...
@@ -397,7 +397,7 @@ class ConnectionWrapper(object):
self
.
_loads
=
loads
for
attr
in
(
'fileno'
,
'close'
,
'poll'
,
'recv_bytes'
,
'send_bytes'
):
obj
=
getattr
(
conn
,
attr
)
setattr
(
self
,
attr
,
obj
)
setattr
(
self
,
attr
,
obj
)
def
send
(
self
,
obj
):
s
=
self
.
_dumps
(
obj
)
self
.
_conn
.
send_bytes
(
s
)
...
...
Lib/multiprocessing/dummy/__init__.py
View file @
dfd79494
#
# Support for the API of the multiprocessing package using threads
#
# multiprocessing/dummy/__init__.py
#
# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
#
__all__
=
[
'Process'
,
'current_process'
,
'active_children'
,
'freeze_support'
,
'Lock'
,
'RLock'
,
'Semaphore'
,
'BoundedSemaphore'
,
'Condition'
,
'Event'
,
'Queue'
,
'Manager'
,
'Pipe'
,
'Pool'
,
'JoinableQueue'
]
#
# Imports
#
import
threading
import
sys
import
weakref
import
array
import
itertools
from
multiprocessing
import
TimeoutError
,
cpu_count
from
multiprocessing.dummy.connection
import
Pipe
from
threading
import
Lock
,
RLock
,
Semaphore
,
BoundedSemaphore
from
threading
import
Event
from
Queue
import
Queue
#
#
#
class
DummyProcess
(
threading
.
Thread
):
def
__init__
(
self
,
group
=
None
,
target
=
None
,
name
=
None
,
args
=
(),
kwargs
=
{}):
threading
.
Thread
.
__init__
(
self
,
group
,
target
,
name
,
args
,
kwargs
)
self
.
_pid
=
None
self
.
_children
=
weakref
.
WeakKeyDictionary
()
self
.
_start_called
=
False
self
.
_parent
=
current_process
()
def
start
(
self
):
assert
self
.
_parent
is
current_process
()
self
.
_start_called
=
True
self
.
_parent
.
_children
[
self
]
=
None
threading
.
Thread
.
start
(
self
)
def
get_exitcode
(
self
):
if
self
.
_start_called
and
not
self
.
is_alive
():
return
0
else
:
return
None
# XXX
if
sys
.
version_info
<
(
3
,
0
):
is_alive
=
threading
.
Thread
.
is_alive
.
im_func
get_name
=
threading
.
Thread
.
get_name
.
im_func
set_name
=
threading
.
Thread
.
set_name
.
im_func
is_daemon
=
threading
.
Thread
.
is_daemon
.
im_func
set_daemon
=
threading
.
Thread
.
set_daemon
.
im_func
else
:
is_alive
=
threading
.
Thread
.
is_alive
get_name
=
threading
.
Thread
.
get_name
set_name
=
threading
.
Thread
.
set_name
is_daemon
=
threading
.
Thread
.
is_daemon
set_daemon
=
threading
.
Thread
.
set_daemon
#
#
#
class
Condition
(
threading
.
_Condition
):
# XXX
if
sys
.
version_info
<
(
3
,
0
):
notify_all
=
threading
.
_Condition
.
notify_all
.
im_func
else
:
notify_all
=
threading
.
_Condition
.
notify_all
#
#
#
Process
=
DummyProcess
current_process
=
threading
.
current_thread
current_process
().
_children
=
weakref
.
WeakKeyDictionary
()
def
active_children
():
children
=
current_process
().
_children
for
p
in
list
(
children
):
if
not
p
.
is_alive
():
children
.
pop
(
p
,
None
)
return
list
(
children
)
def
freeze_support
():
pass
#
#
#
class
Namespace
(
object
):
def
__init__
(
self
,
**
kwds
):
self
.
__dict__
.
update
(
kwds
)
def
__repr__
(
self
):
items
=
self
.
__dict__
.
items
()
temp
=
[]
for
name
,
value
in
items
:
if
not
name
.
startswith
(
'_'
):
temp
.
append
(
'%s=%r'
%
(
name
,
value
))
temp
.
sort
()
return
'Namespace(%s)'
%
str
.
join
(
', '
,
temp
)
dict
=
dict
list
=
list
def
Array
(
typecode
,
sequence
,
lock
=
True
):
return
array
.
array
(
typecode
,
sequence
)
class
Value
(
object
):
def
__init__
(
self
,
typecode
,
value
,
lock
=
True
):
self
.
_typecode
=
typecode
self
.
_value
=
value
def
_get
(
self
):
return
self
.
_value
def
_set
(
self
,
value
):
self
.
_value
=
value
value
=
property
(
_get
,
_set
)
def
__repr__
(
self
):
return
'<%r(%r, %r)>'
%
(
type
(
self
).
__name__
,
self
.
_typecode
,
self
.
_value
)
def
Manager
():
return
sys
.
modules
[
__name__
]
def
shutdown
():
pass
def
Pool
(
processes
=
None
,
initializer
=
None
,
initargs
=
()):
from
multiprocessing.pool
import
ThreadPool
return
ThreadPool
(
processes
,
initializer
,
initargs
)
JoinableQueue
=
Queue
#
# Support for the API of the multiprocessing package using threads
#
# multiprocessing/dummy/__init__.py
#
# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
#
__all__
=
[
'Process'
,
'current_process'
,
'active_children'
,
'freeze_support'
,
'Lock'
,
'RLock'
,
'Semaphore'
,
'BoundedSemaphore'
,
'Condition'
,
'Event'
,
'Queue'
,
'Manager'
,
'Pipe'
,
'Pool'
,
'JoinableQueue'
]
#
# Imports
#
import
threading
import
sys
import
weakref
import
array
import
itertools
from
multiprocessing
import
TimeoutError
,
cpu_count
from
multiprocessing.dummy.connection
import
Pipe
from
threading
import
Lock
,
RLock
,
Semaphore
,
BoundedSemaphore
from
threading
import
Event
from
Queue
import
Queue
#
#
#
class
DummyProcess
(
threading
.
Thread
):
def
__init__
(
self
,
group
=
None
,
target
=
None
,
name
=
None
,
args
=
(),
kwargs
=
{}):
threading
.
Thread
.
__init__
(
self
,
group
,
target
,
name
,
args
,
kwargs
)
self
.
_pid
=
None
self
.
_children
=
weakref
.
WeakKeyDictionary
()
self
.
_start_called
=
False
self
.
_parent
=
current_process
()
def
start
(
self
):
assert
self
.
_parent
is
current_process
()
self
.
_start_called
=
True
self
.
_parent
.
_children
[
self
]
=
None
threading
.
Thread
.
start
(
self
)
def
get_exitcode
(
self
):
if
self
.
_start_called
and
not
self
.
is_alive
():
return
0
else
:
return
None
# XXX
if
sys
.
version_info
<
(
3
,
0
):
is_alive
=
threading
.
Thread
.
is_alive
.
im_func
get_name
=
threading
.
Thread
.
get_name
.
im_func
set_name
=
threading
.
Thread
.
set_name
.
im_func
is_daemon
=
threading
.
Thread
.
is_daemon
.
im_func
set_daemon
=
threading
.
Thread
.
set_daemon
.
im_func
else
:
is_alive
=
threading
.
Thread
.
is_alive
get_name
=
threading
.
Thread
.
get_name
set_name
=
threading
.
Thread
.
set_name
is_daemon
=
threading
.
Thread
.
is_daemon
set_daemon
=
threading
.
Thread
.
set_daemon
#
#
#
class
Condition
(
threading
.
_Condition
):
# XXX
if
sys
.
version_info
<
(
3
,
0
):
notify_all
=
threading
.
_Condition
.
notify_all
.
im_func
else
:
notify_all
=
threading
.
_Condition
.
notify_all
#
#
#
Process
=
DummyProcess
current_process
=
threading
.
current_thread
current_process
().
_children
=
weakref
.
WeakKeyDictionary
()
def
active_children
():
children
=
current_process
().
_children
for
p
in
list
(
children
):
if
not
p
.
is_alive
():
children
.
pop
(
p
,
None
)
return
list
(
children
)
def
freeze_support
():
pass
#
#
#
class
Namespace
(
object
):
def
__init__
(
self
,
**
kwds
):
self
.
__dict__
.
update
(
kwds
)
def
__repr__
(
self
):
items
=
self
.
__dict__
.
items
()
temp
=
[]
for
name
,
value
in
items
:
if
not
name
.
startswith
(
'_'
):
temp
.
append
(
'%s=%r'
%
(
name
,
value
))
temp
.
sort
()
return
'Namespace(%s)'
%
str
.
join
(
', '
,
temp
)
dict
=
dict
list
=
list
def
Array
(
typecode
,
sequence
,
lock
=
True
):
return
array
.
array
(
typecode
,
sequence
)
class
Value
(
object
):
def
__init__
(
self
,
typecode
,
value
,
lock
=
True
):
self
.
_typecode
=
typecode
self
.
_value
=
value
def
_get
(
self
):
return
self
.
_value
def
_set
(
self
,
value
):
self
.
_value
=
value
value
=
property
(
_get
,
_set
)
def
__repr__
(
self
):
return
'<%r(%r, %r)>'
%
(
type
(
self
).
__name__
,
self
.
_typecode
,
self
.
_value
)
def
Manager
():
return
sys
.
modules
[
__name__
]
def
shutdown
():
pass
def
Pool
(
processes
=
None
,
initializer
=
None
,
initargs
=
()):
from
multiprocessing.pool
import
ThreadPool
return
ThreadPool
(
processes
,
initializer
,
initargs
)
JoinableQueue
=
Queue
Lib/multiprocessing/dummy/connection.py
View file @
dfd79494
#
# Analogue of `multiprocessing.connection` which uses queues instead of sockets
#
# multiprocessing/dummy/connection.py
#
# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
#
__all__
=
[
'Client'
,
'Listener'
,
'Pipe'
]
from
Queue
import
Queue
families
=
[
None
]
class
Listener
(
object
):
def
__init__
(
self
,
address
=
None
,
family
=
None
,
backlog
=
1
):
self
.
_backlog_queue
=
Queue
(
backlog
)
def
accept
(
self
):
return
Connection
(
*
self
.
_backlog_queue
.
get
())
def
close
(
self
):
self
.
_backlog_queue
=
None
address
=
property
(
lambda
self
:
self
.
_backlog_queue
)
def
Client
(
address
):
_in
,
_out
=
Queue
(),
Queue
()
address
.
put
((
_out
,
_in
))
return
Connection
(
_in
,
_out
)
def
Pipe
(
duplex
=
True
):
a
,
b
=
Queue
(),
Queue
()
return
Connection
(
a
,
b
),
Connection
(
b
,
a
)
class
Connection
(
object
):
def
__init__
(
self
,
_in
,
_out
):
self
.
_out
=
_out
self
.
_in
=
_in
self
.
send
=
self
.
send_bytes
=
_out
.
put
self
.
recv
=
self
.
recv_bytes
=
_in
.
get
def
poll
(
self
,
timeout
=
0.0
):
if
self
.
_in
.
qsize
()
>
0
:
return
True
if
timeout
<=
0.0
:
return
False
self
.
_in
.
not_empty
.
acquire
()
self
.
_in
.
not_empty
.
wait
(
timeout
)
self
.
_in
.
not_empty
.
release
()
return
self
.
_in
.
qsize
()
>
0
def
close
(
self
):
pass
#
# Analogue of `multiprocessing.connection` which uses queues instead of sockets
#
# multiprocessing/dummy/connection.py
#
# Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
#
__all__
=
[
'Client'
,
'Listener'
,
'Pipe'
]
from
Queue
import
Queue
families
=
[
None
]
class
Listener
(
object
):
def
__init__
(
self
,
address
=
None
,
family
=
None
,
backlog
=
1
):
self
.
_backlog_queue
=
Queue
(
backlog
)
def
accept
(
self
):
return
Connection
(
*
self
.
_backlog_queue
.
get
())
def
close
(
self
):
self
.
_backlog_queue
=
None
address
=
property
(
lambda
self
:
self
.
_backlog_queue
)
def
Client
(
address
):
_in
,
_out
=
Queue
(),
Queue
()
address
.
put
((
_out
,
_in
))
return
Connection
(
_in
,
_out
)
def
Pipe
(
duplex
=
True
):
a
,
b
=
Queue
(),
Queue
()
return
Connection
(
a
,
b
),
Connection
(
b
,
a
)
class
Connection
(
object
):
def
__init__
(
self
,
_in
,
_out
):
self
.
_out
=
_out
self
.
_in
=
_in
self
.
send
=
self
.
send_bytes
=
_out
.
put
self
.
recv
=
self
.
recv_bytes
=
_in
.
get
def
poll
(
self
,
timeout
=
0.0
):
if
self
.
_in
.
qsize
()
>
0
:
return
True
if
timeout
<=
0.0
:
return
False
self
.
_in
.
not_empty
.
acquire
()
self
.
_in
.
not_empty
.
wait
(
timeout
)
self
.
_in
.
not_empty
.
release
()
return
self
.
_in
.
qsize
()
>
0
def
close
(
self
):
pass
Lib/multiprocessing/forking.py
View file @
dfd79494
...
...
@@ -92,7 +92,7 @@ if sys.platform != 'win32':
except
OSError
,
e
:
if
self
.
wait
(
timeout
=
0.1
)
is
None
:
raise
@
staticmethod
def
thread_is_spawning
():
return
False
...
...
@@ -107,10 +107,10 @@ else:
import
_subprocess
import
copy_reg
import
time
from
._multiprocessing
import
win32
,
Connection
,
PipeConnection
from
.util
import
Finalize
try
:
from
cPickle
import
dump
,
load
,
HIGHEST_PROTOCOL
except
ImportError
:
...
...
@@ -217,7 +217,7 @@ else:
if
code
==
TERMINATE
:
code
=
-
signal
.
SIGTERM
self
.
returncode
=
code
return
self
.
returncode
def
poll
(
self
):
...
...
@@ -230,7 +230,7 @@ else:
except
WindowsError
:
if
self
.
wait
(
timeout
=
0.1
)
is
None
:
raise
#
#
#
...
...
@@ -308,7 +308,7 @@ else:
Return info about parent needed by child to unpickle process object
'''
from
.util
import
_logger
,
_log_to_stderr
d
=
dict
(
name
=
name
,
sys_path
=
sys
.
path
,
...
...
@@ -317,7 +317,7 @@ else:
orig_dir
=
process
.
ORIGINAL_DIR
,
authkey
=
process
.
current_process
().
get_authkey
(),
)
if
_logger
is
not
None
:
d
[
'log_level'
]
=
_logger
.
getEffectiveLevel
()
...
...
@@ -336,7 +336,7 @@ else:
#
# Make (Pipe)Connection picklable
#
def
reduce_connection
(
conn
):
if
not
Popen
.
thread_is_spawning
():
raise
RuntimeError
(
...
...
@@ -345,7 +345,7 @@ else:
)
return
type
(
conn
),
(
Popen
.
duplicate_for_child
(
conn
.
fileno
()),
conn
.
readable
,
conn
.
writable
)
copy_reg
.
pickle
(
Connection
,
reduce_connection
)
copy_reg
.
pickle
(
PipeConnection
,
reduce_connection
)
...
...
@@ -367,7 +367,7 @@ def prepare(data):
if
'authkey'
in
data
:
process
.
current_process
().
_authkey
=
data
[
'authkey'
]
if
'log_to_stderr'
in
data
and
data
[
'log_to_stderr'
]:
util
.
log_to_stderr
()
...
...
Lib/multiprocessing/heap.py
View file @
dfd79494
This diff is collapsed.
Click to expand it.
Lib/multiprocessing/managers.py
View file @
dfd79494
...
...
@@ -40,7 +40,7 @@ try:
bytes
except
NameError
:
bytes
=
str
# XXX not needed in Py2.6 and Py3.0
#
# Register some things for pickling
#
...
...
@@ -55,7 +55,7 @@ if view_types[0] is not list: # XXX only needed in Py3.0
return
list
,
(
list
(
obj
),)
for
view_type
in
view_types
:
copy_reg
.
pickle
(
view_type
,
rebuild_as_list
)
#
# Type for identifying shared objects
#
...
...
@@ -104,7 +104,7 @@ def convert_to_error(kind, result):
return
RemoteError
(
'Unserializable message: %s
\
n
'
%
result
)
else
:
return
ValueError
(
'Unrecognized message type'
)
class
RemoteError
(
Exception
):
def
__str__
(
self
):
return
(
'
\
n
'
+
'-'
*
75
+
'
\
n
'
+
str
(
self
.
args
[
0
])
+
'-'
*
75
)
...
...
@@ -340,7 +340,7 @@ class Server(object):
util
.
debug
(
'resetting stdout, stderr'
)
sys
.
stdout
=
sys
.
__stdout__
sys
.
stderr
=
sys
.
__stderr__
util
.
_run_finalizers
(
0
)
for
p
in
active_children
():
...
...
@@ -358,7 +358,7 @@ class Server(object):
traceback
.
print_exc
()
finally
:
exit
(
0
)
def
create
(
self
,
c
,
typeid
,
*
args
,
**
kwds
):
'''
Create a new shared object and return its id
...
...
@@ -367,7 +367,7 @@ class Server(object):
try
:
callable
,
exposed
,
method_to_typeid
,
proxytype
=
\
self
.
registry
[
typeid
]
if
callable
is
None
:
assert
len
(
args
)
==
1
and
not
kwds
obj
=
args
[
0
]
...
...
@@ -456,7 +456,7 @@ class BaseManager(object):
'''
_registry
=
{}
_Server
=
Server
def
__init__
(
self
,
address
=
None
,
authkey
=
None
,
serializer
=
'pickle'
):
if
authkey
is
None
:
authkey
=
current_process
().
get_authkey
()
...
...
@@ -487,7 +487,7 @@ class BaseManager(object):
conn
=
Client
(
self
.
_address
,
authkey
=
self
.
_authkey
)
dispatch
(
conn
,
None
,
'dummy'
)
self
.
_state
.
value
=
State
.
STARTED
def
start
(
self
):
'''
Spawn a server process for this manager object
...
...
@@ -570,10 +570,10 @@ class BaseManager(object):
Return the number of shared objects
'''
conn
=
self
.
_Client
(
self
.
_address
,
authkey
=
self
.
_authkey
)
try
:
try
:
return
dispatch
(
conn
,
None
,
'number_of_objects'
)
finally
:
conn
.
close
()
conn
.
close
()
def
__enter__
(
self
):
return
self
...
...
@@ -612,7 +612,7 @@ class BaseManager(object):
del
BaseProxy
.
_address_to_local
[
address
]
except
KeyError
:
pass
address
=
property
(
lambda
self
:
self
.
_address
)
@
classmethod
...
...
@@ -640,7 +640,7 @@ class BaseManager(object):
cls
.
_registry
[
typeid
]
=
(
callable
,
exposed
,
method_to_typeid
,
proxytype
)
if
create_method
:
def
temp
(
self
,
*
args
,
**
kwds
):
util
.
debug
(
'requesting creation of a shared %r object'
,
typeid
)
...
...
@@ -709,9 +709,9 @@ class BaseProxy(object):
if
incref
:
self
.
_incref
()
util
.
register_after_fork
(
self
,
BaseProxy
.
_after_fork
)
def
_connect
(
self
):
util
.
debug
(
'making connection to manager'
)
name
=
current_process
().
get_name
()
...
...
@@ -720,7 +720,7 @@ class BaseProxy(object):
conn
=
self
.
_Client
(
self
.
_token
.
address
,
authkey
=
self
.
_authkey
)
dispatch
(
conn
,
None
,
'accept_connection'
,
(
name
,))
self
.
_tls
.
connection
=
conn
def
_callmethod
(
self
,
methodname
,
args
=
(),
kwds
=
{}):
'''
Try to call a method of the referrent and return a copy of the result
...
...
@@ -735,7 +735,7 @@ class BaseProxy(object):
conn
.
send
((
self
.
_id
,
methodname
,
args
,
kwds
))
kind
,
result
=
conn
.
recv
()
if
kind
==
'#RETURN'
:
return
result
elif
kind
==
'#PROXY'
:
...
...
@@ -793,7 +793,7 @@ class BaseProxy(object):
threading
.
current_thread
().
get_name
())
tls
.
connection
.
close
()
del
tls
.
connection
def
_after_fork
(
self
):
self
.
_manager
=
None
try
:
...
...
@@ -806,7 +806,7 @@ class BaseProxy(object):
kwds
=
{}
if
Popen
.
thread_is_spawning
():
kwds
[
'authkey'
]
=
self
.
_authkey
if
getattr
(
self
,
'_isauto'
,
False
):
kwds
[
'exposed'
]
=
self
.
_exposed_
return
(
RebuildProxy
,
...
...
@@ -817,7 +817,7 @@ class BaseProxy(object):
def
__deepcopy__
(
self
,
memo
):
return
self
.
_getvalue
()
def
__repr__
(
self
):
return
'<%s object, typeid %r at %s>'
%
\
(
type
(
self
).
__name__
,
self
.
_token
.
typeid
,
'0x%x'
%
id
(
self
))
...
...
@@ -842,7 +842,7 @@ def RebuildProxy(func, token, serializer, kwds):
If possible the shared object is returned, or otherwise a proxy for it.
'''
server
=
getattr
(
current_process
(),
'_manager_server'
,
None
)
if
server
and
server
.
address
==
token
.
address
:
return
server
.
id_to_obj
[
token
.
id
][
0
]
else
:
...
...
@@ -884,7 +884,7 @@ def AutoProxy(token, serializer, manager=None, authkey=None,
Return an auto-proxy for `token`
'''
_Client
=
listener_client
[
serializer
][
1
]
if
exposed
is
None
:
conn
=
_Client
(
token
.
address
,
authkey
=
authkey
)
try
:
...
...
@@ -995,7 +995,7 @@ class NamespaceProxy(BaseProxy):
if
key
[
0
]
==
'_'
:
return
object
.
__getattribute__
(
self
,
key
)
callmethod
=
object
.
__getattribute__
(
self
,
'_callmethod'
)
return
callmethod
(
'__getattribute__'
,
(
key
,))
return
callmethod
(
'__getattribute__'
,
(
key
,))
def
__setattr__
(
self
,
key
,
value
):
if
key
[
0
]
==
'_'
:
return
object
.
__setattr__
(
self
,
key
,
value
)
...
...
@@ -1007,7 +1007,7 @@ class NamespaceProxy(BaseProxy):
callmethod
=
object
.
__getattribute__
(
self
,
'_callmethod'
)
return
callmethod
(
'__delattr__'
,
(
key
,))
class
ValueProxy
(
BaseProxy
):
_exposed_
=
(
'get'
,
'set'
)
def
get
(
self
):
...
...
@@ -1063,10 +1063,10 @@ PoolProxy._method_to_typeid_ = {
class
SyncManager
(
BaseManager
):
'''
Subclass of `BaseManager` which supports a number of shared object types.
The types registered are those intended for the synchronization
of threads, plus `dict`, `list` and `Namespace`.
The `multiprocessing.Manager()` function creates started instances of
this class.
'''
...
...
Lib/multiprocessing/pool.py
View file @
dfd79494
...
...
@@ -58,18 +58,18 @@ def worker(inqueue, outqueue, initializer=None, initargs=()):
except
(
EOFError
,
IOError
):
debug
(
'worker got EOFError or IOError -- exiting'
)
break
if
task
is
None
:
debug
(
'worker got sentinel -- exiting'
)
break
job
,
i
,
func
,
args
,
kwds
=
task
try
:
result
=
(
True
,
func
(
*
args
,
**
kwds
))
except
Exception
,
e
:
result
=
(
False
,
e
)
put
((
job
,
i
,
result
))
#
# Class representing a process pool
#
...
...
@@ -91,7 +91,7 @@ class Pool(object):
processes
=
cpu_count
()
except
NotImplementedError
:
processes
=
1
self
.
_pool
=
[]
for
i
in
range
(
processes
):
w
=
self
.
Process
(
...
...
@@ -102,7 +102,7 @@ class Pool(object):
w
.
set_name
(
w
.
get_name
().
replace
(
'Process'
,
'PoolWorker'
))
w
.
set_daemon
(
True
)
w
.
start
()
self
.
_task_handler
=
threading
.
Thread
(
target
=
Pool
.
_handle_tasks
,
args
=
(
self
.
_taskqueue
,
self
.
_quick_put
,
self
.
_outqueue
,
self
.
_pool
)
...
...
@@ -132,7 +132,7 @@ class Pool(object):
self
.
_outqueue
=
SimpleQueue
()
self
.
_quick_put
=
self
.
_inqueue
.
_writer
.
send
self
.
_quick_get
=
self
.
_outqueue
.
_reader
.
recv
def
apply
(
self
,
func
,
args
=
(),
kwds
=
{}):
'''
Equivalent of `apply()` builtin
...
...
@@ -182,7 +182,7 @@ class Pool(object):
self
.
_taskqueue
.
put
((((
result
.
_job
,
i
,
mapstar
,
(
x
,),
{})
for
i
,
x
in
enumerate
(
task_batches
)),
result
.
_set_length
))
return
(
item
for
chunk
in
result
for
item
in
chunk
)
def
apply_async
(
self
,
func
,
args
=
(),
kwds
=
{},
callback
=
None
):
'''
Asynchronous equivalent of `apply()` builtin
...
...
@@ -199,12 +199,12 @@ class Pool(object):
assert
self
.
_state
==
RUN
if
not
hasattr
(
iterable
,
'__len__'
):
iterable
=
list
(
iterable
)
if
chunksize
is
None
:
chunksize
,
extra
=
divmod
(
len
(
iterable
),
len
(
self
.
_pool
)
*
4
)
if
extra
:
chunksize
+=
1
task_batches
=
Pool
.
_get_tasks
(
func
,
iterable
,
chunksize
)
result
=
MapResult
(
self
.
_cache
,
chunksize
,
len
(
iterable
),
callback
)
self
.
_taskqueue
.
put
((((
result
.
_job
,
i
,
mapstar
,
(
x
,),
{})
...
...
@@ -234,13 +234,13 @@ class Pool(object):
break
else
:
debug
(
'task handler got sentinel'
)
try
:
# tell result handler to finish when cache is empty
debug
(
'task handler sending sentinel to result handler'
)
outqueue
.
put
(
None
)
# tell workers there is no more work
debug
(
'task handler sending sentinel to workers'
)
for
p
in
pool
:
...
...
@@ -260,12 +260,12 @@ class Pool(object):
except
(
IOError
,
EOFError
):
debug
(
'result handler got EOFError/IOError -- exiting'
)
return
if
thread
.
_state
:
assert
thread
.
_state
==
TERMINATE
debug
(
'result handler found thread._state=TERMINATE'
)
break
if
task
is
None
:
debug
(
'result handler got sentinel'
)
break
...
...
@@ -321,7 +321,7 @@ class Pool(object):
raise
NotImplementedError
(
'pool objects cannot be passed between processes or pickled'
)
def
close
(
self
):
debug
(
'closing pool'
)
if
self
.
_state
==
RUN
:
...
...
@@ -355,7 +355,7 @@ class Pool(object):
task_handler
,
result_handler
,
cache
):
# this is guaranteed to only be called once
debug
(
'finalizing pool'
)
task_handler
.
_state
=
TERMINATE
taskqueue
.
put
(
None
)
# sentinel
...
...
@@ -363,7 +363,7 @@ class Pool(object):
cls
.
_help_stuff_finish
(
inqueue
,
task_handler
,
len
(
pool
))
assert
result_handler
.
is_alive
()
or
len
(
cache
)
==
0
result_handler
.
_state
=
TERMINATE
outqueue
.
put
(
None
)
# sentinel
...
...
@@ -396,14 +396,14 @@ class ApplyResult(object):
self
.
_ready
=
False
self
.
_callback
=
callback
cache
[
self
.
_job
]
=
self
def
ready
(
self
):
return
self
.
_ready
def
successful
(
self
):
assert
self
.
_ready
return
self
.
_success
def
wait
(
self
,
timeout
=
None
):
self
.
_cond
.
acquire
()
try
:
...
...
@@ -438,7 +438,7 @@ class ApplyResult(object):
#
class
MapResult
(
ApplyResult
):
def
__init__
(
self
,
cache
,
chunksize
,
length
,
callback
):
ApplyResult
.
__init__
(
self
,
cache
,
callback
)
self
.
_success
=
True
...
...
@@ -449,7 +449,7 @@ class MapResult(ApplyResult):
self
.
_ready
=
True
else
:
self
.
_number_left
=
length
//
chunksize
+
bool
(
length
%
chunksize
)
def
_set
(
self
,
i
,
success_result
):
success
,
result
=
success_result
if
success
:
...
...
@@ -492,10 +492,10 @@ class IMapIterator(object):
self
.
_length
=
None
self
.
_unsorted
=
{}
cache
[
self
.
_job
]
=
self
def
__iter__
(
self
):
return
self
def
next
(
self
,
timeout
=
None
):
self
.
_cond
.
acquire
()
try
:
...
...
@@ -520,7 +520,7 @@ class IMapIterator(object):
raise
value
__next__
=
next
# XXX
def
_set
(
self
,
i
,
obj
):
self
.
_cond
.
acquire
()
try
:
...
...
@@ -534,12 +534,12 @@ class IMapIterator(object):
self
.
_cond
.
notify
()
else
:
self
.
_unsorted
[
i
]
=
obj
if
self
.
_index
==
self
.
_length
:
del
self
.
_cache
[
self
.
_job
]
finally
:
self
.
_cond
.
release
()
def
_set_length
(
self
,
length
):
self
.
_cond
.
acquire
()
try
:
...
...
@@ -572,18 +572,18 @@ class IMapUnorderedIterator(IMapIterator):
#
class
ThreadPool
(
Pool
):
from
.dummy
import
Process
def
__init__
(
self
,
processes
=
None
,
initializer
=
None
,
initargs
=
()):
Pool
.
__init__
(
self
,
processes
,
initializer
,
initargs
)
def
_setup_queues
(
self
):
self
.
_inqueue
=
Queue
.
Queue
()
self
.
_outqueue
=
Queue
.
Queue
()
self
.
_quick_put
=
self
.
_inqueue
.
put
self
.
_quick_get
=
self
.
_outqueue
.
get
@
staticmethod
def
_help_stuff_finish
(
inqueue
,
task_handler
,
size
):
# put sentinels at head of inqueue to make workers finish
...
...
Lib/multiprocessing/process.py
View file @
dfd79494
...
...
@@ -47,7 +47,7 @@ def active_children():
'''
_cleanup
()
return
list
(
_current_process
.
_children
)
#
#
#
...
...
@@ -69,7 +69,7 @@ class Process(object):
The class is analagous to `threading.Thread`
'''
_Popen
=
None
def
__init__
(
self
,
group
=
None
,
target
=
None
,
name
=
None
,
args
=
(),
kwargs
=
{}):
assert
group
is
None
,
'group argument must be None for now'
count
=
_current_process
.
_counter
.
next
()
...
...
@@ -91,7 +91,7 @@ class Process(object):
'''
if
self
.
_target
:
self
.
_target
(
*
self
.
_args
,
**
self
.
_kwargs
)
def
start
(
self
):
'''
Start child process
...
...
@@ -114,7 +114,7 @@ class Process(object):
Terminate process; sends SIGTERM signal or uses TerminateProcess()
'''
self
.
_popen
.
terminate
()
def
join
(
self
,
timeout
=
None
):
'''
Wait until child process terminates
...
...
@@ -217,11 +217,11 @@ class Process(object):
status
,
self
.
_daemonic
and
' daemon'
or
''
)
##
def
_bootstrap
(
self
):
from
.
import
util
global
_current_process
try
:
self
.
_children
=
set
()
self
.
_counter
=
itertools
.
count
(
1
)
...
...
Lib/multiprocessing/queues.py
View file @
dfd79494
...
...
@@ -41,9 +41,9 @@ class Queue(object):
else
:
self
.
_wlock
=
Lock
()
self
.
_sem
=
BoundedSemaphore
(
maxsize
)
self
.
_after_fork
()
if
sys
.
platform
!=
'win32'
:
register_after_fork
(
self
,
Queue
.
_after_fork
)
...
...
@@ -51,12 +51,12 @@ class Queue(object):
assert_spawning
(
self
)
return
(
self
.
_maxsize
,
self
.
_reader
,
self
.
_writer
,
self
.
_rlock
,
self
.
_wlock
,
self
.
_sem
,
self
.
_opid
)
def
__setstate__
(
self
,
state
):
(
self
.
_maxsize
,
self
.
_reader
,
self
.
_writer
,
self
.
_rlock
,
self
.
_wlock
,
self
.
_sem
,
self
.
_opid
)
=
state
self
.
_after_fork
()
def
_after_fork
(
self
):
debug
(
'Queue._after_fork()'
)
self
.
_notempty
=
threading
.
Condition
(
threading
.
Lock
())
...
...
@@ -69,7 +69,7 @@ class Queue(object):
self
.
_send
=
self
.
_writer
.
send
self
.
_recv
=
self
.
_reader
.
recv
self
.
_poll
=
self
.
_reader
.
poll
def
put
(
self
,
obj
,
block
=
True
,
timeout
=
None
):
assert
not
self
.
_closed
if
not
self
.
_sem
.
acquire
(
block
,
timeout
):
...
...
@@ -93,7 +93,7 @@ class Queue(object):
return
res
finally
:
self
.
_rlock
.
release
()
else
:
if
block
:
deadline
=
time
.
time
()
+
timeout
...
...
@@ -135,7 +135,7 @@ class Queue(object):
assert
self
.
_closed
if
self
.
_jointhread
:
self
.
_jointhread
()
def
cancel_join_thread
(
self
):
debug
(
'Queue.cancel_join_thread()'
)
self
.
_joincancelled
=
True
...
...
@@ -146,7 +146,7 @@ class Queue(object):
def
_start_thread
(
self
):
debug
(
'Queue._start_thread()'
)
# Start thread which transfers data from buffer to pipe
self
.
_buffer
.
clear
()
self
.
_thread
=
threading
.
Thread
(
...
...
@@ -174,14 +174,14 @@ class Queue(object):
[
weakref
.
ref
(
self
.
_thread
)],
exitpriority
=-
5
)
# Send sentinel to the thread queue object when garbage collected
self
.
_close
=
Finalize
(
self
,
Queue
.
_finalize_close
,
[
self
.
_buffer
,
self
.
_notempty
],
exitpriority
=
10
)
@
staticmethod
def
_finalize_join
(
twr
):
debug
(
'joining queue thread'
)
...
...
@@ -191,7 +191,7 @@ class Queue(object):
debug
(
'... queue thread joined'
)
else
:
debug
(
'... queue thread already dead'
)
@
staticmethod
def
_finalize_close
(
buffer
,
notempty
):
debug
(
'telling queue thread to quit'
)
...
...
@@ -206,7 +206,7 @@ class Queue(object):
def
_feed
(
buffer
,
notempty
,
send
,
writelock
,
close
):
debug
(
'starting thread to feed data to pipe'
)
from
.util
import
is_exiting
nacquire
=
notempty
.
acquire
nrelease
=
notempty
.
release
nwait
=
notempty
.
wait
...
...
@@ -217,7 +217,7 @@ class Queue(object):
wrelease
=
writelock
.
release
else
:
wacquire
=
None
try
:
while
1
:
nacquire
()
...
...
@@ -257,7 +257,7 @@ class Queue(object):
traceback
.
print_exc
()
except
Exception
:
pass
_sentinel
=
object
()
#
...
...
@@ -274,7 +274,7 @@ class JoinableQueue(Queue):
Queue
.
__init__
(
self
,
maxsize
)
self
.
_unfinished_tasks
=
Semaphore
(
0
)
self
.
_cond
=
Condition
()
def
__getstate__
(
self
):
return
Queue
.
__getstate__
(
self
)
+
(
self
.
_cond
,
self
.
_unfinished_tasks
)
...
...
@@ -285,7 +285,7 @@ class JoinableQueue(Queue):
def
put
(
self
,
item
,
block
=
True
,
timeout
=
None
):
Queue
.
put
(
self
,
item
,
block
,
timeout
)
self
.
_unfinished_tasks
.
release
()
def
task_done
(
self
):
self
.
_cond
.
acquire
()
try
:
...
...
@@ -295,7 +295,7 @@ class JoinableQueue(Queue):
self
.
_cond
.
notify_all
()
finally
:
self
.
_cond
.
release
()
def
join
(
self
):
self
.
_cond
.
acquire
()
try
:
...
...
Lib/multiprocessing/reduction.py
View file @
dfd79494
...
...
@@ -36,7 +36,7 @@ if not(sys.platform == 'win32' or hasattr(_multiprocessing, 'recvfd')):
if
sys
.
platform
==
'win32'
:
import
_subprocess
from
._multiprocessing
import
win32
def
send_handle
(
conn
,
handle
,
destination_pid
):
process_handle
=
win32
.
OpenProcess
(
win32
.
PROCESS_ALL_ACCESS
,
False
,
destination_pid
...
...
@@ -46,14 +46,14 @@ if sys.platform == 'win32':
conn
.
send
(
new_handle
)
finally
:
close
(
process_handle
)
def
recv_handle
(
conn
):
return
conn
.
recv
()
else
:
def
send_handle
(
conn
,
handle
,
destination_pid
):
_multiprocessing
.
sendfd
(
conn
.
fileno
(),
handle
)
def
recv_handle
(
conn
):
return
_multiprocessing
.
recvfd
(
conn
.
fileno
())
...
...
@@ -93,7 +93,7 @@ def _get_listener():
def
_serve
():
from
.util
import
is_exiting
,
sub_warning
while
1
:
try
:
conn
=
_listener
.
accept
()
...
...
@@ -109,7 +109,7 @@ def _serve():
'thread for sharing handles raised exception :
\
n
'
+
'-'
*
79
+
'
\
n
'
+
traceback
.
format_exc
()
+
'-'
*
79
)
#
# Functions to be used for pickling/unpickling objects with handles
#
...
...
@@ -176,15 +176,15 @@ copy_reg.pickle(socket.socket, reduce_socket)
#
if
sys
.
platform
==
'win32'
:
def
reduce_pipe_connection
(
conn
):
rh
=
reduce_handle
(
conn
.
fileno
())
return
rebuild_pipe_connection
,
(
rh
,
conn
.
readable
,
conn
.
writable
)
def
rebuild_pipe_connection
(
reduced_handle
,
readable
,
writable
):
handle
=
rebuild_handle
(
reduced_handle
)
return
_multiprocessing
.
PipeConnection
(
handle
,
readable
=
readable
,
writable
=
writable
)
copy_reg
.
pickle
(
_multiprocessing
.
PipeConnection
,
reduce_pipe_connection
)
Lib/multiprocessing/sharedctypes.py
View file @
dfd79494
...
...
@@ -92,10 +92,10 @@ def copy(obj):
new_obj
=
_new_value
(
type
(
obj
))
ctypes
.
pointer
(
new_obj
)[
0
]
=
obj
return
new_obj
def
synchronized
(
obj
,
lock
=
None
):
assert
not
isinstance
(
obj
,
SynchronizedBase
),
'object already synchronized'
if
isinstance
(
obj
,
ctypes
.
_SimpleCData
):
return
Synchronized
(
obj
,
lock
)
elif
isinstance
(
obj
,
ctypes
.
Array
):
...
...
@@ -123,7 +123,7 @@ def reduce_ctype(obj):
return
rebuild_ctype
,
(
obj
.
_type_
,
obj
.
_wrapper
,
obj
.
_length_
)
else
:
return
rebuild_ctype
,
(
type
(
obj
),
obj
.
_wrapper
,
None
)
def
rebuild_ctype
(
type_
,
wrapper
,
length
):
if
length
is
not
None
:
type_
=
type_
*
length
...
...
@@ -170,7 +170,7 @@ class_cache = weakref.WeakKeyDictionary()
#
class
SynchronizedBase
(
object
):
def
__init__
(
self
,
obj
,
lock
=
None
):
self
.
_obj
=
obj
self
.
_lock
=
lock
or
RLock
()
...
...
@@ -180,55 +180,55 @@ class SynchronizedBase(object):
def
__reduce__
(
self
):
assert_spawning
(
self
)
return
synchronized
,
(
self
.
_obj
,
self
.
_lock
)
def
get_obj
(
self
):
return
self
.
_obj
def
get_lock
(
self
):
return
self
.
_lock
def
__repr__
(
self
):
return
'<%s wrapper for %s>'
%
(
type
(
self
).
__name__
,
self
.
_obj
)
class
Synchronized
(
SynchronizedBase
):
value
=
make_property
(
'value'
)
class
SynchronizedArray
(
SynchronizedBase
):
def
__len__
(
self
):
return
len
(
self
.
_obj
)
def
__getitem__
(
self
,
i
):
self
.
acquire
()
try
:
return
self
.
_obj
[
i
]
finally
:
self
.
release
()
def
__setitem__
(
self
,
i
,
value
):
self
.
acquire
()
try
:
self
.
_obj
[
i
]
=
value
finally
:
self
.
release
()
def
__getslice__
(
self
,
start
,
stop
):
self
.
acquire
()
try
:
return
self
.
_obj
[
start
:
stop
]
finally
:
self
.
release
()
def
__setslice__
(
self
,
start
,
stop
,
values
):
self
.
acquire
()
try
:
self
.
_obj
[
start
:
stop
]
=
values
finally
:
self
.
release
()
class
SynchronizedString
(
SynchronizedArray
):
value
=
make_property
(
'value'
)
raw
=
make_property
(
'raw'
)
Lib/multiprocessing/synchronize.py
View file @
dfd79494
...
...
@@ -38,7 +38,7 @@ class SemLock(object):
sl
=
self
.
_semlock
=
_multiprocessing
.
SemLock
(
kind
,
value
,
maxvalue
)
debug
(
'created semlock with handle %s'
%
sl
.
handle
)
self
.
_make_methods
()
if
sys
.
platform
!=
'win32'
:
def
_after_fork
(
obj
):
obj
.
_semlock
.
_after_fork
()
...
...
@@ -129,7 +129,7 @@ class RLock(SemLock):
def
__init__
(
self
):
SemLock
.
__init__
(
self
,
RECURSIVE_MUTEX
,
1
,
1
)
def
__repr__
(
self
):
try
:
if
self
.
_semlock
.
_is_mine
():
...
...
@@ -210,17 +210,17 @@ class Condition(object):
def
notify
(
self
):
assert
self
.
_lock
.
_semlock
.
_is_mine
(),
'lock is not owned'
assert
not
self
.
_wait_semaphore
.
acquire
(
False
)
# to take account of timeouts since last notify() we subtract
# woken_count from sleeping_count and rezero woken_count
while
self
.
_woken_count
.
acquire
(
False
):
res
=
self
.
_sleeping_count
.
acquire
(
False
)
assert
res
if
self
.
_sleeping_count
.
acquire
(
False
):
# try grabbing a sleeper
self
.
_wait_semaphore
.
release
()
# wake up one sleeper
self
.
_woken_count
.
acquire
()
# wait for the sleeper to wake
# rezero _wait_semaphore in case a timeout just happened
self
.
_wait_semaphore
.
acquire
(
False
)
...
...
@@ -233,7 +233,7 @@ class Condition(object):
while
self
.
_woken_count
.
acquire
(
False
):
res
=
self
.
_sleeping_count
.
acquire
(
False
)
assert
res
sleepers
=
0
while
self
.
_sleeping_count
.
acquire
(
False
):
self
.
_wait_semaphore
.
release
()
# wake up one sleeper
...
...
@@ -266,7 +266,7 @@ class Event(object):
return
False
finally
:
self
.
_cond
.
release
()
def
set
(
self
):
self
.
_cond
.
acquire
()
try
:
...
...
Lib/multiprocessing/util.py
View file @
dfd79494
...
...
@@ -83,7 +83,7 @@ def _check_logger_class():
import
logging
if
hasattr
(
logging
,
'multiprocessing'
):
return
logging
.
_acquireLock
()
try
:
OldLoggerClass
=
logging
.
getLoggerClass
()
...
...
Lib/test/test_multiprocessing.py
View file @
dfd79494
This diff is collapsed.
Click to expand it.
Modules/_multiprocessing/multiprocessing.c
View file @
dfd79494
This diff is collapsed.
Click to expand it.
Modules/_multiprocessing/multiprocessing.h
View file @
dfd79494
#ifndef MULTIPROCESSING_H
#define MULTIPROCESSING_H
#define PY_SSIZE_T_CLEAN
#include "Python.h"
#include "structmember.h"
#include "pythread.h"
/*
* Platform includes and definitions
*/
#ifdef MS_WINDOWS
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# include <winsock2.h>
# include <process.h>
/* getpid() */
# define SEM_HANDLE HANDLE
# define SEM_VALUE_MAX LONG_MAX
#else
# include <fcntl.h>
/* O_CREAT and O_EXCL */
# include <sys/socket.h>
# include <arpa/inet.h>
/* htonl() and ntohl() */
# if HAVE_SEM_OPEN
# include <semaphore.h>
typedef
sem_t
*
SEM_HANDLE
;
# endif
# 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)
#endif
/*
* Make sure Py_ssize_t available
*/
#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
typedef
int
Py_ssize_t
;
# define PY_SSIZE_T_MAX INT_MAX
# define PY_SSIZE_T_MIN INT_MIN
# define F_PY_SSIZE_T "i"
# define PY_FORMAT_SIZE_T ""
# define PyInt_FromSsize_t(n) PyInt_FromLong((long)n)
#else
# define F_PY_SSIZE_T "n"
#endif
/*
* Format codes
*/
#if SIZEOF_VOID_P == SIZEOF_LONG
# define F_POINTER "k"
# define T_POINTER T_ULONG
#elif defined(HAVE_LONG_LONG) && (SIZEOF_VOID_P == SIZEOF_LONG_LONG)
# define F_POINTER "K"
# define T_POINTER T_ULONGLONG
#else
# error "can't find format code for unsigned integer of same size as void*"
#endif
#ifdef MS_WINDOWS
# define F_HANDLE F_POINTER
# define T_HANDLE T_POINTER
# define F_SEM_HANDLE F_HANDLE
# define T_SEM_HANDLE T_HANDLE
# define F_DWORD "k"
# define T_DWORD T_ULONG
#else
# define F_HANDLE "i"
# define T_HANDLE T_INT
# define F_SEM_HANDLE F_POINTER
# define T_SEM_HANDLE T_POINTER
#endif
#if PY_VERSION_HEX >= 0x03000000
# define F_RBUFFER "y"
#else
# define F_RBUFFER "s"
#endif
/*
* Error codes which can be returned by functions called without GIL
*/
#define MP_SUCCESS (0)
#define MP_STANDARD_ERROR (-1)
#define MP_MEMORY_ERROR (-1001)
#define MP_END_OF_FILE (-1002)
#define MP_EARLY_END_OF_FILE (-1003)
#define MP_BAD_MESSAGE_LENGTH (-1004)
#define MP_SOCKET_ERROR (-1005)
#define MP_EXCEPTION_HAS_BEEN_SET (-1006)
PyObject
*
mp_SetError
(
PyObject
*
Type
,
int
num
);
/*
* Externs - not all will really exist on all platforms
*/
extern
PyObject
*
pickle_dumps
;
extern
PyObject
*
pickle_loads
;
extern
PyObject
*
pickle_protocol
;
extern
PyObject
*
BufferTooShort
;
extern
PyTypeObject
SemLockType
;
extern
PyTypeObject
ConnectionType
;
extern
PyTypeObject
PipeConnectionType
;
extern
HANDLE
sigint_event
;
/*
* Py3k compatibility
*/
#if PY_VERSION_HEX >= 0x03000000
# define PICKLE_MODULE "pickle"
# define FROM_FORMAT PyUnicode_FromFormat
# define PyInt_FromLong PyLong_FromLong
# define PyInt_FromSsize_t PyLong_FromSsize_t
#else
# define PICKLE_MODULE "cPickle"
# define FROM_FORMAT PyString_FromFormat
#endif
#ifndef PyVarObject_HEAD_INIT
# define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
#endif
#ifndef Py_TPFLAGS_HAVE_WEAKREFS
# define Py_TPFLAGS_HAVE_WEAKREFS 0
#endif
/*
* Connection definition
*/
#define CONNECTION_BUFFER_SIZE 1024
typedef
struct
{
PyObject_HEAD
HANDLE
handle
;
int
flags
;
PyObject
*
weakreflist
;
char
buffer
[
CONNECTION_BUFFER_SIZE
];
}
ConnectionObject
;
/*
* Miscellaneous
*/
#define MAX_MESSAGE_LENGTH 0x7fffffff
#ifndef MIN
# define MIN(x, y) ((x) < (y) ? x : y)
# define MAX(x, y) ((x) > (y) ? x : y)
#endif
#endif
/* MULTIPROCESSING_H */
#ifndef MULTIPROCESSING_H
#define MULTIPROCESSING_H
#define PY_SSIZE_T_CLEAN
#include "Python.h"
#include "structmember.h"
#include "pythread.h"
/*
* Platform includes and definitions
*/
#ifdef MS_WINDOWS
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# include <winsock2.h>
# include <process.h>
/* getpid() */
# define SEM_HANDLE HANDLE
# define SEM_VALUE_MAX LONG_MAX
#else
# include <fcntl.h>
/* O_CREAT and O_EXCL */
# include <sys/socket.h>
# include <arpa/inet.h>
/* htonl() and ntohl() */
# if HAVE_SEM_OPEN
# include <semaphore.h>
typedef
sem_t
*
SEM_HANDLE
;
# endif
# 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)
#endif
/*
* Make sure Py_ssize_t available
*/
#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
typedef
int
Py_ssize_t
;
# define PY_SSIZE_T_MAX INT_MAX
# define PY_SSIZE_T_MIN INT_MIN
# define F_PY_SSIZE_T "i"
# define PY_FORMAT_SIZE_T ""
# define PyInt_FromSsize_t(n) PyInt_FromLong((long)n)
#else
# define F_PY_SSIZE_T "n"
#endif
/*
* Format codes
*/
#if SIZEOF_VOID_P == SIZEOF_LONG
# define F_POINTER "k"
# define T_POINTER T_ULONG
#elif defined(HAVE_LONG_LONG) && (SIZEOF_VOID_P == SIZEOF_LONG_LONG)
# define F_POINTER "K"
# define T_POINTER T_ULONGLONG
#else
# error "can't find format code for unsigned integer of same size as void*"
#endif
#ifdef MS_WINDOWS
# define F_HANDLE F_POINTER
# define T_HANDLE T_POINTER
# define F_SEM_HANDLE F_HANDLE
# define T_SEM_HANDLE T_HANDLE
# define F_DWORD "k"
# define T_DWORD T_ULONG
#else
# define F_HANDLE "i"
# define T_HANDLE T_INT
# define F_SEM_HANDLE F_POINTER
# define T_SEM_HANDLE T_POINTER
#endif
#if PY_VERSION_HEX >= 0x03000000
# define F_RBUFFER "y"
#else
# define F_RBUFFER "s"
#endif
/*
* Error codes which can be returned by functions called without GIL
*/
#define MP_SUCCESS (0)
#define MP_STANDARD_ERROR (-1)
#define MP_MEMORY_ERROR (-1001)
#define MP_END_OF_FILE (-1002)
#define MP_EARLY_END_OF_FILE (-1003)
#define MP_BAD_MESSAGE_LENGTH (-1004)
#define MP_SOCKET_ERROR (-1005)
#define MP_EXCEPTION_HAS_BEEN_SET (-1006)
PyObject
*
mp_SetError
(
PyObject
*
Type
,
int
num
);
/*
* Externs - not all will really exist on all platforms
*/
extern
PyObject
*
pickle_dumps
;
extern
PyObject
*
pickle_loads
;
extern
PyObject
*
pickle_protocol
;
extern
PyObject
*
BufferTooShort
;
extern
PyTypeObject
SemLockType
;
extern
PyTypeObject
ConnectionType
;
extern
PyTypeObject
PipeConnectionType
;
extern
HANDLE
sigint_event
;
/*
* Py3k compatibility
*/
#if PY_VERSION_HEX >= 0x03000000
# define PICKLE_MODULE "pickle"
# define FROM_FORMAT PyUnicode_FromFormat
# define PyInt_FromLong PyLong_FromLong
# define PyInt_FromSsize_t PyLong_FromSsize_t
#else
# define PICKLE_MODULE "cPickle"
# define FROM_FORMAT PyString_FromFormat
#endif
#ifndef PyVarObject_HEAD_INIT
# define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
#endif
#ifndef Py_TPFLAGS_HAVE_WEAKREFS
# define Py_TPFLAGS_HAVE_WEAKREFS 0
#endif
/*
* Connection definition
*/
#define CONNECTION_BUFFER_SIZE 1024
typedef
struct
{
PyObject_HEAD
HANDLE
handle
;
int
flags
;
PyObject
*
weakreflist
;
char
buffer
[
CONNECTION_BUFFER_SIZE
];
}
ConnectionObject
;
/*
* Miscellaneous
*/
#define MAX_MESSAGE_LENGTH 0x7fffffff
#ifndef MIN
# define MIN(x, y) ((x) < (y) ? x : y)
# define MAX(x, y) ((x) > (y) ? x : y)
#endif
#endif
/* MULTIPROCESSING_H */
Modules/_multiprocessing/pipe_connection.c
View file @
dfd79494
/*
* A type which wraps a pipe handle in message oriented mode
*
* pipe_connection.c
*
* Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
*/
#include "multiprocessing.h"
#define CLOSE(h) CloseHandle(h)
/*
* Send string to the pipe; assumes in message oriented mode
*/
static
Py_ssize_t
conn_send_string
(
ConnectionObject
*
conn
,
char
*
string
,
size_t
length
)
{
DWORD
amount_written
;
return
WriteFile
(
conn
->
handle
,
string
,
length
,
&
amount_written
,
NULL
)
?
MP_SUCCESS
:
MP_STANDARD_ERROR
;
}
/*
* Attempts to read into buffer, or if buffer too small into *newbuffer.
*
* Returns number of bytes read. Assumes in message oriented mode.
*/
static
Py_ssize_t
conn_recv_string
(
ConnectionObject
*
conn
,
char
*
buffer
,
size_t
buflength
,
char
**
newbuffer
,
size_t
maxlength
)
{
DWORD
left
,
length
,
full_length
,
err
;
*
newbuffer
=
NULL
;
if
(
ReadFile
(
conn
->
handle
,
buffer
,
MIN
(
buflength
,
maxlength
),
&
length
,
NULL
))
return
length
;
err
=
GetLastError
();
if
(
err
!=
ERROR_MORE_DATA
)
{
if
(
err
==
ERROR_BROKEN_PIPE
)
return
MP_END_OF_FILE
;
return
MP_STANDARD_ERROR
;
}
if
(
!
PeekNamedPipe
(
conn
->
handle
,
NULL
,
0
,
NULL
,
NULL
,
&
left
))
return
MP_STANDARD_ERROR
;
full_length
=
length
+
left
;
if
(
full_length
>
maxlength
)
return
MP_BAD_MESSAGE_LENGTH
;
*
newbuffer
=
PyMem_Malloc
(
full_length
);
if
(
*
newbuffer
==
NULL
)
return
MP_MEMORY_ERROR
;
memcpy
(
*
newbuffer
,
buffer
,
length
);
if
(
ReadFile
(
conn
->
handle
,
*
newbuffer
+
length
,
left
,
&
length
,
NULL
))
{
assert
(
length
==
left
);
return
full_length
;
}
else
{
PyMem_Free
(
*
newbuffer
);
return
MP_STANDARD_ERROR
;
}
}
/*
* Check whether any data is available for reading
*/
#define conn_poll(conn, timeout) conn_poll_save(conn, timeout, _save)
static
int
conn_poll_save
(
ConnectionObject
*
conn
,
double
timeout
,
PyThreadState
*
_save
)
{
DWORD
bytes
,
deadline
,
delay
;
int
difference
,
res
;
BOOL
block
=
FALSE
;
if
(
!
PeekNamedPipe
(
conn
->
handle
,
NULL
,
0
,
NULL
,
&
bytes
,
NULL
))
return
MP_STANDARD_ERROR
;
if
(
timeout
==
0
.
0
)
return
bytes
>
0
;
if
(
timeout
<
0
.
0
)
block
=
TRUE
;
else
/* XXX does not check for overflow */
deadline
=
GetTickCount
()
+
(
DWORD
)(
1000
*
timeout
+
0
.
5
);
Sleep
(
0
);
for
(
delay
=
1
;
;
delay
+=
1
)
{
if
(
!
PeekNamedPipe
(
conn
->
handle
,
NULL
,
0
,
NULL
,
&
bytes
,
NULL
))
return
MP_STANDARD_ERROR
;
else
if
(
bytes
>
0
)
return
TRUE
;
if
(
!
block
)
{
difference
=
deadline
-
GetTickCount
();
if
(
difference
<
0
)
return
FALSE
;
if
((
int
)
delay
>
difference
)
delay
=
difference
;
}
if
(
delay
>
20
)
delay
=
20
;
Sleep
(
delay
);
/* check for signals */
Py_BLOCK_THREADS
res
=
PyErr_CheckSignals
();
Py_UNBLOCK_THREADS
if
(
res
)
return
MP_EXCEPTION_HAS_BEEN_SET
;
}
}
/*
* "connection.h" defines the PipeConnection type using the definitions above
*/
#define CONNECTION_NAME "PipeConnection"
#define CONNECTION_TYPE PipeConnectionType
#include "connection.h"
/*
* A type which wraps a pipe handle in message oriented mode
*
* pipe_connection.c
*
* Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
*/
#include "multiprocessing.h"
#define CLOSE(h) CloseHandle(h)
/*
* Send string to the pipe; assumes in message oriented mode
*/
static
Py_ssize_t
conn_send_string
(
ConnectionObject
*
conn
,
char
*
string
,
size_t
length
)
{
DWORD
amount_written
;
return
WriteFile
(
conn
->
handle
,
string
,
length
,
&
amount_written
,
NULL
)
?
MP_SUCCESS
:
MP_STANDARD_ERROR
;
}
/*
* Attempts to read into buffer, or if buffer too small into *newbuffer.
*
* Returns number of bytes read. Assumes in message oriented mode.
*/
static
Py_ssize_t
conn_recv_string
(
ConnectionObject
*
conn
,
char
*
buffer
,
size_t
buflength
,
char
**
newbuffer
,
size_t
maxlength
)
{
DWORD
left
,
length
,
full_length
,
err
;
*
newbuffer
=
NULL
;
if
(
ReadFile
(
conn
->
handle
,
buffer
,
MIN
(
buflength
,
maxlength
),
&
length
,
NULL
))
return
length
;
err
=
GetLastError
();
if
(
err
!=
ERROR_MORE_DATA
)
{
if
(
err
==
ERROR_BROKEN_PIPE
)
return
MP_END_OF_FILE
;
return
MP_STANDARD_ERROR
;
}
if
(
!
PeekNamedPipe
(
conn
->
handle
,
NULL
,
0
,
NULL
,
NULL
,
&
left
))
return
MP_STANDARD_ERROR
;
full_length
=
length
+
left
;
if
(
full_length
>
maxlength
)
return
MP_BAD_MESSAGE_LENGTH
;
*
newbuffer
=
PyMem_Malloc
(
full_length
);
if
(
*
newbuffer
==
NULL
)
return
MP_MEMORY_ERROR
;
memcpy
(
*
newbuffer
,
buffer
,
length
);
if
(
ReadFile
(
conn
->
handle
,
*
newbuffer
+
length
,
left
,
&
length
,
NULL
))
{
assert
(
length
==
left
);
return
full_length
;
}
else
{
PyMem_Free
(
*
newbuffer
);
return
MP_STANDARD_ERROR
;
}
}
/*
* Check whether any data is available for reading
*/
#define conn_poll(conn, timeout) conn_poll_save(conn, timeout, _save)
static
int
conn_poll_save
(
ConnectionObject
*
conn
,
double
timeout
,
PyThreadState
*
_save
)
{
DWORD
bytes
,
deadline
,
delay
;
int
difference
,
res
;
BOOL
block
=
FALSE
;
if
(
!
PeekNamedPipe
(
conn
->
handle
,
NULL
,
0
,
NULL
,
&
bytes
,
NULL
))
return
MP_STANDARD_ERROR
;
if
(
timeout
==
0
.
0
)
return
bytes
>
0
;
if
(
timeout
<
0
.
0
)
block
=
TRUE
;
else
/* XXX does not check for overflow */
deadline
=
GetTickCount
()
+
(
DWORD
)(
1000
*
timeout
+
0
.
5
);
Sleep
(
0
);
for
(
delay
=
1
;
;
delay
+=
1
)
{
if
(
!
PeekNamedPipe
(
conn
->
handle
,
NULL
,
0
,
NULL
,
&
bytes
,
NULL
))
return
MP_STANDARD_ERROR
;
else
if
(
bytes
>
0
)
return
TRUE
;
if
(
!
block
)
{
difference
=
deadline
-
GetTickCount
();
if
(
difference
<
0
)
return
FALSE
;
if
((
int
)
delay
>
difference
)
delay
=
difference
;
}
if
(
delay
>
20
)
delay
=
20
;
Sleep
(
delay
);
/* check for signals */
Py_BLOCK_THREADS
res
=
PyErr_CheckSignals
();
Py_UNBLOCK_THREADS
if
(
res
)
return
MP_EXCEPTION_HAS_BEEN_SET
;
}
}
/*
* "connection.h" defines the PipeConnection type using the definitions above
*/
#define CONNECTION_NAME "PipeConnection"
#define CONNECTION_TYPE PipeConnectionType
#include "connection.h"
Modules/_multiprocessing/win32_functions.c
View file @
dfd79494
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment