Author: ArcRiley Date: 2009-01-09 23:02:10 -0500 (Fri, 09 Jan 2009) New Revision: 1456
Modified: trunk/concordance/examples/echo.py trunk/concordance/src/Core.c Log: now typechecks callback returns to do the right thing (ie, not segfault) Modified: trunk/concordance/examples/echo.py =================================================================== --- trunk/concordance/examples/echo.py 2009-01-09 23:04:06 UTC (rev 1455) +++ trunk/concordance/examples/echo.py 2009-01-10 04:02:10 UTC (rev 1456) @@ -29,7 +29,7 @@ class newcore(concordance.Core) : def clientHandle(self, input) : print(":%s" % input) - return "" + return nc = newcore() nc() Modified: trunk/concordance/src/Core.c =================================================================== --- trunk/concordance/src/Core.c 2009-01-09 23:04:06 UTC (rev 1455) +++ trunk/concordance/src/Core.c 2009-01-10 04:02:10 UTC (rev 1456) @@ -21,6 +21,7 @@ #include "Core.h" +static void conCore_queueFreeMsg (conCoreQueueMsg*); static gpointer conCore_loop (gpointer); static int conCore_listenChannel (conCoreObject*, conChannel*); static gboolean conCore_listenNew (GIOChannel*, GIOCondition, gpointer); @@ -298,8 +299,9 @@ popped = g_async_queue_timed_pop(self->queueRecv, &popEnd); Py_END_ALLOW_THREADS - /* return to start of loop if NULL is returned */ - if (!popped) continue; + /* return to start of loop if the pop call timed out */ + if (!popped) + continue; /* build argument tuple @@ -322,25 +324,70 @@ handle = PyObject_GetAttrString(s, "clientHandle"); output = PyEval_CallObject(handle, tinput); - /* reset popped->message to reuse with response, convert utf16 to utf8 + /* free the objects we're done with - GString* g_string_assign (GString *string, + void Py_DECREF (PyObject *o); + */ + Py_DECREF(handle); + Py_DECREF(tinput); + Py_DECREF(sinput); + + if (!output) { + /* free message struct and exit here if callback raised an error */ + conCore_queueFreeMsg(popped); + break; + } + + /* if output is None, decref it, free message struct, and continue */ + if (output == Py_None) { + Py_DECREF(output); + conCore_queueFreeMsg(popped); + continue; + } + + /* ensure output is PyUnicode_Type (since it's not None) + + int PyUnicode_Check (PyObject *o); + */ + if (!PyUnicode_Check(output)) { + /* free whatever was returned and raise an error + + void Py_DECREF (PyObject *o); + void PyErr_SetString (PyObject *type, + const char *message); + */ + Py_DECREF(output); + conCore_queueFreeMsg(popped); + PyErr_SetString(PyExc_TypeError, + "handle must return a Unicode string or None"); + return NULL; + } + + /* only use output when non-empty + + Py_ssize_t PyUnicode_GetSize (PyObject *unicode); + */ + if (PyUnicode_GetSize(output)) { + /* convert unicode to utf8, reusing popped->message for response + + GString* g_string_assign (GString *string, const gchar *rval); - void g_async_queue_push (GAsyncQueue *queue, + void g_async_queue_push (GAsyncQueue *queue, gpointer data); - */ - popped->message = g_string_assign(popped->message, - conPyUnicodeToUTF8(output)); - g_async_queue_push(self->queueSend, popped); + */ + popped->message = g_string_assign(popped->message, + conPyUnicodeToUTF8(output)); + g_async_queue_push(self->queueSend, popped); + } + else + /* free message struct since we didn't use it */ + conCore_queueFreeMsg(popped); - /* free the objects we're done with + /* free the output object void Py_DECREF (PyObject *o); */ Py_DECREF(output); - Py_DECREF(handle); - Py_DECREF(tinput); - Py_DECREF(sinput); } /* signal was raised, return with error condition */ @@ -351,6 +398,26 @@ # ########################################################################### # + # Convenience functions + # */ + + static void + conCore_queueFreeMsg(conCoreQueueMsg* msg) { + /* free message struct and it's members + + gchar* g_string_free (GString *string, + gboolean free_segment); + void g_free (gpointer mem); + */ + g_string_free(msg->message, TRUE); + g_free(msg); + } + + + /* + # + ########################################################################### + # # MainLoop thread functions (nogil) # */ @@ -611,15 +678,8 @@ pop = g_async_queue_pop(self->queueSend); conCore_sessionSend(pop->session, pop->message->str, pop->message->len); - /* free popped message before returning - - gchar* g_string_free (GString *string, - gboolean free_segment); - void g_free (gpointer mem); - */ - g_string_free(pop->message, TRUE); - g_free(pop); - + /* free popped message struct and return */ + conCore_queueFreeMsg(pop); return TRUE; } _______________________________________________ PySoy-SVN mailing list PySoy-SVN@pysoy.org http://www.pysoy.org/mailman/listinfo/pysoy-svn