~psycopg/psycopg/2.0.x

« back to all changes in this revision

Viewing changes to psycopg/pqpath.c

  • Committer: Federico Di Gregorio
  • Date: 2004-12-10 10:34:57 UTC
  • Revision ID: fog-1b2e9ebeaa5d76bd7e4a9dc5eb779afb4076f236
async fixes and better connection/cursor management.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
20
 */
21
21
 
 
22
/* IMPORTANT NOTE: no function in this file do its own connection locking
 
23
   except for pg_execute and pq_fetch (that are somehow high-level. This means
 
24
   that all the othe functions should be called while holding a lock to the
 
25
   connection.
 
26
*/
 
27
 
22
28
#include <Python.h>
23
29
#include <string.h>
24
30
 
33
39
#include "psycopg/pgtypes.h"
34
40
#include "psycopg/pgversion.h"
35
41
 
36
 
/* pq_raise - raise a python exception of the right kind */
 
42
/* pq_raise - raise a python exception of the right kind
 
43
 
 
44
   This function should be called while holding the GIL. */
37
45
 
38
46
void
39
47
pq_raise(connectionObject *conn, cursorObject *curs, PyObject *exc, char *msg)
106
114
   critical condition like out of memory or lost connection. it save the error
107
115
   message and mark the connection as 'wanting cleanup'.
108
116
 
109
 
   both functions do not call any Py_*_ALLOW_THREADS macros. */
 
117
   both functions do not call any Py_*_ALLOW_THREADS macros.
 
118
   pq_resolve_critical should be called while holding the GIL. */
110
119
 
111
120
void
112
121
pq_set_critical(connectionObject *conn, const char *msg)
140
149
   note that this function does block because it needs to wait for the full
141
150
   result sets of the previous query to clear them.
142
151
 
 
152
   
143
153
   this function does not call any Py_*_ALLOW_THREADS macros */
144
154
 
145
155
void
149
159
 
150
160
    do {
151
161
        pgres = PQgetResult(conn->pgconn);
 
162
        Dprintf("pq_clear_async: clearing PGresult at %p", pgres);
152
163
        IFCLEARPGRES(pgres);
153
164
    } while (pgres != NULL);
154
165
}
291
302
 
292
303
   a status of 1 means that a call to pq_fetch will block, while a status of 0
293
304
   means that there is data available to be collected. -1 means an error, the
294
 
   exception will be set accordingly. */
 
305
   exception will be set accordingly.
 
306
 
 
307
   this fucntion locks the connection object
 
308
   this function call Py_*_ALLOW_THREADS macros */
295
309
 
296
310
int
297
311
pq_is_busy(connectionObject *conn)
299
313
    PGnotify *pgn;
300
314
    
301
315
    Dprintf("pq_is_busy: consuming input");
 
316
 
 
317
    Py_BEGIN_ALLOW_THREADS;
 
318
    pthread_mutex_lock(&(conn->lock));
 
319
 
302
320
    if (PQconsumeInput(conn->pgconn) == 0) {
303
321
        Dprintf("pq_is_busy: PQconsumeInput() failed");
304
322
        PyErr_SetString(OperationalError, PQerrorMessage(conn->pgconn));
 
323
        pthread_mutex_unlock(&(conn->lock));
 
324
        Py_BLOCK_THREADS;
305
325
        return -1;
306
326
    }
307
327
 
315
335
        notify = PyTuple_New(2);
316
336
        PyTuple_SET_ITEM(notify, 0, PyInt_FromLong((long)pgn->be_pid));
317
337
        PyTuple_SET_ITEM(notify, 1, PyString_FromString(pgn->relname));
318
 
        pthread_mutex_lock(&(conn->lock));
319
338
        PyList_Append(conn->notifies, notify);
320
 
        pthread_mutex_unlock(&(conn->lock));
321
339
        free(pgn);
322
340
    }
 
341
 
 
342
    pthread_mutex_unlock(&(conn->lock));
 
343
    Py_END_ALLOW_THREADS;
323
344
    
324
345
    return PQisBusy(conn->pgconn);
325
346
}
656
677
        
657
678
        Dprintf("pq_fetch: no data: entering polling loop");
658
679
        
659
 
        Py_BEGIN_ALLOW_THREADS;
660
 
        pthread_mutex_lock(&(curs->conn->lock));
661
 
        
662
680
        while (pq_is_busy(curs->conn) > 0) {
663
681
            fd_set rfds;
664
682
            struct timeval tv;
665
683
            int sval, sock;
666
684
 
 
685
            Py_BEGIN_ALLOW_THREADS;
 
686
            pthread_mutex_lock(&(curs->conn->lock));
 
687
 
667
688
            sock = PQsocket(curs->conn->pgconn);
668
689
            FD_ZERO(&rfds);
669
690
            FD_SET(sock, &rfds);
677
698
            Dprintf("pq_fetch: entering PDflush() loop");
678
699
            while (PQflush(curs->conn->pgconn) != 0);
679
700
            sval = select(sock+1, &rfds, NULL, NULL, &tv);
 
701
 
 
702
            pthread_mutex_unlock(&(curs->conn->lock));
 
703
            Py_END_ALLOW_THREADS;
680
704
        }
681
705
 
682
706
        Dprintf("pq_fetch: data is probably ready");
683
707
        IFCLEARPGRES(curs->pgres);
684
708
        curs->pgres = PQgetResult(curs->conn->pgconn);
685
 
 
686
 
        pthread_mutex_unlock(&(curs->conn->lock));
687
 
        Py_END_ALLOW_THREADS;
688
709
    }
689
710
 
690
711
    /* check for PGRES_FATAL_ERROR result */