[BRLTTY] Fwd: Orca crash with grade 2 and latest versions of brltty and liblouis

Samuel Thibault samuel.thibault at ens-lyon.org
Sun Jul 19 19:31:27 EDT 2009


Hello,

Mario Lang, le Fri 03 Jul 2009 10:08:13 +0200, a écrit :
> Samuel Thibault <samuel.thibault at ens-lyon.org> writes:
> > Willie Walker, le Thu 02 Jul 2009 15:29:45 -0400, a écrit :
> >> BrlAPI provides a brlapi_setExceptionHandler method, but I'm not sure 
> >> how to get to it from Python.  Can you BrlTTY folks offer some guidance?
> >
> > We haven't implemented anything for this yet.  The issue is being able
> > to call python code from the C code, I don't know how this is allowed to
> > be done.
> 
> The following article is probably pretty helpful:
> http://www.codeproject.com/KB/cpp/embedpython_1.aspx

Thanks!
I played a bit, and unfortunately we can't raise exception from C. Or
rather, that doesn't raise it, just record it and return.  I've followed
another, simpler, way.  Dave, could you apply the attached patch which
transforms BrlAPI protocol exceptions into python exceptions?

Samuel
-------------- next part --------------
Index: Bindings/Python/bindings.h
===================================================================
--- Bindings/Python/bindings.h	(révision 4693)
+++ Bindings/Python/bindings.h	(copie de travail)
@@ -22,3 +22,5 @@
 #include "brlapi.h"
 
 extern const brlapi_writeArguments_t brlapi_writeArguments_initialized;
+extern char *brlapi_protocolException(void);
+extern void brlapi_protocolExceptionInit(brlapi_handle_t *handle);
Index: Bindings/Python/c_brlapi.pxd
===================================================================
--- Bindings/Python/c_brlapi.pxd	(révision 4693)
+++ Bindings/Python/c_brlapi.pxd	(copie de travail)
@@ -104,6 +104,8 @@
 
 cdef extern from "bindings.h":
 	brlapi_writeArguments_t brlapi_writeArguments_initialized
+	char *brlapi_protocolException()
+	void brlapi_protocolExceptionInit(brlapi_handle_t *)
 
 cdef extern from "stdlib.h":
 	void *malloc(size_t)
Index: Bindings/Python/brlapi.pyx
===================================================================
--- Bindings/Python/brlapi.pyx	(révision 4693)
+++ Bindings/Python/brlapi.pyx	(copie de travail)
@@ -80,14 +80,22 @@
 class OperationError(Exception):
 	"""Error while performing some operation"""
 	def __init__(self):
-		self.brlerrno = c_brlapi.brlapi_error.brlerrno
-		self.libcerrno = c_brlapi.brlapi_error.libcerrno
-		self.gaierrno = c_brlapi.brlapi_error.gaierrno
-		if (c_brlapi.brlapi_error.errfun):
-			self.errfun = c_brlapi.brlapi_error.errfun
+		cdef char *exception
+		exception = c_brlapi.brlapi_protocolException()
+		if (exception):
+			self.exception = exception
+			c_brlapi.free(exception)
+		else:
+			self.brlerrno = c_brlapi.brlapi_error.brlerrno
+			self.libcerrno = c_brlapi.brlapi_error.libcerrno
+			self.gaierrno = c_brlapi.brlapi_error.gaierrno
+			if (c_brlapi.brlapi_error.errfun):
+				self.errfun = c_brlapi.brlapi_error.errfun
 
 	def __str__(self):
 		cdef c_brlapi.brlapi_error_t error
+		if self.exception:
+			return self.exception
 		error.brlerrno = self.brlerrno
 		error.libcerrno = self.libcerrno
 		error.gaierrno = self.gaierrno
@@ -273,6 +281,7 @@
 		c_brlapi.Py_BEGIN_ALLOW_THREADS
 		self.fd = c_brlapi.brlapi__openConnection(self.h, &client, &self.settings)
 		c_brlapi.Py_END_ALLOW_THREADS
+		c_brlapi.brlapi_protocolExceptionInit(self.h)
 		if self.fd == -1:
 			c_brlapi.free(self.h)
 			raise ConnectionError(self.settings.host, self.settings.auth)
Index: Bindings/Python/bindings.c
===================================================================
--- Bindings/Python/bindings.c	(révision 4693)
+++ Bindings/Python/bindings.c	(copie de travail)
@@ -17,8 +17,77 @@
  * This software is maintained by Dave Mielke <dave at mielke.cc>.
  */
 
-/* bindings.c provides initialized variables to the Python bindings */
+/* bindings.c provides initialized variables and brlapi exception handler to
+ * the Python bindings */
 
+
 #include "brlapi.h"
 
+#ifdef __MINGW32__
+#include "win_pthread.h"
+#else
+#include <pthread.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#include "bindings.h"
+
 const brlapi_writeArguments_t brlapi_writeArguments_initialized = BRLAPI_WRITEARGUMENTS_INITIALIZER;
+
+static pthread_once_t brlapi_protocolExceptionOnce = PTHREAD_ONCE_INIT;
+static pthread_key_t brlapi_protocolExceptionKey;
+static char *brlapi_protocolExceptionSingleThread;
+
+#if defined(WINDOWS)
+
+#elif defined(__GNUC__) || defined(__sun__)
+#pragma weak pthread_once
+#pragma weak pthread_key_create
+#pragma weak pthread_getspecific
+#pragma weak pthread_setspecific
+#endif /* weak external references */
+
+static void BRLAPI_STDCALL brlapi_pythonExceptionHandler(brlapi_handle_t *handle, int error, brlapi_packetType_t type, const void *packet, size_t size)
+{
+  char str[128];
+
+  brlapi__strexception(handle, str, sizeof(str), error, type, packet, size);
+#ifndef WINDOWS
+  if (!(pthread_once && pthread_key_create))
+    brlapi_protocolExceptionSingleThread = strdup(str);
+  else
+#endif
+    pthread_setspecific(brlapi_protocolExceptionKey, strdup(str));
+}
+
+char *brlapi_protocolException(void)
+{
+  char *exception;
+#ifndef WINDOWS
+  if (!(pthread_once && pthread_key_create)) {
+    exception = brlapi_protocolExceptionSingleThread;
+    brlapi_protocolExceptionSingleThread = NULL;
+    return exception;
+  } else
+#endif
+  {
+    exception = pthread_getspecific(brlapi_protocolExceptionKey);
+    pthread_setspecific(brlapi_protocolExceptionKey, NULL);
+    return exception;
+  }
+}
+
+static void do_brlapi_protocolExceptionInit(void)
+{
+  pthread_key_create(&brlapi_protocolExceptionKey, free);
+}
+
+void brlapi_protocolExceptionInit(brlapi_handle_t *handle) {
+#ifndef WINDOWS
+  if (pthread_once && pthread_key_create)
+#endif /* WINDOWS */
+    pthread_once(&brlapi_protocolExceptionOnce, do_brlapi_protocolExceptionInit);
+
+  brlapi__setExceptionHandler(handle, &brlapi_pythonExceptionHandler);
+}


More information about the BRLTTY mailing list