• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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