1 /* Common code for use by all hashlib related modules. */ 2 3 #include "pycore_lock.h" // PyMutex 4 5 /* 6 * Given a PyObject* obj, fill in the Py_buffer* viewp with the result 7 * of PyObject_GetBuffer. Sets an exception and issues the erraction 8 * on any errors, e.g. 'return NULL' or 'goto error'. 9 */ 10 #define GET_BUFFER_VIEW_OR_ERROR(obj, viewp, erraction) do { \ 11 if (PyUnicode_Check((obj))) { \ 12 PyErr_SetString(PyExc_TypeError, \ 13 "Strings must be encoded before hashing");\ 14 erraction; \ 15 } \ 16 if (!PyObject_CheckBuffer((obj))) { \ 17 PyErr_SetString(PyExc_TypeError, \ 18 "object supporting the buffer API required"); \ 19 erraction; \ 20 } \ 21 if (PyObject_GetBuffer((obj), (viewp), PyBUF_SIMPLE) == -1) { \ 22 erraction; \ 23 } \ 24 if ((viewp)->ndim > 1) { \ 25 PyErr_SetString(PyExc_BufferError, \ 26 "Buffer must be single dimension"); \ 27 PyBuffer_Release((viewp)); \ 28 erraction; \ 29 } \ 30 } while(0) 31 32 #define GET_BUFFER_VIEW_OR_ERROUT(obj, viewp) \ 33 GET_BUFFER_VIEW_OR_ERROR(obj, viewp, return NULL) 34 35 /* 36 * Helper code to synchronize access to the hash object when the GIL is 37 * released around a CPU consuming hashlib operation. All code paths that 38 * access a mutable part of obj must be enclosed in an ENTER_HASHLIB / 39 * LEAVE_HASHLIB block or explicitly acquire and release the lock inside 40 * a PY_BEGIN / END_ALLOW_THREADS block if they wish to release the GIL for 41 * an operation. 42 * 43 * These only drop the GIL if the lock acquisition itself is likely to 44 * block. Thus the non-blocking acquire gating the GIL release for a 45 * blocking lock acquisition. The intent of these macros is to surround 46 * the assumed always "fast" operations that you aren't releasing the 47 * GIL around. Otherwise use code similar to what you see in hash 48 * function update() methods. 49 */ 50 51 #include "pythread.h" 52 #define ENTER_HASHLIB(obj) \ 53 if ((obj)->use_mutex) { \ 54 PyMutex_Lock(&(obj)->mutex); \ 55 } 56 #define LEAVE_HASHLIB(obj) \ 57 if ((obj)->use_mutex) { \ 58 PyMutex_Unlock(&(obj)->mutex); \ 59 } 60 61 #ifdef Py_GIL_DISABLED 62 #define HASHLIB_INIT_MUTEX(obj) \ 63 do { \ 64 (obj)->mutex = (PyMutex){0}; \ 65 (obj)->use_mutex = true; \ 66 } while (0) 67 #else 68 #define HASHLIB_INIT_MUTEX(obj) \ 69 do { \ 70 (obj)->mutex = (PyMutex){0}; \ 71 (obj)->use_mutex = false; \ 72 } while (0) 73 #endif 74 75 /* TODO(gpshead): We should make this a module or class attribute 76 * to allow the user to optimize based on the platform they're using. */ 77 #define HASHLIB_GIL_MINSIZE 2048 78 79