Exemplo n.º 1
0
/* 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();
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 4
0
/* 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);
}
Exemplo n.º 5
0
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);
}
Exemplo n.º 6
0
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);
}