diff -r e488bff4ed0e Modules/audioop.c --- a/Modules/audioop.c Wed Aug 15 17:10:43 2012 +0200 +++ b/Modules/audioop.c Thu Aug 16 10:19:29 2012 +0200 @@ -293,15 +293,42 @@ #define SHORTP(cp, i) ((short *)(cp+i)) #define LONGP(cp, i) ((Py_Int32 *)(cp+i)) +typedef struct { + PyObject *AudioopError; +} audioopstate; +#define audioop_state(o) ((audioopstate *)PyModule_GetState(o)) -static PyObject *AudioopError; +static int +audioop_clear(PyObject *m) +{ + Py_CLEAR(audioop_state(m)->AudioopError); + return 0; +} + +static int +audioop_traverse(PyObject *m, visitproc visit, void *arg) +{ + Py_VISIT(audioop_state(m)->AudioopError); + return 0; +} + +static void +audioop_free(void *m) +{ + audioop_clear((PyObject *)m); +} + +static PyModuleDef audioopmodule; + +#define audioopstate_global ((audioopstate *)PyModule_GetState(PyState_FindModule(&audioopmodule))) + static int audioop_check_size(int size) { if (size != 1 && size != 2 && size != 4) { - PyErr_SetString(AudioopError, "Size should be 1, 2 or 4"); + PyErr_SetString(audioopstate_global->AudioopError, "Size should be 1, 2 or 4"); return 0; } else @@ -314,7 +341,7 @@ if (!audioop_check_size(size)) return 0; if (len % size != 0) { - PyErr_SetString(AudioopError, "not a whole number of frames"); + PyErr_SetString(audioopstate_global->AudioopError, "not a whole number of frames"); return 0; } return 1; @@ -332,7 +359,7 @@ if (!audioop_check_parameters(len, size)) return NULL; if ( i < 0 || i >= len/size ) { - PyErr_SetString(AudioopError, "Index out of range"); + PyErr_SetString(audioopstate_global->AudioopError, "Index out of range"); return 0; } if ( size == 1 ) val = (int)*CHARP(cp, i); @@ -495,14 +522,14 @@ (char**)&cp1, &len1, (char**)&cp2, &len2) ) return 0; if ( len1 & 1 || len2 & 1 ) { - PyErr_SetString(AudioopError, "Strings should be even-sized"); + PyErr_SetString(audioopstate_global->AudioopError, "Strings should be even-sized"); return 0; } len1 >>= 1; len2 >>= 1; if ( len1 < len2 ) { - PyErr_SetString(AudioopError, "First sample should be longer"); + PyErr_SetString(audioopstate_global->AudioopError, "First sample should be longer"); return 0; } sum_ri_2 = _sum2(cp2, cp2, len2); @@ -551,11 +578,11 @@ (char**)&cp1, &len1, (char**)&cp2, &len2) ) return 0; if ( len1 & 1 || len2 & 1 ) { - PyErr_SetString(AudioopError, "Strings should be even-sized"); + PyErr_SetString(audioopstate_global->AudioopError, "Strings should be even-sized"); return 0; } if ( len1 != len2 ) { - PyErr_SetString(AudioopError, "Samples should be same size"); + PyErr_SetString(audioopstate_global->AudioopError, "Samples should be same size"); return 0; } len2 >>= 1; @@ -584,13 +611,13 @@ (char**)&cp1, &len1, &len2) ) return 0; if ( len1 & 1 ) { - PyErr_SetString(AudioopError, "Strings should be even-sized"); + PyErr_SetString(audioopstate_global->AudioopError, "Strings should be even-sized"); return 0; } len1 >>= 1; if ( len2 < 0 || len1 < len2 ) { - PyErr_SetString(AudioopError, "Input sample should be longer"); + PyErr_SetString(audioopstate_global->AudioopError, "Input sample should be longer"); return 0; } @@ -765,7 +792,7 @@ else if ( size == 2 ) maxval = (double) 0x7fff; else if ( size == 4 ) maxval = (double) 0x7fffffff; else { - PyErr_SetString(AudioopError, "Size should be 1, 2 or 4"); + PyErr_SetString(audioopstate_global->AudioopError, "Size should be 1, 2 or 4"); return 0; } @@ -810,7 +837,7 @@ return NULL; } if (((len / size) & 1) != 0) { - PyErr_SetString(AudioopError, "not a whole number of frames"); + PyErr_SetString(audioopstate_global->AudioopError, "not a whole number of frames"); PyBuffer_Release(&pcp); return NULL; } @@ -820,7 +847,7 @@ else if ( size == 4 ) maxval = (double) 0x7fffffff; else { PyBuffer_Release(&pcp); - PyErr_SetString(AudioopError, "Size should be 1, 2 or 4"); + PyErr_SetString(audioopstate_global->AudioopError, "Size should be 1, 2 or 4"); return 0; } @@ -870,7 +897,7 @@ else if ( size == 2 ) maxval = (double) 0x7fff; else if ( size == 4 ) maxval = (double) 0x7fffffff; else { - PyErr_SetString(AudioopError, "Size should be 1, 2 or 4"); + PyErr_SetString(audioopstate_global->AudioopError, "Size should be 1, 2 or 4"); return 0; } @@ -926,7 +953,7 @@ if (!audioop_check_parameters(len1, size)) return NULL; if ( len1 != len2 ) { - PyErr_SetString(AudioopError, "Lengths should be the same"); + PyErr_SetString(audioopstate_global->AudioopError, "Lengths should be the same"); return 0; } @@ -934,7 +961,7 @@ else if ( size == 2 ) maxval = 0x7fff; else if ( size == 4 ) maxval = 0x7fffffff; else { - PyErr_SetString(AudioopError, "Size should be 1, 2 or 4"); + PyErr_SetString(audioopstate_global->AudioopError, "Size should be 1, 2 or 4"); return 0; } @@ -1105,7 +1132,7 @@ if (!audioop_check_size(size)) return NULL; if (nchannels < 1) { - PyErr_SetString(AudioopError, "# of channels should be >= 1"); + PyErr_SetString(audioopstate_global->AudioopError, "# of channels should be >= 1"); return NULL; } bytes_per_frame = size * nchannels; @@ -1118,16 +1145,16 @@ return NULL; } if (weightA < 1 || weightB < 0) { - PyErr_SetString(AudioopError, + PyErr_SetString(audioopstate_global->AudioopError, "weightA should be >= 1, weightB should be >= 0"); return NULL; } if (len % bytes_per_frame != 0) { - PyErr_SetString(AudioopError, "not a whole number of frames"); + PyErr_SetString(audioopstate_global->AudioopError, "not a whole number of frames"); return NULL; } if (inrate <= 0 || outrate <= 0) { - PyErr_SetString(AudioopError, "sampling rate not > 0"); + PyErr_SetString(audioopstate_global->AudioopError, "sampling rate not > 0"); return NULL; } /* divide inrate and outrate by their greatest common divisor */ @@ -1160,7 +1187,7 @@ &d, &PyTuple_Type, &samps)) goto exit; if (PyTuple_Size(samps) != nchannels) { - PyErr_SetString(AudioopError, + PyErr_SetString(audioopstate_global->AudioopError, "illegal state argument"); goto exit; } @@ -1637,12 +1664,12 @@ PyModuleDef_HEAD_INIT, "audioop", NULL, - -1, + sizeof(audioopstate), audioop_methods, NULL, - NULL, - NULL, - NULL + audioop_traverse, + audioop_clear, + audioop_free }; PyMODINIT_FUNC @@ -1655,8 +1682,8 @@ d = PyModule_GetDict(m); if (d == NULL) return NULL; - AudioopError = PyErr_NewException("audioop.error", NULL, NULL); - if (AudioopError != NULL) - PyDict_SetItemString(d,"error",AudioopError); + audioop_state(m)->AudioopError = PyErr_NewException("audioop.error", NULL, NULL); + if (audioop_state(m)->AudioopError != NULL) + PyDict_SetItemString(d,"error", audioop_state(m)->AudioopError); return m; }