Oracle FAQ | Your Portal to the Oracle Knowledge Grid |
![]() |
![]() |
Home -> Community -> Mailing Lists -> Oracle-L -> Re:Race condition in Oracle C Interface?
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-L/ora8/m01/app/oracle/product/8.1.6/lib/ -lclntsh
-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
*/
#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;
--
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 Liststo: ListGuru_at_fatcity.com (note EXACT spelling of 'ListGuru') and in Received on Mon Nov 20 2000 - 08:17:15 CST
--------------------------------------------------------------------
To REMOVE yourself from this mailing list, send an E-Mail message
![]() |
![]() |