diff options
Diffstat (limited to 'psycopg/psycopgmodule.c')
| -rw-r--r-- | psycopg/psycopgmodule.c | 64 |
1 files changed, 56 insertions, 8 deletions
diff --git a/psycopg/psycopgmodule.c b/psycopg/psycopgmodule.c index ee4bc8e..53fd641 100644 --- a/psycopg/psycopgmodule.c +++ b/psycopg/psycopgmodule.c @@ -62,7 +62,6 @@ PyObject *pyPsycopgTzLOCAL = NULL; PyObject *pyPsycopgTzFixedOffsetTimezone = NULL; PyObject *psycoEncodings = NULL; -PyObject *decimalType = NULL; /** connect module-level function **/ #define psyco_connect_doc \ @@ -330,7 +329,8 @@ psyco_adapters_init(PyObject *mod) #endif #ifdef HAVE_DECIMAL - microprotocols_add((PyTypeObject*)decimalType, NULL, (PyObject*)&asisType); + microprotocols_add((PyTypeObject*)psyco_GetDecimalType(), + NULL, (PyObject*)&asisType); #endif } @@ -554,14 +554,55 @@ psyco_set_error(PyObject *exc, PyObject *curs, char *msg, } } -/* psyco_decimal_init - Initialize the module's pointer to the decimal type. */ +/* Return nonzero if the current one is the main interpreter */ +static int +psyco_is_main_interp() +{ + static PyInterpreterState *main_interp = NULL; /* Cached reference */ + PyInterpreterState *interp; -void -psyco_decimal_init(void) + if (main_interp) { + return (main_interp == PyThreadState_Get()->interp); + } + + /* No cached value: cache the proper value and try again. */ + interp = PyInterpreterState_Head(); + while (interp->next) + interp = interp->next; + + main_interp = interp; + assert (main_interp); + return psyco_is_main_interp(); +} + + +/* psyco_GetDecimalType + + Return a new reference to the adapter for decimal type. + + If decimals should be used but the module import fails, fall back on + the float type. + + If decimals are not to be used, return NULL. + */ + +PyObject * +psyco_GetDecimalType(void) { + PyObject *decimalType = NULL; + static PyObject *cachedType = NULL; + #ifdef HAVE_DECIMAL + + /* Use the cached object if running from the main interpreter. */ + int can_cache = psyco_is_main_interp(); + if (can_cache && cachedType) { + Py_INCREF(cachedType); + return cachedType; + } + + /* Get a new reference to the Decimal type. */ PyObject *decimal = PyImport_ImportModule("decimal"); if (decimal) { decimalType = PyObject_GetAttrString(decimal, "Decimal"); @@ -572,7 +613,15 @@ psyco_decimal_init(void) decimalType = (PyObject *)&PyFloat_Type; Py_INCREF(decimalType); } -#endif + + /* Store the object from future uses. */ + if (can_cache && !cachedType) { + cachedType = decimalType; + } + +#endif /* HAVE_DECIMAL */ + + return decimalType; } @@ -731,7 +780,6 @@ init_psycopg(void) /* other mixed initializations of module-level variables */ psycoEncodings = PyDict_New(); psyco_encodings_fill(psycoEncodings); - psyco_decimal_init(); /* set some module's parameters */ PyModule_AddStringConstant(module, "__version__", PSYCOPG_VERSION); |
