@@ -165,12 +165,11 @@ _get_CDict(ZstdDict *self, int compressionLevel)
165165 }
166166
167167 /* Get PyCapsule object from self->c_dicts */
168- int result = PyDict_GetItemRef (self -> c_dicts , level , & capsule );
169- if (result < 0 ) {
170- goto error ;
171- }
172-
168+ capsule = PyDict_GetItemWithError (self -> c_dicts , level );
173169 if (capsule == NULL ) {
170+ if (PyErr_Occurred ()) {
171+ goto error ;
172+ }
174173 /* Create ZSTD_CDict instance */
175174 char * dict_buffer = PyBytes_AS_STRING (self -> dict_content );
176175 Py_ssize_t dict_len = Py_SIZE (self -> dict_content );
@@ -198,18 +197,15 @@ _get_CDict(ZstdDict *self, int compressionLevel)
198197 }
199198
200199 /* Add PyCapsule object to self->c_dicts if not already inserted */
201- PyObject * capsule_value ;
202- int result = PyDict_SetDefaultRef (self -> c_dicts , level , capsule ,
203- & capsule_value );
204- if (result < 0 ) {
200+ if (PyDict_SetItem (self -> c_dicts , level , capsule ) < 0 ) {
201+ Py_DECREF (capsule );
205202 goto error ;
206203 }
207- Py_XDECREF ( capsule_value );
204+ Py_DECREF ( capsule );
208205 }
209206 else {
210207 /* ZSTD_CDict instance already exists */
211208 cdict = PyCapsule_GetPointer (capsule , NULL );
212- Py_DECREF (capsule );
213209 }
214210 goto success ;
215211
@@ -221,10 +217,50 @@ _get_CDict(ZstdDict *self, int compressionLevel)
221217}
222218
223219static int
224- _zstd_load_c_dict (ZstdCompressor * self , PyObject * dict )
220+ _zstd_load_impl (ZstdCompressor * self , ZstdDict * zd ,
221+ _zstd_state * mod_state , int type )
225222{
226-
227223 size_t zstd_ret ;
224+ if (type == DICT_TYPE_DIGESTED ) {
225+ /* Get ZSTD_CDict */
226+ ZSTD_CDict * c_dict = _get_CDict (zd , self -> compression_level );
227+ if (c_dict == NULL ) {
228+ return -1 ;
229+ }
230+ /* Reference a prepared dictionary.
231+ It overrides some compression context's parameters. */
232+ zstd_ret = ZSTD_CCtx_refCDict (self -> cctx , c_dict );
233+ }
234+ else if (type == DICT_TYPE_UNDIGESTED ) {
235+ /* Load a dictionary.
236+ It doesn't override compression context's parameters. */
237+ zstd_ret = ZSTD_CCtx_loadDictionary (
238+ self -> cctx ,
239+ PyBytes_AS_STRING (zd -> dict_content ),
240+ Py_SIZE (zd -> dict_content ));
241+ }
242+ else if (type == DICT_TYPE_PREFIX ) {
243+ /* Load a prefix */
244+ zstd_ret = ZSTD_CCtx_refPrefix (
245+ self -> cctx ,
246+ PyBytes_AS_STRING (zd -> dict_content ),
247+ Py_SIZE (zd -> dict_content ));
248+ }
249+ else {
250+ Py_UNREACHABLE ();
251+ }
252+
253+ /* Check error */
254+ if (ZSTD_isError (zstd_ret )) {
255+ set_zstd_error (mod_state , ERR_LOAD_C_DICT , zstd_ret );
256+ return -1 ;
257+ }
258+ return 0 ;
259+ }
260+
261+ static int
262+ _zstd_load_c_dict (ZstdCompressor * self , PyObject * dict )
263+ {
228264 _zstd_state * const mod_state = PyType_GetModuleState (Py_TYPE (self ));
229265 if (mod_state == NULL ) {
230266 return -1 ;
@@ -241,7 +277,10 @@ _zstd_load_c_dict(ZstdCompressor *self, PyObject *dict)
241277 /* When compressing, use undigested dictionary by default. */
242278 zd = (ZstdDict * )dict ;
243279 type = DICT_TYPE_UNDIGESTED ;
244- goto load ;
280+ PyMutex_Lock (& zd -> lock );
281+ ret = _zstd_load_impl (self , zd , mod_state , type );
282+ PyMutex_Unlock (& zd -> lock );
283+ return ret ;
245284 }
246285
247286 /* Check (ZstdDict, type) */
@@ -261,7 +300,10 @@ _zstd_load_c_dict(ZstdCompressor *self, PyObject *dict)
261300 {
262301 assert (type >= 0 );
263302 zd = (ZstdDict * )PyTuple_GET_ITEM (dict , 0 );
264- goto load ;
303+ PyMutex_Lock (& zd -> lock );
304+ ret = _zstd_load_impl (self , zd , mod_state , type );
305+ PyMutex_Unlock (& zd -> lock );
306+ return ret ;
265307 }
266308 }
267309 }
@@ -270,43 +312,6 @@ _zstd_load_c_dict(ZstdCompressor *self, PyObject *dict)
270312 PyErr_SetString (PyExc_TypeError ,
271313 "zstd_dict argument should be ZstdDict object." );
272314 return -1 ;
273-
274- load :
275- if (type == DICT_TYPE_DIGESTED ) {
276- /* Get ZSTD_CDict */
277- ZSTD_CDict * c_dict = _get_CDict (zd , self -> compression_level );
278- if (c_dict == NULL ) {
279- return -1 ;
280- }
281- /* Reference a prepared dictionary.
282- It overrides some compression context's parameters. */
283- zstd_ret = ZSTD_CCtx_refCDict (self -> cctx , c_dict );
284- }
285- else if (type == DICT_TYPE_UNDIGESTED ) {
286- /* Load a dictionary.
287- It doesn't override compression context's parameters. */
288- zstd_ret = ZSTD_CCtx_loadDictionary (
289- self -> cctx ,
290- PyBytes_AS_STRING (zd -> dict_content ),
291- Py_SIZE (zd -> dict_content ));
292- }
293- else if (type == DICT_TYPE_PREFIX ) {
294- /* Load a prefix */
295- zstd_ret = ZSTD_CCtx_refPrefix (
296- self -> cctx ,
297- PyBytes_AS_STRING (zd -> dict_content ),
298- Py_SIZE (zd -> dict_content ));
299- }
300- else {
301- Py_UNREACHABLE ();
302- }
303-
304- /* Check error */
305- if (ZSTD_isError (zstd_ret )) {
306- set_zstd_error (mod_state , ERR_LOAD_C_DICT , zstd_ret );
307- return -1 ;
308- }
309- return 0 ;
310315}
311316
312317/*[clinic input]
0 commit comments