[pypy-svn] r47516 - pypy/dist/pypy/module/zlib
arigo at codespeak.net
arigo at codespeak.net
Wed Oct 17 17:19:24 CEST 2007
Author: arigo
Date: Wed Oct 17 17:19:22 2007
New Revision: 47516
Modified:
pypy/dist/pypy/module/zlib/interp_zlib.py
Log:
Increase the probability to be safe against __del__ being called while
self.stream is still in use.
Modified: pypy/dist/pypy/module/zlib/interp_zlib.py
==============================================================================
--- pypy/dist/pypy/module/zlib/interp_zlib.py (original)
+++ pypy/dist/pypy/module/zlib/interp_zlib.py Wed Oct 17 17:19:22 2007
@@ -4,6 +4,7 @@
from pypy.interpreter.typedef import TypeDef, interp_attrproperty
from pypy.interpreter.error import OperationError
from pypy.rlib.rarithmetic import intmask
+from pypy.rlib.objectmodel import keepalive_until_here
from pypy.rlib import rzlib
@@ -95,19 +96,39 @@
decompress.unwrap_spec = [ObjSpace, str, int, int]
-class Compress(Wrappable):
+class ZLibObject(Wrappable):
"""
- Wrapper around zlib's z_stream structure which provides convenient
- compression functionality.
+ Common base class for Compress and Decompress.
"""
stream = rzlib.null_stream
+ def __init__(self, space):
+ self.space = space
+ self._lock = space.allocate_lock()
+
+ def lock(self):
+ """To call before using self.stream."""
+ self._lock.acquire(True)
+
+ def unlock(self):
+ """To call after using self.stream."""
+ self._lock.release()
+ keepalive_until_here(self)
+ # subtle: we have to make sure that 'self' is not garbage-collected
+ # while we are still using 'self.stream' - hence the keepalive.
+
+
+class Compress(ZLibObject):
+ """
+ Wrapper around zlib's z_stream structure which provides convenient
+ compression functionality.
+ """
def __init__(self, space, level=rzlib.Z_DEFAULT_COMPRESSION,
method=rzlib.Z_DEFLATED, # \
wbits=rzlib.MAX_WBITS, # \ undocumented
memLevel=rzlib.DEF_MEM_LEVEL, # / parameters
strategy=rzlib.Z_DEFAULT_STRATEGY): # /
- self.space = space
+ ZLibObject.__init__(self, space)
try:
self.stream = rzlib.deflateInit(level, method, wbits,
memLevel, strategy)
@@ -116,7 +137,6 @@
except ValueError:
raise OperationError(space.w_ValueError,
space.wrap("Invalid initialization option"))
- self.lock = space.allocate_lock()
def __del__(self):
"""Automatically free the resources used by the stream."""
@@ -135,15 +155,14 @@
Call the flush() method to clear these buffers.
"""
try:
- lock = self.lock
- lock.acquire(True)
+ self.lock()
try:
if not self.stream:
raise zlib_error(self.space,
"compressor object already flushed")
result = rzlib.compress(self.stream, data)
finally:
- lock.release()
+ self.unlock()
except rzlib.RZlibError, e:
raise zlib_error(self.space, e.msg)
return self.space.wrap(result)
@@ -163,20 +182,19 @@
compressed.
"""
try:
- lock = self.lock
- lock.acquire(True)
+ self.lock()
try:
if not self.stream:
raise zlib_error(self.space,
"compressor object already flushed")
result = rzlib.compress(self.stream, '', mode)
+ if mode == rzlib.Z_FINISH: # release the data structures now
+ rzlib.deflateEnd(self.stream)
+ self.stream = rzlib.null_stream
finally:
- lock.release()
+ self.unlock()
except rzlib.RZlibError, e:
raise zlib_error(self.space, e.msg)
- if mode == rzlib.Z_FINISH: # release the data structures now
- rzlib.deflateEnd(self.stream)
- self.stream = rzlib.null_stream
return self.space.wrap(result)
flush.unwrap_spec = ['self', int]
@@ -208,13 +226,11 @@
""")
-class Decompress(Wrappable):
+class Decompress(ZLibObject):
"""
Wrapper around zlib's z_stream structure which provides convenient
decompression functionality.
"""
- stream = rzlib.null_stream
-
def __init__(self, space, wbits=rzlib.MAX_WBITS):
"""
Initialize a new decompression object.
@@ -224,7 +240,7 @@
and decompression. See the documentation for deflateInit2 and
inflateInit2.
"""
- self.space = space
+ ZLibObject.__init__(self, space)
self.unused_data = ''
self.unconsumed_tail = ''
try:
@@ -234,7 +250,6 @@
except ValueError:
raise OperationError(space.w_ValueError,
space.wrap("Invalid initialization option"))
- self.lock = space.allocate_lock()
def __del__(self):
"""Automatically free the resources used by the stream."""
@@ -259,13 +274,12 @@
self.space.wrap("max_length must be "
"greater than zero"))
try:
- lock = self.lock
- lock.acquire(True)
+ self.lock()
try:
result = rzlib.decompress(self.stream, data,
max_length = max_length)
finally:
- lock.release()
+ self.unlock()
except rzlib.RZlibError, e:
raise zlib_error(self.space, e.msg)
More information about the Pypy-commit
mailing list