17db96d56Sopenharmony_ci/* Common code for use by all hashlib related modules. */ 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_ci/* 47db96d56Sopenharmony_ci * Given a PyObject* obj, fill in the Py_buffer* viewp with the result 57db96d56Sopenharmony_ci * of PyObject_GetBuffer. Sets an exception and issues the erraction 67db96d56Sopenharmony_ci * on any errors, e.g. 'return NULL' or 'goto error'. 77db96d56Sopenharmony_ci */ 87db96d56Sopenharmony_ci#define GET_BUFFER_VIEW_OR_ERROR(obj, viewp, erraction) do { \ 97db96d56Sopenharmony_ci if (PyUnicode_Check((obj))) { \ 107db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, \ 117db96d56Sopenharmony_ci "Strings must be encoded before hashing");\ 127db96d56Sopenharmony_ci erraction; \ 137db96d56Sopenharmony_ci } \ 147db96d56Sopenharmony_ci if (!PyObject_CheckBuffer((obj))) { \ 157db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, \ 167db96d56Sopenharmony_ci "object supporting the buffer API required"); \ 177db96d56Sopenharmony_ci erraction; \ 187db96d56Sopenharmony_ci } \ 197db96d56Sopenharmony_ci if (PyObject_GetBuffer((obj), (viewp), PyBUF_SIMPLE) == -1) { \ 207db96d56Sopenharmony_ci erraction; \ 217db96d56Sopenharmony_ci } \ 227db96d56Sopenharmony_ci if ((viewp)->ndim > 1) { \ 237db96d56Sopenharmony_ci PyErr_SetString(PyExc_BufferError, \ 247db96d56Sopenharmony_ci "Buffer must be single dimension"); \ 257db96d56Sopenharmony_ci PyBuffer_Release((viewp)); \ 267db96d56Sopenharmony_ci erraction; \ 277db96d56Sopenharmony_ci } \ 287db96d56Sopenharmony_ci } while(0) 297db96d56Sopenharmony_ci 307db96d56Sopenharmony_ci#define GET_BUFFER_VIEW_OR_ERROUT(obj, viewp) \ 317db96d56Sopenharmony_ci GET_BUFFER_VIEW_OR_ERROR(obj, viewp, return NULL) 327db96d56Sopenharmony_ci 337db96d56Sopenharmony_ci/* 347db96d56Sopenharmony_ci * Helper code to synchronize access to the hash object when the GIL is 357db96d56Sopenharmony_ci * released around a CPU consuming hashlib operation. All code paths that 367db96d56Sopenharmony_ci * access a mutable part of obj must be enclosed in an ENTER_HASHLIB / 377db96d56Sopenharmony_ci * LEAVE_HASHLIB block or explicitly acquire and release the lock inside 387db96d56Sopenharmony_ci * a PY_BEGIN / END_ALLOW_THREADS block if they wish to release the GIL for 397db96d56Sopenharmony_ci * an operation. 407db96d56Sopenharmony_ci */ 417db96d56Sopenharmony_ci 427db96d56Sopenharmony_ci#include "pythread.h" 437db96d56Sopenharmony_ci#define ENTER_HASHLIB(obj) \ 447db96d56Sopenharmony_ci if ((obj)->lock) { \ 457db96d56Sopenharmony_ci if (!PyThread_acquire_lock((obj)->lock, 0)) { \ 467db96d56Sopenharmony_ci Py_BEGIN_ALLOW_THREADS \ 477db96d56Sopenharmony_ci PyThread_acquire_lock((obj)->lock, 1); \ 487db96d56Sopenharmony_ci Py_END_ALLOW_THREADS \ 497db96d56Sopenharmony_ci } \ 507db96d56Sopenharmony_ci } 517db96d56Sopenharmony_ci#define LEAVE_HASHLIB(obj) \ 527db96d56Sopenharmony_ci if ((obj)->lock) { \ 537db96d56Sopenharmony_ci PyThread_release_lock((obj)->lock); \ 547db96d56Sopenharmony_ci } 557db96d56Sopenharmony_ci 567db96d56Sopenharmony_ci/* TODO(gps): We should probably make this a module or EVPobject attribute 577db96d56Sopenharmony_ci * to allow the user to optimize based on the platform they're using. */ 587db96d56Sopenharmony_ci#define HASHLIB_GIL_MINSIZE 2048 597db96d56Sopenharmony_ci 60