Results 1 to 6 of 6
  1. #1
    Join Date
    Jun 2009
    Posts
    7

    Unanswered: libpq multiple PGresults problem

    I'm writing an application that is driven mostly asynchronous with libev:

    It's a socket server handling clients and it's listening on notifications.
    For this I have two database connections con1 and con2 with con2 being asynchronous handling only the notifications.
    I have declared PGresult *res; and use it pretty much everywhere with con1.

    The problem arises when I receive a notification, I then run a query to see what's new or what's changed and use the results to send them to the socket clients.
    This callback function, for the notification, has a local PGresult *res2; which I use (on con1) for this.
    It then calls functions, in other files, to deliver these updates to the clients. These functions need information from the DB as well, using the global PGresult *res also on con1.

    When I do PQclear(res) in the called function, the program terminates, no errors, no stacktrace, just stops. Removing that PQclear will allow returning the program to the callback function, where it then stops in the same way.
    (The callback function is in a for loop using res2 at this point)

    I have no idea why the program stops, any help would be appreciated.
    Is it possible to define two seperate PGresults on one connection?

  2. #2
    Join Date
    Sep 2009
    Location
    Bangalore, India
    Posts
    6
    What do you mean by program terminates? Is it a segmentation fault? If so can you post gdb stack trace here?
    As far as I know, on a single connection you can execute multiple statements but the result will reflect only the last executed statement. Maybe you can execute one statement copy the result to a local structure and then execute another one and use the local structure to access the previous result. PQclear frees the result structure and further accesses to that structure will ofcourse result in segmentation fault.

    Hope it helps!

    Samarth

  3. #3
    Join Date
    Jun 2009
    Posts
    7
    Code:
    res = PQexec(conn_block,query);
    for(i=0;i<PQntuples(res);i++)
    {
        temp = send_data(atoi(PQgetvalue(res,i,0)), message, messagesize);
        if(temp != -1)
        {	operatorssent += temp;}
        else
        {	log(DEBUG,("%s: send_data returned -1",__func__));}
    }
    
    log(DEBUG,("%s: free(message)",__func__));
    free(message);	
    log(DEBUG,("%s: PQclear(res)",__func__));
    PQclear(res);
    log(DEBUG,("%s: free(query)",__func__));
    free(query);
    log(DEBUG,("%s: Returning %d",__func__,operatorssent));
    return operatorssent; // success.
    What I mean is that the logfile just ends with "PQclear(res)", nothing more.
    No stacktrace, no memeory dump no segfault nothing that reveals anything.
    But the process just doesn't exist anymore. (according to 'ps aux')


    Meanwhile I have added, and removed #include <libpq-fe.h> in that file, and now I do get an error:
    2009-09-09 13:11:47 function: PQclear(res)
    *** glibc detected *** ./program: corrupted double-linked list: 0x092b09c8 ***
    ======= Backtrace: =========
    /lib/libc.so.6[0x63b9aa]
    /lib/libc.so.6(cfree+0x90)[0x63f0f0]
    /usr/lib/libpq.so.5(PQclear+0x49)[0xae1759]
    ./program[0x80507fb]
    ./program[0x804f5d8]
    /usr/local/lib/libev.so.3(ev_loop+0x939)[0x117f89]
    ./program[0x8049a4a]
    /lib/libc.so.6(__libc_start_main+0xe0)[0x5e8390]
    ./program[0x8049311]

    P.S.: No problems in other functions in same file.

  4. #4
    Join Date
    Sep 2009
    Location
    Bangalore, India
    Posts
    6
    Are you sure there is no seg fault? Are you running it as a background process?
    In any case, as I mentioned in my earlier post, you can try copying the result into a temporary structure and then using it later.

  5. #5
    Join Date
    Jun 2009
    Posts
    7
    The problem is solved!

    samarth: I'm sure there was no segfault, it is a background process.
    The problem lay elsewhere where I forgot to allocated memory for a pointer

    The interesting thing I found out is that it should be no problem to do something as follows:

    Code:
    PGresult *res1;
    PGresult *res2;
    
    res1 = PQexec(connection, somequery);
    for(i=0;i<PQntuples(res1);i++)
    {
        res2 = PQexec(connection,someotherquery);
        // do stuff with res2
        PQclear(res2);
    }
    
    PQclear(res1);
    (just don't use only 1 res because that would obviously cause troubles)

  6. #6
    Join Date
    Sep 2009
    Location
    Bangalore, India
    Posts
    6
    Not sure, but I think it may cause problems if you use result res1 inside the for loop.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •