1 /* Common code for use by all hashlib related modules. */ 2 3 /* 4 * Given a PyObject* obj, fill in the Py_buffer* viewp with the result 5 * of PyObject_GetBuffer. Sets an exception and issues the erraction 6 * on any errors, e.g. 'return NULL' or 'goto error'. 7 */ 8 #define GET_BUFFER_VIEW_OR_ERROR(obj, viewp, erraction) do { \ 9 if (PyUnicode_Check((obj))) { \ 10 PyErr_SetString(PyExc_TypeError, \ 11 "Unicode-objects must be encoded before hashing");\ 12 erraction; \ 13 } \ 14 if (!PyObject_CheckBuffer((obj))) { \ 15 PyErr_SetString(PyExc_TypeError, \ 16 "object supporting the buffer API required"); \ 17 erraction; \ 18 } \ 19 if (PyObject_GetBuffer((obj), (viewp), PyBUF_SIMPLE) == -1) { \ 20 erraction; \ 21 } \ 22 if ((viewp)->ndim > 1) { \ 23 PyErr_SetString(PyExc_BufferError, \ 24 "Buffer must be single dimension"); \ 25 PyBuffer_Release((viewp)); \ 26 erraction; \ 27 } \ 28 } while(0) 29 30 #define GET_BUFFER_VIEW_OR_ERROUT(obj, viewp) \ 31 GET_BUFFER_VIEW_OR_ERROR(obj, viewp, return NULL) 32 33 /* 34 * Helper code to synchronize access to the hash object when the GIL is 35 * released around a CPU consuming hashlib operation. All code paths that 36 * access a mutable part of obj must be enclosed in an ENTER_HASHLIB / 37 * LEAVE_HASHLIB block or explicitly acquire and release the lock inside 38 * a PY_BEGIN / END_ALLOW_THREADS block if they wish to release the GIL for 39 * an operation. 40 */ 41 42 #include "pythread.h" 43 #define ENTER_HASHLIB(obj) \ 44 if ((obj)->lock) { \ 45 if (!PyThread_acquire_lock((obj)->lock, 0)) { \ 46 Py_BEGIN_ALLOW_THREADS \ 47 PyThread_acquire_lock((obj)->lock, 1); \ 48 Py_END_ALLOW_THREADS \ 49 } \ 50 } 51 #define LEAVE_HASHLIB(obj) \ 52 if ((obj)->lock) { \ 53 PyThread_release_lock((obj)->lock); \ 54 } 55 56 /* TODO(gps): We should probably make this a module or EVPobject attribute 57 * to allow the user to optimize based on the platform they're using. */ 58 #define HASHLIB_GIL_MINSIZE 2048 59 60