Oracle FAQ Your Portal to the Oracle Knowledge Grid
HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US
 

Home -> Community -> Mailing Lists -> Oracle-L -> Re:Race condition in Oracle C Interface?

Re:Race condition in Oracle C Interface?

From: <dgoulet_at_vicr.com>
Date: Mon, 20 Nov 2000 09:17:15 -0500
Message-Id: <10686.122489@fatcity.com>


Michael,

    Sorry, but I'm not a OCI person. I personally prefer Pro*C as it's much easier to maintain & read. To your point though, I've written many a Pro*C program that does exactly what your trying without any difficulty and they all behave very well. Is there a reason why your using OCI? I've found it to be a very good way to shoot oneself in the foot regularly over the years.

Dick Goulet

____________________Reply Separator____________________
Subject: Race condition in Oracle C Interface? Author: Michael Haggerty <mhagger_at_alum.mit.edu> Date: 11/19/00 3:00 PM

I am trying to use Oracle in a multithreaded application that creates and destroys multiple database connections. It seems to have tickled a bug in Oracle, though, because the application hangs up deep in Oracle. I simplified the application into the trivial C program appended below, which on my system locks up about half of the time. It just opens up two database connections and some associated structures and then closes them. I don't think there is a problem with code, but if you are sceptical just take a look; it is quite trivial.

Has anybody seen this problem? Does anyone know a workaround?

I am running Oracle 8.1.6.1 under Linux/Intel with kernel version 2.2.14. The program locks up within OCIServerDetach and has to be kill -6'ed or stronger. Only the client seems to lock up; the server seems unaffected.

Thanks,
Michael

--

Michael Haggerty
mhagger_at_alum.mit.edu

/* ==================== main.c ======================== */

/* compile with:

    gcc -I/ora8/m01/app/oracle/product/8.1.6/rdbms/demo

-I/ora8/m01/app/oracle/product/8.1.6/network/public
-I/ora8/m01/app/oracle/product/8.1.6/plsql/public
-I/ora8/m01/app/oracle/product/8.1.6/rdbms/public -DORACLE8i -g -o main
-L/ora8/m01/app/oracle/product/8.1.6/lib/ -lclntsh
-Wl,-rpath,/ora8/m01/app/oracle/product/8.1.6/lib ./main.c

*/

#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <oci.h>


typedef struct {
        OCIEnv          *envhp;                 /* Environment handle   */
        OCIError        *errhp;                 /* Error handle         */
        OCIServer       *srvhp;                 /* Server handle        */
        OCISession      *usrhp;                 /* User handle          */
        OCISvcCtx       *svchp;                 /* Service Context      */
} ServerContext;

