|
50 | 50 | # define XXHASH_LOCK_INIT(o) ((o)->lock = NULL) |
51 | 51 | # define XXHASH_LOCK_IS_ACTIVE(o) ((o)->lock != NULL) |
52 | 52 | /* Lazy allocation on first large update */ |
53 | | -# define XXHASH_LOCK_MAYBE_INIT(o, len) \ |
| 53 | +# define XXHASH_LOCK_MAYBE_INIT(o, len) \ |
54 | 54 | do { \ |
55 | 55 | if ((o)->lock == NULL && (len) >= XXHASH_GIL_MINSIZE) { \ |
56 | 56 | (o)->lock = PyThread_allocate_lock(); \ |
|
62 | 62 | } while (0) |
63 | 63 | /* Acquire lock when GIL is already released — simple blocking acquire. |
64 | 64 | * Only acquires if lock has been allocated (lazy init). */ |
65 | | -# define XXHASH_LOCK_ACQUIRE_BLOCKING(o) \ |
| 65 | +# define XXHASH_LOCK_ACQUIRE_BLOCKING(o) \ |
66 | 66 | do { \ |
67 | 67 | if ((o)->lock) { \ |
68 | 68 | PyThread_acquire_lock((o)->lock, WAIT_LOCK); \ |
|
72 | 72 | /* Acquire lock with the GIL held — non-blocking try first, then release |
73 | 73 | * GIL and block if contested (matches hashlib's ENTER_HASHLIB in 3.9-3.12). |
74 | 74 | * Only acquires if lock has been allocated (lazy init). */ |
75 | | -# define XXHASH_LOCK_ACQUIRE(o) \ |
| 75 | +# define XXHASH_LOCK_ACQUIRE(o) \ |
76 | 76 | do { \ |
77 | 77 | if ((o)->lock) { \ |
78 | 78 | if (!PyThread_acquire_lock((o)->lock, NOWAIT_LOCK)) { \ |
|
84 | 84 | } \ |
85 | 85 | } while (0) |
86 | 86 |
|
87 | | -# define XXHASH_LOCK_RELEASE(o) \ |
| 87 | +# define XXHASH_LOCK_RELEASE(o) \ |
88 | 88 | do { \ |
89 | 89 | if ((o)->lock) { \ |
90 | 90 | PyThread_release_lock((o)->lock); \ |
91 | | - } \ |
| 91 | + } \ |
92 | 92 | } while (0) |
93 | 93 | # endif |
94 | 94 | #else /* !XXHASH_WITH_LOCK */ |
@@ -670,7 +670,7 @@ PY##type##_do_update(PY##type##Object *self, Py_buffer *buf) \ |
670 | 670 | XXHASH_LOCK_RELEASE(self); \ |
671 | 671 | } \ |
672 | 672 | } else { \ |
673 | | - /* No lock: release GIL for large data to avoid blocking other threads. */ \ |
| 673 | + /* No lock */ \ |
674 | 674 | if (buf->len > XXHASH_GIL_MINSIZE) { \ |
675 | 675 | Py_BEGIN_ALLOW_THREADS \ |
676 | 676 | update_fn(self->xxhash_state, buf->buf, buf->len); \ |
@@ -853,60 +853,60 @@ static int PY##type##_init(PY##type##Object *self, PyObject *args, \ |
853 | 853 |
|
854 | 854 | XXHASH_INIT(XXH32, XXH32_reset, XXH32_update, XXH32_hash_t) |
855 | 855 |
|
856 | | -#define XXHASH_UPDATE_METHOD(prefix, name) \ |
857 | | -PyDoc_STRVAR( \ |
858 | | - PY##prefix##_update_doc, \ |
859 | | - "update (data)\n\n" \ |
860 | | - "Update the " name " object with bytes-like data. Repeated calls are\n" \ |
861 | | - "equivalent to a single call with the concatenation of all the arguments."); \ |
862 | | - \ |
863 | | -static PyObject *PY##prefix##_update(PY##prefix##Object *self, \ |
864 | | - PyObject *const *args, \ |
865 | | - Py_ssize_t nargs, PyObject *kwnames) \ |
866 | | -{ \ |
867 | | - PyObject *arg = NULL; \ |
868 | | - \ |
869 | | - /* validate keywords first */ \ |
870 | | - if (kwnames) { \ |
871 | | - Py_ssize_t nkw = PyTuple_GET_SIZE(kwnames); \ |
872 | | - for (Py_ssize_t i = 0; i < nkw; i++) { \ |
873 | | - PyObject *key = PyTuple_GET_ITEM(kwnames, i); \ |
874 | | - if (PyUnicode_CompareWithASCIIString(key, "data") == 0) { \ |
875 | | - if (nargs >= 1) { \ |
876 | | - PyErr_SetString(PyExc_TypeError, \ |
877 | | - name ".update() got multiple values for argument 'data'"); \ |
878 | | - return NULL; \ |
879 | | - } \ |
880 | | - arg = args[nargs + i]; \ |
881 | | - } else { \ |
882 | | - PyErr_Format(PyExc_TypeError, \ |
883 | | - "'%U' is an invalid keyword argument for '" name ".update()'", \ |
884 | | - key); \ |
885 | | - return NULL; \ |
886 | | - } \ |
887 | | - } \ |
888 | | - } \ |
889 | | - \ |
890 | | - if (nargs >= 1) { \ |
891 | | - if (nargs > 1) { \ |
892 | | - PyErr_Format(PyExc_TypeError, \ |
| 856 | +#define XXHASH_UPDATE_METHOD(prefix, name) \ |
| 857 | +PyDoc_STRVAR( \ |
| 858 | + PY##prefix##_update_doc, \ |
| 859 | + "update (data)\n\n" \ |
| 860 | + "Update the " name " object with bytes-like data. Repeated calls are\n" \ |
| 861 | + "equivalent to a single call with the concatenation of all the arguments."); \ |
| 862 | + \ |
| 863 | +static PyObject *PY##prefix##_update(PY##prefix##Object *self, \ |
| 864 | + PyObject *const *args, \ |
| 865 | + Py_ssize_t nargs, PyObject *kwnames) \ |
| 866 | +{ \ |
| 867 | + PyObject *arg = NULL; \ |
| 868 | + \ |
| 869 | + /* validate keywords first */ \ |
| 870 | + if (kwnames) { \ |
| 871 | + Py_ssize_t nkw = PyTuple_GET_SIZE(kwnames); \ |
| 872 | + for (Py_ssize_t i = 0; i < nkw; i++) { \ |
| 873 | + PyObject *key = PyTuple_GET_ITEM(kwnames, i); \ |
| 874 | + if (PyUnicode_CompareWithASCIIString(key, "data") == 0) { \ |
| 875 | + if (nargs >= 1) { \ |
| 876 | + PyErr_SetString(PyExc_TypeError, \ |
| 877 | + name ".update() got multiple values for argument 'data'"); \ |
| 878 | + return NULL; \ |
| 879 | + } \ |
| 880 | + arg = args[nargs + i]; \ |
| 881 | + } else { \ |
| 882 | + PyErr_Format(PyExc_TypeError, \ |
| 883 | + "'%U' is an invalid keyword argument for '" name ".update()'", \ |
| 884 | + key); \ |
| 885 | + return NULL; \ |
| 886 | + } \ |
| 887 | + } \ |
| 888 | + } \ |
| 889 | + \ |
| 890 | + if (nargs >= 1) { \ |
| 891 | + if (nargs > 1) { \ |
| 892 | + PyErr_Format(PyExc_TypeError, \ |
893 | 893 | name ".update() takes at most 1 positional argument (%zd given)", nargs); \ |
894 | | - return NULL; \ |
895 | | - } \ |
896 | | - arg = args[0]; \ |
897 | | - } \ |
898 | | - \ |
899 | | - if (!arg) { \ |
900 | | - PyErr_SetString(PyExc_TypeError, \ |
901 | | - name ".update() missing required argument 'data'"); \ |
902 | | - return NULL; \ |
903 | | - } \ |
904 | | - \ |
905 | | - Py_buffer buf; \ |
906 | | - if (_get_buffer_or_str(arg, &buf) < 0) \ |
907 | | - return NULL; \ |
908 | | - PY##prefix##_do_update(self, &buf); \ |
909 | | - Py_RETURN_NONE; \ |
| 894 | + return NULL; \ |
| 895 | + } \ |
| 896 | + arg = args[0]; \ |
| 897 | + } \ |
| 898 | + \ |
| 899 | + if (!arg) { \ |
| 900 | + PyErr_SetString(PyExc_TypeError, \ |
| 901 | + name ".update() missing required argument 'data'"); \ |
| 902 | + return NULL; \ |
| 903 | + } \ |
| 904 | + \ |
| 905 | + Py_buffer buf; \ |
| 906 | + if (_get_buffer_or_str(arg, &buf) < 0) \ |
| 907 | + return NULL; \ |
| 908 | + PY##prefix##_do_update(self, &buf); \ |
| 909 | + Py_RETURN_NONE; \ |
910 | 910 | } |
911 | 911 |
|
912 | 912 | XXHASH_UPDATE_METHOD(XXH32, "xxh32") |
|
0 commit comments