2727
2828from .util import debug , info , Finalize , register_after_fork , is_exiting
2929
30+ #
31+ # Sendable Object, with a serialization protocol
32+ #
33+
34+
35+ class _SendableObject (object ):
36+ def __init__ (self , obj , serialization = None ):
37+ self .obj = obj
38+ self .serialization = serialization
39+
40+ def serialize (self ):
41+ if self .serialization :
42+ return self .serialization (self .obj )
43+ return self .obj
44+
45+
3046#
3147# Queue type using a pipe, buffer and thread
3248#
@@ -78,17 +94,26 @@ def _after_fork(self):
7894 self ._poll = self ._reader .poll
7995
8096 def put (self , obj , block = True , timeout = None ):
97+ self ._put_bytes (obj , block = block , timeout = timeout ,
98+ serialization = _ForkingPickler .dumps )
99+
100+ def _put_bytes (self , obj , block = True , timeout = None , serialization = None ):
81101 assert not self ._closed , "Queue {0!r} has been closed" .format (self )
82102 if not self ._sem .acquire (block , timeout ):
83103 raise Full
84104
85105 with self ._notempty :
86106 if self ._thread is None :
87107 self ._start_thread ()
88- self ._buffer .append (obj )
108+ self ._buffer .append (_SendableObject (
109+ obj , serialization = serialization ))
89110 self ._notempty .notify ()
90111
91112 def get (self , block = True , timeout = None ):
113+ return self ._get_bytes (block = block , timeout = timeout ,
114+ deserialization = _ForkingPickler .loads )
115+
116+ def _get_bytes (self , block = True , timeout = None , deserialization = None ):
92117 if block and timeout is None :
93118 with self ._rlock :
94119 res = self ._recv_bytes ()
@@ -109,8 +134,10 @@ def get(self, block=True, timeout=None):
109134 self ._sem .release ()
110135 finally :
111136 self ._rlock .release ()
112- # unserialize the data after having released the lock
113- return _ForkingPickler .loads (res )
137+ # un-serialize the data after having released the lock
138+ if deserialization :
139+ return deserialization (res )
140+ return res
114141
115142 def qsize (self ):
116143 # Raises NotImplementedError on Mac OSX because of broken sem_getvalue()
@@ -233,7 +260,7 @@ def _feed(buffer, notempty, send_bytes, writelock, close, ignore_epipe,
233260 return
234261
235262 # serialize the data before acquiring the lock
236- obj = _ForkingPickler . dumps ( obj )
263+ obj = obj . serialize ( )
237264 if wacquire is None :
238265 send_bytes (obj )
239266 else :
@@ -255,7 +282,7 @@ def _feed(buffer, notempty, send_bytes, writelock, close, ignore_epipe,
255282 info ('error in queue thread: %s' , e )
256283 return
257284 else :
258- onerror (e , obj )
285+ onerror (e , obj . obj )
259286
260287 @staticmethod
261288 def _on_queue_feeder_error (e , obj ):
@@ -299,7 +326,8 @@ def put(self, obj, block=True, timeout=None):
299326 with self ._notempty , self ._cond :
300327 if self ._thread is None :
301328 self ._start_thread ()
302- self ._buffer .append (obj )
329+ self ._buffer .append (_SendableObject (
330+ obj , serialization = _ForkingPickler .dumps ))
303331 self ._unfinished_tasks .release ()
304332 self ._notempty .notify ()
305333
@@ -342,14 +370,25 @@ def __setstate__(self, state):
342370 self ._poll = self ._reader .poll
343371
344372 def get (self ):
373+ # Get the object and deserialize it with the _ForkingPickler
374+ return self ._get_bytes (deserialization = _ForkingPickler .loads )
375+
376+ def _get_bytes (self , deserialization = None ):
345377 with self ._rlock :
346378 res = self ._reader .recv_bytes ()
347379 # unserialize the data after having released the lock
348- return _ForkingPickler .loads (res )
380+ if deserialization :
381+ return deserialization (res )
382+ return res
349383
350384 def put (self , obj ):
385+ # Get the object and deserialize it with the _ForkingPickler
386+ self ._put_bytes (obj , serialization = _ForkingPickler .dumps )
387+
388+ def _put_bytes (self , obj , serialization = None ):
351389 # serialize the data before acquiring the lock
352- obj = _ForkingPickler .dumps (obj )
390+ if serialization :
391+ obj = serialization (obj )
353392 if self ._wlock is None :
354393 # writes to a message oriented win32 pipe are atomic
355394 self ._writer .send_bytes (obj )
0 commit comments