[Zope-Checkins] CVS: Products/DCOracle2/src - dco2.c:1.102

Matthew T. Kromer matt@zope.com
Tue, 29 Jan 2002 11:35:20 -0500


Update of /cvs-repository/Products/DCOracle2/src
In directory cvs.zope.org:/tmp/cvs-serv19880/src

Modified Files:
	dco2.c 
Log Message:
Added thread logging and added error handles to cursors and lobs; so that 
the wrong error does not get attached due to a thread switch. 
(Reported by Alexander Craemer)


=== Products/DCOracle2/src/dco2.c 1.101 => 1.102 === (446/546 lines abridged)
 #include <oci.h>
 #include <Python.h>
+#include <pythread.h>
 
 /* If the build script detected Oracle 9i, turn Oracle 8i definition on too */
 
@@ -162,6 +163,7 @@
 
 #define TRACE(condition,args) if (traceFlags & condition) *(trace args) = (char) condition, Traceprint1(traceLog, -1)
 
+#define T_TSWITCH (0x08)
 #define T_ENTRY   (0x11)	
 #define T_EXIT    (0x12)
 #define T_ERROR   (0x14)
@@ -310,6 +312,7 @@
 typedef struct {
 	PyObject_HEAD
 	ServerContext	*sc;			/* Server Context	*/
+	OCIError	*errhp;			/* Error handle		*/
 	PyObject	*definition;		/* Definition list	*/
 	PyObject	*results;		/* Result set list	*/
 	OCIStmt		*stmtp;			/* Statement pointer	*/
@@ -339,6 +342,7 @@
 typedef struct {
 	PyObject_HEAD
 	ServerContext	*sc;			/* Server Context	*/
+	OCIError	*errhp;			/* Error handle		*/
 	OCILobLocator	*lobp;			/* LOB Locator		*/
 } LobLocator;
 
@@ -1751,6 +1755,7 @@
 	if ((cursor = PyObject_NEW(Cursor, &CursorType)) == NULL) return NULL;
 
 	cursor->stmtp = NULL;
+	cursor->errhp = NULL;
 
 	TRACE(T_HCALL,("sAs", "OCIHandleAlloc", &cursor->stmtp,
 		"OCI_HTYPE_STMT"));
@@ -1765,6 +1770,20 @@
 		return NULL;
 	}
 
+	/* Allocate the per-cursor error handle */
+	TRACE(T_HCALL,("sAs","OCIHandleAlloc",&cursor->errhp,
+		"OCI_HTYPE_ERROR"));
+	status = OCIHandleAlloc(self->envhp, (dvoid **)&cursor->errhp,
+		OCI_HTYPE_ERROR, 0, NULL);
+	TRACE(T_RETURN,("sRA","OCIHandleAlloc",status,cursor->errhp));
+
+	if (status != OCI_SUCCESS) {

[-=- -=- -=- 446 lines omitted -=- -=- -=-]

-	status = OCILobWrite(self->sc->svchp, self->sc->errhp, self->lobp,
+	status = OCILobWrite(self->sc->svchp, self->errhp, self->lobp,
 		(ub4 *) &sl, offset, s, sl, OCI_ONE_PIECE, NULL, NULL,
 		csid, csfrm);
 
@@ -4516,7 +4575,7 @@
 	TRACE(T_RETURN,("sR", "OCILobWrite", status));
 
 	if (status != OCI_SUCCESS) 
-		return RaiseOCIError(self->sc->errhp, OCI_HTYPE_ERROR);
+		return RaiseOCIError(self->errhp, OCI_HTYPE_ERROR);
 
 	obj = PyInt_FromLong(sl);
 
@@ -4549,7 +4608,7 @@
 	/* Note that the amount is going to get garbled if the character
 	** set size is not 1
 	*/
-	status = OCILobTrim(self->sc->svchp, self->sc->errhp, self->lobp,
+	status = OCILobTrim(self->sc->svchp, self->errhp, self->lobp,
 		len);
 
 	Py_END_ALLOW_THREADS
@@ -4557,7 +4616,7 @@
 	TRACE(T_RETURN,("sR", "OCILobTrim", status));
 
 	if (status != OCI_SUCCESS) 
-		return RaiseOCIError(self->sc->errhp, OCI_HTYPE_ERROR);
+		return RaiseOCIError(self->errhp, OCI_HTYPE_ERROR);
 
 	obj = Py_None;
 	Py_INCREF(obj);
@@ -6328,8 +6387,17 @@
 	int d;
 	int i = 0;
 	traceRecord *tr;
+	static long last_thread = -1;
 
 	if (traceBase == NULL) return NULL; /* FIXME -- macro cant take */
+
+	if (traceFlags & T_TSWITCH) {
+		long tid = PyThread_get_thread_ident();
+		if (tid != last_thread) {
+			last_thread = tid;
+			TRACE(T_TSWITCH,("sd", "ThreadSwitch", tid));
+		}
+	}
 
 	if (traceNext >= traceCount) traceNext = 0;
 	tr = traceBase + traceNext++;