/* Expose the notices received as Python objects. * * The function should be called with the connection lock and the GIL. */ void conn_notice_process(connectionObject *self) { struct connectionObject_notice *notice; PyObject *msg = NULL; PyObject *tmp = NULL; static PyObject *append; if (NULL == self->notice_pending) { return; } if (!append) { if (!(append = Text_FromUTF8("append"))) { goto error; } } notice = self->notice_pending; while (notice != NULL) { Dprintf("conn_notice_process: %s", notice->message); if (!(msg = conn_text_from_chars(self, notice->message))) { goto error; } if (!(tmp = PyObject_CallMethodObjArgs( self->notice_list, append, msg, NULL))) { goto error; } Py_DECREF(tmp); tmp = NULL; Py_DECREF(msg); msg = NULL; notice = notice->next; } /* Remove the oldest item if the queue is getting too long. */ if (PyList_Check(self->notice_list)) { Py_ssize_t nnotices; nnotices = PyList_GET_SIZE(self->notice_list); if (nnotices > CONN_NOTICES_LIMIT) { if (-1 == PySequence_DelSlice(self->notice_list, 0, nnotices - CONN_NOTICES_LIMIT)) { PyErr_Clear(); } } } conn_notice_clean(self); return; error: Py_XDECREF(tmp); Py_XDECREF(msg); conn_notice_clean(self); /* TODO: the caller doesn't expects errors from us */ PyErr_Clear(); }
static void connection_dealloc(PyObject* obj) { connectionObject *self = (connectionObject *)obj; /* Make sure to untrack the connection before calling conn_close, which may * allow a different thread to try and dealloc the connection again, * resulting in a double-free segfault (ticket #166). */ PyObject_GC_UnTrack(self); conn_close(self); if (self->weakreflist) { PyObject_ClearWeakRefs(obj); } conn_notice_clean(self); PyMem_Free(self->dsn); PyMem_Free(self->encoding); if (self->critical) free(self->critical); if (self->cancel) PQfreeCancel(self->cancel); connection_clear(self); pthread_mutex_destroy(&(self->lock)); Dprintf("connection_dealloc: deleted connection object at %p, refcnt = " FORMAT_CODE_PY_SSIZE_T, obj, Py_REFCNT(obj) ); Py_TYPE(obj)->tp_free(obj); }
static void connection_dealloc(PyObject* obj) { connectionObject *self = (connectionObject *)obj; PyObject_GC_UnTrack(self); if (self->closed == 0) conn_close(self); conn_notice_clean(self); if (self->dsn) free(self->dsn); if (self->encoding) free(self->encoding); if (self->critical) free(self->critical); Py_CLEAR(self->async_cursor); Py_CLEAR(self->notice_list); Py_CLEAR(self->notice_filter); Py_CLEAR(self->notifies); Py_CLEAR(self->string_types); Py_CLEAR(self->binary_types); pthread_mutex_destroy(&(self->lock)); Dprintf("connection_dealloc: deleted connection object at %p, refcnt = " FORMAT_CODE_PY_SSIZE_T, obj, obj->ob_refcnt ); obj->ob_type->tp_free(obj); }
/* Expose the notices received as Python objects. * * The function should be called with the connection lock and the GIL. */ void conn_notice_process(connectionObject *self) { struct connectionObject_notice *notice; Py_ssize_t nnotices; if (NULL == self->notice_pending) { return; } notice = self->notice_pending; nnotices = PyList_GET_SIZE(self->notice_list); while (notice != NULL) { PyObject *msg; msg = conn_text_from_chars(self, notice->message); Dprintf("conn_notice_process: %s", notice->message); /* Respect the order in which notices were produced, because in notice_list they are reversed (see ticket #9) */ if (msg) { PyList_Insert(self->notice_list, nnotices, msg); Py_DECREF(msg); } else { /* We don't really have a way to report errors, so gulp it. * The function should only fail for out of memory, so we are * likely going to die anyway. */ PyErr_Clear(); } notice = notice->next; } /* Remove the oldest item if the queue is getting too long. */ nnotices = PyList_GET_SIZE(self->notice_list); if (nnotices > CONN_NOTICES_LIMIT) { PySequence_DelSlice(self->notice_list, 0, nnotices - CONN_NOTICES_LIMIT); } conn_notice_clean(self); }
static void connection_dealloc(PyObject* obj) { connectionObject *self = (connectionObject *)obj; /* Make sure to untrack the connection before calling conn_close, which may * allow a different thread to try and dealloc the connection again, * resulting in a double-free segfault (ticket #166). */ PyObject_GC_UnTrack(self); /* close the connection only if this is the same process it was created * into, otherwise using multiprocessing we may close the connection * belonging to another process. */ #ifdef CONN_CHECK_PID if (self->procpid == getpid()) #endif { conn_close(self); } if (self->weakreflist) { PyObject_ClearWeakRefs(obj); } conn_notice_clean(self); PyMem_Free(self->dsn); PyMem_Free(self->encoding); if (self->error) free(self->error); if (self->cancel) PQfreeCancel(self->cancel); PQclear(self->pgres); connection_clear(self); pthread_mutex_destroy(&(self->lock)); Dprintf("connection_dealloc: deleted connection object at %p, refcnt = " FORMAT_CODE_PY_SSIZE_T, obj, Py_REFCNT(obj) ); Py_TYPE(obj)->tp_free(obj); }
static void connection_dealloc(PyObject* obj) { connectionObject *self = (connectionObject *)obj; if (self->weakreflist) { PyObject_ClearWeakRefs(obj); } PyObject_GC_UnTrack(self); if (self->closed == 0) conn_close(self); conn_notice_clean(self); if (self->dsn) free(self->dsn); PyMem_Free(self->encoding); PyMem_Free(self->codec); if (self->critical) free(self->critical); Py_CLEAR(self->tpc_xid); Py_CLEAR(self->async_cursor); Py_CLEAR(self->notice_list); Py_CLEAR(self->notice_filter); Py_CLEAR(self->notifies); Py_CLEAR(self->string_types); Py_CLEAR(self->binary_types); pthread_mutex_destroy(&(self->lock)); Dprintf("connection_dealloc: deleted connection object at %p, refcnt = " FORMAT_CODE_PY_SSIZE_T, obj, Py_REFCNT(obj) ); Py_TYPE(obj)->tp_free(obj); }