Oracle FAQ | Your Portal to the Oracle Knowledge Grid |
![]() |
![]() |
Home -> Community -> Mailing Lists -> Oracle-L -> RE: Race condition in Oracle C Interface?
This message is in MIME format. Since your mail reader does not understand
this format, some or all of this message may not be legible.
------_=_NextPart_001_01C05306.6ED15320
Content-Type: text/plain;
charset="iso-8859-1"
The client locks up you believe?
It would be interesting to run
it under Un*x, just to see if the
same thing happens.
Could be an NT threading thing, there
are some performance issues with older
versions of NT and small thread scheduling...
just a thought
-----Original Message-----
From: Michael Haggerty [mailto:mhagger_at_alum.mit.edu]
Sent: Sunday, November 19, 2000 6:00 PM
To: Multiple recipients of list ORACLE-L
Subject: Race condition in Oracle C Interface?
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 the message BODY, include a line containing: UNSUB ORACLE-L (or the name of mailing list you want to be removed from). You may also send the HELP command for other information (like subscribing).
--------------------------------------------------------------------
To REMOVE yourself from this mailing list, send an E-Mail message
------_=_NextPart_001_01C05306.6ED15320
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> <HTML> <HEAD> <META HTTP-EQUIV=3D"Content-Type" CONTENT=3D"text/html; =charset=3Diso-8859-1">
<TITLE>RE: Race condition in Oracle C Interface?</TITLE> </HEAD> <BODY>
<P><FONT SIZE=3D2>The client locks up you believe?</FONT> </P>
<P><FONT SIZE=3D2>It would be interesting to run</FONT> <BR><FONT SIZE=3D2>it under Un*x, just to see if the</FONT> <BR><FONT SIZE=3D2>same thing happens. </FONT> </P> <P><FONT SIZE=3D2>Could be an NT threading thing, there</FONT> <BR><FONT SIZE=3D2>are some performance issues with older</FONT><BR><FONT SIZE=3D2>versions of NT and small thread scheduling...</FONT> </P>
<P><FONT SIZE=3D2>just a thought</FONT>
</P>
<P><FONT SIZE=3D2>- Ross Mohan</FONT>
</P>
<P><FONT SIZE=3D2>-----Original Message-----</FONT> <BR><FONT SIZE=3D2>From: Michael Haggerty [<A = HREF=3D"mailto:mhagger_at_alum.mit.edu">mailto:mhagger_at_alum.mit.edu</A>]</F=
ONT> <BR><FONT SIZE=3D2>Sent: Sunday, November 19, 2000 6:00 PM</FONT> <BR><FONT SIZE=3D2>To: Multiple recipients of list ORACLE-L</FONT> <BR><FONT SIZE=3D2>Subject: Race condition in Oracle C =Interface?</FONT>
<P><FONT SIZE=3D2>I am trying to use Oracle in a multithreaded =
application that creates</FONT>
<BR><FONT SIZE=3D2>and destroys multiple database connections. It =
seems to have tickled</FONT>
<BR><FONT SIZE=3D2>a bug in Oracle, though, because the application =
hangs up deep in</FONT>
<BR><FONT SIZE=3D2>Oracle. I simplified the application into the =
trivial C program</FONT>
<BR><FONT SIZE=3D2>appended below, which on my system locks up about =
half of the time.</FONT>
<BR><FONT SIZE=3D2>It just opens up two database connections and some =
associated</FONT>
<BR><FONT SIZE=3D2>structures and then closes them. I don't think =
there is a problem</FONT>
<BR><FONT SIZE=3D2>with code, but if you are sceptical just take a =
look; it is quite</FONT>
<BR><FONT SIZE=3D2>trivial.</FONT>
</P>
<P><FONT SIZE=3D2>Has anybody seen this problem? Does anyone know =
a workaround?</FONT>
</P>
<P><FONT SIZE=3D2>I am running Oracle 8.1.6.1 under Linux/Intel with =
kernel version</FONT>
<BR><FONT SIZE=3D2>2.2.14. The program locks up within =
OCIServerDetach and has to be</FONT>
<BR><FONT SIZE=3D2>kill -6'ed or stronger. Only the client seems =
to lock up; the server</FONT>
<BR><FONT SIZE=3D2>seems unaffected.</FONT>
</P>
<P><FONT SIZE=3D2>Thanks,</FONT> <BR><FONT SIZE=3D2>Michael</FONT> </P> <P><FONT SIZE=3D2>--</FONT> <BR><FONT SIZE=3D2>Michael Haggerty</FONT><BR><FONT SIZE=3D2>mhagger_at_alum.mit.edu</FONT> </P>
<P><FONT SIZE=3D2>/* = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D main.c = =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=*/</FONT>
<P><FONT SIZE=3D2>/* compile with:</FONT> </P>
<P><FONT SIZE=3D2> 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</FONT></P>
<P><FONT SIZE=3D2>*/</FONT>
</P>
<P><FONT SIZE=3D2>#include <assert.h></FONT> <BR><FONT SIZE=3D2>#include <stdio.h></FONT> <BR><FONT SIZE=3D2>#include <string.h></FONT> <BR><FONT SIZE=3D2>#include <malloc.h></FONT> <BR><FONT SIZE=3D2>#include <oci.h></FONT> </P> <BR>
<P><FONT SIZE=3D2>typedef struct {</FONT>
<BR> <FONT =
SIZE=3D2>OCIEnv =
*envhp; =
/* Environment handle =
*/</FONT>
<BR> <FONT =
SIZE=3D2>OCIError *errhp; =
= /* Error handle = */</FONT><BR> <FONT =
SIZE=3D2>OCIServer *srvhp; = = /* Server = handle */</FONT><BR> <FONT = SIZE=3D2>OCISession *usrhp; =
= /* User handle = */</FONT><BR> <FONT =
SIZE=3D2>OCISvcCtx *svchp; = = /* Service =Context */</FONT>
<BR><FONT SIZE=3D2>} ServerContext;</FONT> </P> <BR>
<P><FONT SIZE=3D2>ServerContext *Connect(char *user, char *password, =
char *database) {</FONT>
<BR> <FONT =
SIZE=3D2>ServerContext *sc;</FONT>
<BR> <FONT =
SIZE=3D2>int userlen;</FONT>
<BR> <FONT =
SIZE=3D2>int passwordlen;</FONT>
<BR> <FONT =
SIZE=3D2>int databaselen;</FONT>
<BR> <FONT = SIZE=3D2>sword status;</FONT> <BR> <FONT =SIZE=3D2>sword credentials =3D OCI_CRED_RDBMS;</FONT> </P>
<P><FONT SIZE=3D2> userlen =
=3D strlen(user);</FONT>
<BR><FONT SIZE=3D2> =
passwordlen =3D strlen(password);</FONT>
<BR><FONT SIZE=3D2> =
databaselen =3D strlen(database);</FONT>
</P>
<P><FONT SIZE=3D2> sc =3D = (ServerContext *)malloc(sizeof(ServerContext));</FONT> </P>
<P> <FONT =
SIZE=3D2>sc->envhp =3D NULL;</FONT> <BR> <FONT = SIZE=3D2>sc->errhp =3D NULL;</FONT> <BR> <FONT = SIZE=3D2>sc->svchp =3D NULL;</FONT> <BR> <FONT = SIZE=3D2>sc->srvhp =3D NULL;</FONT> <BR> <FONT = SIZE=3D2>sc->usrhp =3D NULL;</FONT>
<P> <FONT SIZE=3D2>status =3D =
OCIEnvCreate(&sc->envhp, OCI_THREADED, NULL, NULL, NULL, =
NULL,</FONT>
<BR><FONT =
SIZE=3D2> &nb= sp; &nb= sp; 0, NULL);</FONT><BR> <FONT = SIZE=3D2>assert(status =3D=3D OCI_SUCCESS);</FONT> </P>
<P> <FONT SIZE=3D2>/* =
Allocate the error handle */</FONT>
<BR> <FONT SIZE=3D2>status =
=3D OCIHandleAlloc(sc->envhp, (dvoid **)&sc->errhp,</FONT>
<BR><FONT =
SIZE=3D2> &nb= sp; &nb= sp; OCI_HTYPE_ERROR, 0, =NULL);</FONT>
<P> <FONT SIZE=3D2>/* =
Allocate the server handle */</FONT>
<BR> <FONT SIZE=3D2>status =
=3D OCIHandleAlloc(sc->envhp, (dvoid **) &sc->srvhp,</FONT>
<BR><FONT =
SIZE=3D2> &nb= sp; &nb= sp; OCI_HTYPE_SERVER, =0, NULL);</FONT>
<P> <FONT SIZE=3D2>/* Connect =
to database */</FONT>
<BR> <FONT SIZE=3D2>status =
=3D OCIServerAttach(sc->srvhp, sc->errhp, database, =
databaselen,</FONT>
<BR><FONT =
SIZE=3D2> &nb= sp; &nb= sp; =OCI_DEFAULT);</FONT>
<P> <FONT SIZE=3D2>/* =
Allocate a service context */</FONT>
<BR> <FONT SIZE=3D2>status =
=3D OCIHandleAlloc(sc->envhp, (dvoid **) &sc->svchp,</FONT>
<BR><FONT =
SIZE=3D2> &nb= sp; &nb= sp; OCI_HTYPE_SVCCTX, =0, NULL);</FONT>
<P> <FONT SIZE=3D2>/* Attach =
the server to the service context */</FONT>
<BR> <FONT SIZE=3D2>status =
=3D OCIAttrSet(sc->svchp, OCI_HTYPE_SVCCTX, (dvoid *) =
sc->srvhp,</FONT>
<BR><FONT =
SIZE=3D2> &nb= sp; &nb= sp; (ub4) 0, OCI_ATTR_SERVER, =sc->errhp);</FONT>
<P> <FONT SIZE=3D2>/* =
Allocate a session */</FONT>
<BR> <FONT SIZE=3D2>status =
=3D OCIHandleAlloc(sc->envhp, (dvoid **) &sc->usrhp,</FONT>
<BR><FONT =
SIZE=3D2> &nb= sp; &nb= sp; OCI_HTYPE_SESSION, =0, NULL);</FONT>
<P> <FONT SIZE=3D2>/* Were = credentials provided? if so, set them in the session */</FONT> <BR><FONT SIZE=3D2> status = =3D OCIAttrSet(sc->usrhp, OCI_HTYPE_SESSION,</FONT> <BR><FONT =
SIZE=3D2> &nb= sp; &nb= sp; (dvoid *) user, (ub4) userlen,</FONT><BR><FONT =
SIZE=3D2> &nb= sp; &nb= sp; OCI_ATTR_USERNAME, sc->errhp);</FONT><BR><FONT SIZE=3D2> = assert(status =3D=3D OCI_SUCCESS);</FONT> </P>
<P><FONT SIZE=3D2> status =3D = OCIAttrSet(sc->usrhp, OCI_HTYPE_SESSION,</FONT> <BR><FONT =
SIZE=3D2> &nb= sp; &nb= sp; (dvoid *) password, (ub4) =passwordlen,</FONT>
SIZE=3D2> &nb= sp; &nb= sp; OCI_ATTR_PASSWORD, sc->errhp);</FONT><BR><FONT SIZE=3D2> =
assert(status =3D=3D OCI_SUCCESS);</FONT> <BR> =20 <BR> <FONT SIZE=3D2>/* Now =begin the session */</FONT>
SIZE=3D2> &nb= sp; &nb= sp; credentials, =OCI_DEFAULT);</FONT>
<P> <FONT SIZE=3D2>/* Now = attach the session to the service context */</FONT> <BR> <FONT SIZE=3D2>status = =3D OCIAttrSet(sc->svchp, OCI_HTYPE_SVCCTX,</FONT> <BR><FONT =
SIZE=3D2> &nb= sp; &nb= sp; sc->usrhp, 0, OCI_ATTR_SESSION, =sc->errhp);</FONT>
<P> <FONT SIZE=3D2>return =
sc;</FONT>
<BR><FONT SIZE=3D2>}</FONT>
</P>
<P><FONT SIZE=3D2>/*</FONT> <BR><FONT SIZE=3D2>** ServerContext_dealloc</FONT> <BR><FONT SIZE=3D2>**</FONT> <BR><FONT SIZE=3D2>** Called when a server context goes out of scope; =hang up the connection</FONT>
<BR><FONT SIZE=3D2>** to the database!</FONT> <BR><FONT SIZE=3D2>*/</FONT> </P>
<P><FONT SIZE=3D2>void ServerContext_dealloc(ServerContext *self) =
{</FONT>
<BR> <FONT SIZE=3D2>sword =
status;</FONT>
</P>
<P> <FONT SIZE=3D2>/* End the =
session */</FONT>
<BR> <FONT =
SIZE=3D2>assert(self->svchp);</FONT>
<BR><FONT SIZE=3D2> status =
=3D OCISessionEnd(self->svchp, self->errhp, =
self->usrhp,</FONT>
<BR><FONT =
SIZE=3D2> &nb= sp; &nb= sp; OCI_DEFAULT);</FONT><BR><FONT SIZE=3D2> = assert(status =3D=3D OCI_SUCCESS);</FONT> </P>
<P> <FONT SIZE=3D2>/* =
Disconnect from the server */</FONT>
<BR> <FONT =
SIZE=3D2>assert(self->srvhp);</FONT>
<BR><FONT SIZE=3D2> status =
=3D OCIServerDetach(self->srvhp, self->errhp, =
OCI_DEFAULT);</FONT>
<BR><FONT SIZE=3D2> =
assert(status =3D=3D OCI_SUCCESS);</FONT>
</P>
<P> <FONT SIZE=3D2>/* =
Deallocate the session handle */</FONT>
<BR><FONT SIZE=3D2> =
assert(self->usrhp);</FONT>
<BR><FONT SIZE=3D2> status =
=3D OCIHandleFree(self->usrhp, OCI_HTYPE_SESSION);</FONT>
<BR><FONT SIZE=3D2> =
assert(status =3D=3D OCI_SUCCESS);</FONT>
</P>
<P> <FONT SIZE=3D2>/* =
Deallocate the server handle */</FONT>
<BR><FONT SIZE=3D2> =
assert(self->srvhp);</FONT>
<BR><FONT SIZE=3D2> status =
=3D OCIHandleFree(self->srvhp, OCI_HTYPE_SERVER);</FONT>
<BR><FONT SIZE=3D2> =
assert(status =3D=3D OCI_SUCCESS);</FONT>
</P>
<P> <FONT SIZE=3D2>/* =
Deallocate the service context handle */</FONT>
<BR> <FONT =
SIZE=3D2>assert(self->svchp);</FONT>
<BR><FONT SIZE=3D2> status =
=3D OCIHandleFree(self->svchp, OCI_HTYPE_SVCCTX);</FONT>
<BR><FONT SIZE=3D2> =
assert(status =3D=3D OCI_SUCCESS);</FONT>
</P>
<P> <FONT SIZE=3D2>/* =
Deallocate the error handle */</FONT>
<BR><FONT SIZE=3D2> =
assert(self->errhp);</FONT>
<BR><FONT SIZE=3D2> status =
=3D OCIHandleFree(self->errhp, OCI_HTYPE_ERROR);</FONT>
<BR><FONT SIZE=3D2> =
assert(status =3D=3D OCI_SUCCESS);</FONT>
</P>
<P> <FONT SIZE=3D2>/* = Deallocate the environment handle */</FONT> <BR><FONT SIZE=3D2> = assert(self->envhp);</FONT>
<BR><FONT SIZE=3D2> status = =3D OCIHandleFree(self->envhp, OCI_HTYPE_ENV);</FONT> <BR><FONT SIZE=3D2> =assert(status =3D=3D OCI_SUCCESS);</FONT> </P>
<P><FONT SIZE=3D2> =
free(self);</FONT>
<BR><FONT SIZE=3D2>}</FONT>
</P>
<P><FONT SIZE=3D2>int main(int argc, char *argv[]) {</FONT> <BR><FONT SIZE=3D2> char *user;</FONT> <BR><FONT SIZE=3D2> char *password;</FONT> <BR><FONT SIZE=3D2> char *database;</FONT> <BR><FONT SIZE=3D2> ServerContext *db1;</FONT> <BR><FONT SIZE=3D2> ServerContext *db2;</FONT> <BR><FONT SIZE=3D2> assert(argc =3D=3D 4);</FONT> <BR><FONT SIZE=3D2> user =3D argv[1];</FONT> <BR><FONT SIZE=3D2> password =3D argv[2];</FONT> <BR><FONT SIZE=3D2> database =3D argv[3];</FONT> <BR><FONT SIZE=3D2> db1 =3D Connect(user, password, =database);</FONT>
<BR><FONT SIZE=3D2> return 0;</FONT> <BR><FONT SIZE=3D2>}</FONT> </P>
<P><FONT SIZE=3D2>-- </FONT>
<BR><FONT SIZE=3D2>Please see the official ORACLE-L FAQ: <A =
HREF=3D"http://www.orafaq.com" =
TARGET=3D"_blank">http://www.orafaq.com</A></FONT>
<BR><FONT SIZE=3D2>-- </FONT> <BR><FONT SIZE=3D2>Author: Michael Haggerty</FONT> <BR><FONT SIZE=3D2> INET: mhagger_at_alum.mit.edu</FONT> </P>
<P><FONT SIZE=3D2>Fat City Network Services -- (858) =
538-5051 FAX: (858) 538-5051</FONT>
<BR><FONT SIZE=3D2>San Diego, =
California -- Public Internet =
Received on Mon Nov 20 2000 - 09:31:00 CST
![]() |
![]() |