hashlib.h 2.5 KB

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