@@ -250,7 +250,7 @@ def __init__(self,
250250 quality = lib .BROTLI_DEFAULT_QUALITY ,
251251 lgwin = lib .BROTLI_DEFAULT_WINDOW ,
252252 lgblock = 0 ):
253- self .lock = threading .Lock ()
253+ self .lock = threading .RLock ()
254254 enc = lib .BrotliEncoderCreateInstance (
255255 ffi .NULL , ffi .NULL , ffi .NULL
256256 )
@@ -273,23 +273,23 @@ def _compress(self, data, operation):
273273 because almost all of the code uses the exact same setup. It wouldn't
274274 have to, but it doesn't hurt at all.
275275 """
276- # The 'algorithm' for working out how big to make this buffer is from
277- # the Brotli source code, brotlimodule.cc.
278- original_output_size = int (
279- math .ceil (len (data ) + (len (data ) >> 2 ) + 10240 )
280- )
281- available_out = ffi .new ("size_t *" )
282- available_out [0 ] = original_output_size
283- output_buffer = ffi .new ("uint8_t []" , available_out [0 ])
284- ptr_to_output_buffer = ffi .new ("uint8_t **" , output_buffer )
285- input_size = ffi .new ("size_t *" , len (data ))
286- input_buffer = ffi .new ("uint8_t []" , data )
287- ptr_to_input_buffer = ffi .new ("uint8_t **" , input_buffer )
288-
289276 if not self .lock .acquire (blocking = False ):
290277 raise error (
291278 "Concurrently sharing Compressor objects is not allowed" )
292279 try :
280+ # The 'algorithm' for working out how big to make this buffer is
281+ # from the Brotli source code, brotlimodule.cc.
282+ original_output_size = int (
283+ math .ceil (len (data ) + (len (data ) >> 2 ) + 10240 )
284+ )
285+ available_out = ffi .new ("size_t *" )
286+ available_out [0 ] = original_output_size
287+ output_buffer = ffi .new ("uint8_t []" , available_out [0 ])
288+ ptr_to_output_buffer = ffi .new ("uint8_t **" , output_buffer )
289+ input_size = ffi .new ("size_t *" , len (data ))
290+ input_buffer = ffi .new ("uint8_t []" , data )
291+ ptr_to_input_buffer = ffi .new ("uint8_t **" , input_buffer )
292+
293293 rc = lib .BrotliEncoderCompressStream (
294294 self ._encoder ,
295295 operation ,
@@ -328,11 +328,17 @@ def flush(self):
328328 will not destroy the compressor. It can be used, for example, to ensure
329329 that given chunks of content will decompress immediately.
330330 """
331- chunks = [self ._compress (b'' , lib .BROTLI_OPERATION_FLUSH )]
332-
333- while lib .BrotliEncoderHasMoreOutput (self ._encoder ) == lib .BROTLI_TRUE :
334- chunks .append (self ._compress (b'' , lib .BROTLI_OPERATION_FLUSH ))
331+ if not self .lock .acquire (blocking = False ):
332+ raise error (
333+ "Concurrently sharing Compressor objects is not allowed" )
334+ try :
335+ chunks = [self ._compress (b'' , lib .BROTLI_OPERATION_FLUSH )]
335336
337+ while ((lib .BrotliEncoderHasMoreOutput (self ._encoder ) ==
338+ lib .BROTLI_TRUE )):
339+ chunks .append (self ._compress (b'' , lib .BROTLI_OPERATION_FLUSH ))
340+ finally :
341+ self .lock .release ()
336342 return b'' .join (chunks )
337343
338344 def finish (self ):
@@ -341,10 +347,16 @@ def finish(self):
341347 transition the compressor to a completed state. The compressor cannot
342348 be used again after this point, and must be replaced.
343349 """
344- chunks = []
345- while lib .BrotliEncoderIsFinished (self ._encoder ) == lib .BROTLI_FALSE :
346- chunks .append (self ._compress (b'' , lib .BROTLI_OPERATION_FINISH ))
347-
350+ if not self .lock .acquire (blocking = False ):
351+ raise error (
352+ "Concurrently sharing Compressor objects is not allowed" )
353+ try :
354+ chunks = []
355+ while ((lib .BrotliEncoderIsFinished (self ._encoder ) ==
356+ lib .BROTLI_FALSE )):
357+ chunks .append (self ._compress (b'' , lib .BROTLI_OPERATION_FINISH ))
358+ finally :
359+ self .lock .release ()
348360 return b'' .join (chunks )
349361
350362
0 commit comments