| 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
-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*/
#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
![]() |
![]() |