bpo-1635741: Port audioop extension module to multiphase initializati… · python/cpython@41fbf86
@@ -375,15 +375,22 @@ static PyModuleDef audioopmodule;
375375376376typedef struct {
377377PyObject *AudioopError;
378-} _audioopstate;
378+} audioop_state;
379379380-#define _audioopstate(o) ((_audioopstate *)PyModule_GetState(o))
380+static inline audioop_state *
381+get_audioop_state(PyObject *module)
382+{
383+void *state = PyModule_GetState(module);
384+assert(state != NULL);
385+return (audioop_state *)state;
386+}
381387382388static int
383389audioop_check_size(PyObject *module, int size)
384390{
385391if (size < 1 || size > 4) {
386-PyErr_SetString(_audioopstate(module)->AudioopError, "Size should be 1, 2, 3 or 4");
392+PyErr_SetString(get_audioop_state(module)->AudioopError,
393+"Size should be 1, 2, 3 or 4");
387394return 0;
388395 }
389396else
@@ -396,7 +403,8 @@ audioop_check_parameters(PyObject *module, Py_ssize_t len, int size)
396403if (!audioop_check_size(module, size))
397404return 0;
398405if (len % size != 0) {
399-PyErr_SetString(_audioopstate(module)->AudioopError, "not a whole number of frames");
406+PyErr_SetString(get_audioop_state(module)->AudioopError,
407+"not a whole number of frames");
400408return 0;
401409 }
402410return 1;
@@ -428,7 +436,8 @@ audioop_getsample_impl(PyObject *module, Py_buffer *fragment, int width,
428436if (!audioop_check_parameters(module, fragment->len, width))
429437return NULL;
430438if (index < 0 || index >= fragment->len/width) {
431-PyErr_SetString(_audioopstate(module)->AudioopError, "Index out of range");
439+PyErr_SetString(get_audioop_state(module)->AudioopError,
440+"Index out of range");
432441return NULL;
433442 }
434443val = GETRAWSAMPLE(width, fragment->buf, index*width);
@@ -619,7 +628,8 @@ audioop_findfit_impl(PyObject *module, Py_buffer *fragment,
619628double sum_ri_2, sum_aij_2, sum_aij_ri, result, best_result, factor;
620629621630if (fragment->len & 1 || reference->len & 1) {
622-PyErr_SetString(_audioopstate(module)->AudioopError, "Strings should be even-sized");
631+PyErr_SetString(get_audioop_state(module)->AudioopError,
632+"Strings should be even-sized");
623633return NULL;
624634 }
625635cp1 = (const int16_t *)fragment->buf;
@@ -628,7 +638,8 @@ audioop_findfit_impl(PyObject *module, Py_buffer *fragment,
628638len2 = reference->len >> 1;
629639630640if (len1 < len2) {
631-PyErr_SetString(_audioopstate(module)->AudioopError, "First sample should be longer");
641+PyErr_SetString(get_audioop_state(module)->AudioopError,
642+"First sample should be longer");
632643return NULL;
633644 }
634645sum_ri_2 = _sum2(cp2, cp2, len2);
@@ -686,11 +697,13 @@ audioop_findfactor_impl(PyObject *module, Py_buffer *fragment,
686697double sum_ri_2, sum_aij_ri, result;
687698688699if (fragment->len & 1 || reference->len & 1) {
689-PyErr_SetString(_audioopstate(module)->AudioopError, "Strings should be even-sized");
700+PyErr_SetString(get_audioop_state(module)->AudioopError,
701+"Strings should be even-sized");
690702return NULL;
691703 }
692704if (fragment->len != reference->len) {
693-PyErr_SetString(_audioopstate(module)->AudioopError, "Samples should be same size");
705+PyErr_SetString(get_audioop_state(module)->AudioopError,
706+"Samples should be same size");
694707return NULL;
695708 }
696709cp1 = (const int16_t *)fragment->buf;
@@ -730,14 +743,16 @@ audioop_findmax_impl(PyObject *module, Py_buffer *fragment,
730743double result, best_result;
731744732745if (fragment->len & 1) {
733-PyErr_SetString(_audioopstate(module)->AudioopError, "Strings should be even-sized");
746+PyErr_SetString(get_audioop_state(module)->AudioopError,
747+"Strings should be even-sized");
734748return NULL;
735749 }
736750cp1 = (const int16_t *)fragment->buf;
737751len1 = fragment->len >> 1;
738752739753if (length < 0 || len1 < length) {
740-PyErr_SetString(_audioopstate(module)->AudioopError, "Input sample should be longer");
754+PyErr_SetString(get_audioop_state(module)->AudioopError,
755+"Input sample should be longer");
741756return NULL;
742757 }
743758@@ -969,7 +984,8 @@ audioop_tomono_impl(PyObject *module, Py_buffer *fragment, int width,
969984if (!audioop_check_parameters(module, len, width))
970985return NULL;
971986if (((len / width) & 1) != 0) {
972-PyErr_SetString(_audioopstate(module)->AudioopError, "not a whole number of frames");
987+PyErr_SetString(get_audioop_state(module)->AudioopError,
988+"not a whole number of frames");
973989return NULL;
974990 }
975991@@ -1064,7 +1080,8 @@ audioop_add_impl(PyObject *module, Py_buffer *fragment1,
10641080if (!audioop_check_parameters(module, fragment1->len, width))
10651081return NULL;
10661082if (fragment1->len != fragment2->len) {
1067-PyErr_SetString(_audioopstate(module)->AudioopError, "Lengths should be the same");
1083+PyErr_SetString(get_audioop_state(module)->AudioopError,
1084+"Lengths should be the same");
10681085return NULL;
10691086 }
10701087@@ -1310,7 +1327,8 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width,
13101327if (!audioop_check_size(module, width))
13111328return NULL;
13121329if (nchannels < 1) {
1313-PyErr_SetString(_audioopstate(module)->AudioopError, "# of channels should be >= 1");
1330+PyErr_SetString(get_audioop_state(module)->AudioopError,
1331+"# of channels should be >= 1");
13141332return NULL;
13151333 }
13161334if (width > INT_MAX / nchannels) {
@@ -1323,17 +1341,19 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width,
13231341 }
13241342bytes_per_frame = width * nchannels;
13251343if (weightA < 1 || weightB < 0) {
1326-PyErr_SetString(_audioopstate(module)->AudioopError,
1344+PyErr_SetString(get_audioop_state(module)->AudioopError,
13271345"weightA should be >= 1, weightB should be >= 0");
13281346return NULL;
13291347 }
13301348assert(fragment->len >= 0);
13311349if (fragment->len % bytes_per_frame != 0) {
1332-PyErr_SetString(_audioopstate(module)->AudioopError, "not a whole number of frames");
1350+PyErr_SetString(get_audioop_state(module)->AudioopError,
1351+"not a whole number of frames");
13331352return NULL;
13341353 }
13351354if (inrate <= 0 || outrate <= 0) {
1336-PyErr_SetString(_audioopstate(module)->AudioopError, "sampling rate not > 0");
1355+PyErr_SetString(get_audioop_state(module)->AudioopError,
1356+"sampling rate not > 0");
13371357return NULL;
13381358 }
13391359/* divide inrate and outrate by their greatest common divisor */
@@ -1374,7 +1394,7 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width,
13741394&d, &PyTuple_Type, &samps))
13751395 goto exit;
13761396if (PyTuple_Size(samps) != nchannels) {
1377-PyErr_SetString(_audioopstate(module)->AudioopError,
1397+PyErr_SetString(get_audioop_state(module)->AudioopError,
13781398"illegal state argument");
13791399 goto exit;
13801400 }
@@ -1903,31 +1923,61 @@ static PyMethodDef audioop_methods[] = {
19031923};
1904192419051925static int
1906-audioop_traverse(PyObject *m, visitproc visit, void *arg) {
1907-_audioopstate *state = _audioopstate(m);
1908-if (state != NULL)
1926+audioop_traverse(PyObject *module, visitproc visit, void *arg)
1927+{
1928+audioop_state *state = (audioop_state *)PyModule_GetState(module);
1929+if (state) {
19091930Py_VISIT(state->AudioopError);
1931+ }
19101932return 0;
19111933}
1934+19121935static int
1913-audioop_clear(PyObject *m) {
1914-_audioopstate *state = _audioopstate(m);
1915-if (state != NULL)
1936+audioop_clear(PyObject *module)
1937+{
1938+audioop_state *state = (audioop_state *)PyModule_GetState(module);
1939+if (state) {
19161940Py_CLEAR(state->AudioopError);
1941+ }
19171942return 0;
19181943}
1944+19191945static void
1920-audioop_free(void *m) {
1921-audioop_clear((PyObject *)m);
1946+audioop_free(void *module) {
1947+audioop_clear((PyObject *)module);
19221948}
192319491950+static int
1951+audioop_exec(PyObject* module)
1952+{
1953+audioop_state *state = get_audioop_state(module);
1954+1955+state->AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1956+if (state->AudioopError == NULL) {
1957+return -1;
1958+ }
1959+1960+Py_INCREF(state->AudioopError);
1961+if (PyModule_AddObject(module, "error", state->AudioopError) < 0) {
1962+Py_DECREF(state->AudioopError);
1963+return -1;
1964+ }
1965+1966+return 0;
1967+}
1968+1969+static PyModuleDef_Slot audioop_slots[] = {
1970+ {Py_mod_exec, audioop_exec},
1971+ {0, NULL}
1972+};
1973+19241974static struct PyModuleDef audioopmodule = {
19251975PyModuleDef_HEAD_INIT,
19261976"audioop",
19271977NULL,
1928-sizeof(_audioopstate),
1978+sizeof(audioop_state),
19291979audioop_methods,
1930-NULL,
1980+audioop_slots,
19311981audioop_traverse,
19321982audioop_clear,
19331983audioop_free
@@ -1936,14 +1986,5 @@ static struct PyModuleDef audioopmodule = {
19361986PyMODINIT_FUNC
19371987PyInit_audioop(void)
19381988{
1939-PyObject *m = PyModule_Create(&audioopmodule);
1940-if (m == NULL)
1941-return NULL;
1942-PyObject *AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
1943-if (AudioopError == NULL)
1944-return NULL;
1945-Py_INCREF(AudioopError);
1946-PyModule_AddObject(m, "error", AudioopError);
1947-_audioopstate(m)->AudioopError = AudioopError;
1948-return m;
1989+return PyModuleDef_Init(&audioopmodule);
19491990}