ServerContext *Connect(char *user, char *password, char *database) {

        ServerContext *sc;
        int     userlen;
        int     passwordlen;
        int     databaselen;
        sword   status;
        sword   credentials = OCI_CRED_RDBMS;

        userlen = strlen(user);
        passwordlen = strlen(password);
        databaselen = strlen(database);

        sc = (ServerContext *)malloc(sizeof(ServerContext));

        sc->envhp = NULL;
        sc->errhp = NULL;
        sc->svchp = NULL;
        sc->srvhp = NULL;
        sc->usrhp = NULL;

        status = OCIEnvCreate(&sc->envhp, OCI_THREADED, NULL, NULL, NULL, NULL,
                              0, NULL);
        assert(status == OCI_SUCCESS);

        /* Allocate the error handle */
        status = OCIHandleAlloc(sc->envhp, (dvoid **)&sc->errhp,
                                OCI_HTYPE_ERROR, 0, NULL);
        assert(status == OCI_SUCCESS);

        /* Allocate the server handle */
        status = OCIHandleAlloc(sc->envhp, (dvoid **) &sc->srvhp,
                                OCI_HTYPE_SERVER, 0, NULL);
        assert(status == OCI_SUCCESS);

        /* Connect to database */
        status = OCIServerAttach(sc->srvhp, sc->errhp, database, databaselen,
                                 OCI_DEFAULT);
        assert(status == OCI_SUCCESS);

        /* Allocate a service context */
        status = OCIHandleAlloc(sc->envhp, (dvoid **) &sc->svchp,
                                OCI_HTYPE_SVCCTX, 0, NULL);
        assert(status == OCI_SUCCESS);

        /* Attach the server to the service context */
        status = OCIAttrSet(sc->svchp, OCI_HTYPE_SVCCTX, (dvoid *) sc->srvhp,
                            (ub4) 0, OCI_ATTR_SERVER, sc->errhp);
        assert(status == OCI_SUCCESS);

        /* Allocate a session */
        status = OCIHandleAlloc(sc->envhp, (dvoid **) &sc->usrhp,
                                OCI_HTYPE_SESSION, 0, NULL);
        assert(status == OCI_SUCCESS);

        /* Were credentials provided? if so, set them in the session */
        status = OCIAttrSet(sc->usrhp, OCI_HTYPE_SESSION,
                            (dvoid *) user, (ub4) userlen,
                            OCI_ATTR_USERNAME, sc->errhp);
        assert(status == OCI_SUCCESS);

        status = OCIAttrSet(sc->usrhp, OCI_HTYPE_SESSION,
                            (dvoid *) password, (ub4) passwordlen,
                            OCI_ATTR_PASSWORD, sc->errhp);
        assert(status == OCI_SUCCESS);
        
        /* Now begin the session */
        status = OCISessionBegin(sc->svchp, sc->errhp, sc->usrhp,
                                 credentials, OCI_DEFAULT);
        assert(status == OCI_SUCCESS);

        /* Now attach the session to the service context */
        status = OCIAttrSet(sc->svchp, OCI_HTYPE_SVCCTX,
                            sc->usrhp, 0, OCI_ATTR_SESSION, sc->errhp);
        assert(status == OCI_SUCCESS);

        return sc;

}
/*
** ServerContext_dealloc
**
** Called when a server context goes out of scope; hang up the connection
** to the database!

*/

void ServerContext_dealloc(ServerContext *self) {

        sword status;

        /* End the session */
        assert(self->svchp);
        status = OCISessionEnd(self->svchp, self->errhp, self->usrhp,
                               OCI_DEFAULT);
        assert(status == OCI_SUCCESS);

        /* Disconnect from the server */
        assert(self->srvhp);
        status = OCIServerDetach(self->srvhp, self->errhp, OCI_DEFAULT);
        assert(status == OCI_SUCCESS);

        /* Deallocate the session handle */
        assert(self->usrhp);
        status = OCIHandleFree(self->usrhp, OCI_HTYPE_SESSION);
        assert(status == OCI_SUCCESS);

        /* Deallocate the server handle */
        assert(self->srvhp);
        status = OCIHandleFree(self->srvhp, OCI_HTYPE_SERVER);
        assert(status == OCI_SUCCESS);

        /* Deallocate the service context handle */
        assert(self->svchp);
        status = OCIHandleFree(self->svchp, OCI_HTYPE_SVCCTX);
        assert(status == OCI_SUCCESS);

        /* Deallocate the error handle */
        assert(self->errhp);
        status = OCIHandleFree(self->errhp, OCI_HTYPE_ERROR);
        assert(status == OCI_SUCCESS);

        /* Deallocate the environment handle */
        assert(self->envhp);
        status = OCIHandleFree(self->envhp, OCI_HTYPE_ENV);
        assert(status == OCI_SUCCESS);

        free(self);

}

int main(int argc, char *argv[]) {

    char *user;
    char *password;
    char *database;

    ServerContext *db1;
    ServerContext *db2;
    assert(argc == 4);
    user = argv[1];
    password = argv[2];
    database = argv[3];
    db1 = Connect(user, password, database);     db2 = Connect(user, password, database);     fprintf(stderr, "Deleting db2.\n");
    ServerContext_dealloc(db2);
    fprintf(stderr, "Deleting db1.\n");
    ServerContext_dealloc(db1);
    fprintf(stderr, "This line often not reached.\n");     return 0;
}

--

Please see the official ORACLE-L FAQ: http://www.orafaq.com
--

Author: Michael Haggerty
  INET: mhagger_at_alum.mit.edu

Fat City Network Services    -- (858) 538-5051  FAX: (858) 538-5051
San Diego, California        -- Public Internet access / Mailing Lists

--------------------------------------------------------------------
To REMOVE yourself from this mailing list, send an E-Mail message
to: ListGuru_at_fatcity.com (note EXACT spelling of 'ListGuru') and in Received on Mon Nov 20 2000 - 08:17:15 CST

Original text of this message

HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US