Author: ArcRiley Date: 2009-02-26 17:56:11 -0500 (Thu, 26 Feb 2009) New Revision: 1530
Added: trunk/concordance/src/_core/step.c Modified: trunk/concordance/src/_core/__init__.c Log: beginning work on python callbacks Modified: trunk/concordance/src/_core/__init__.c =================================================================== --- trunk/concordance/src/_core/__init__.c 2009-02-26 22:56:08 UTC (rev 1529) +++ trunk/concordance/src/_core/__init__.c 2009-02-26 22:56:11 UTC (rev 1530) @@ -38,6 +38,7 @@ static PyMethodDef concord_Methods[] = { + { "step", concordStep, NULL, NULL }, { NULL, NULL } }; Added: trunk/concordance/src/_core/step.c =================================================================== --- trunk/concordance/src/_core/step.c (rev 0) +++ trunk/concordance/src/_core/step.c 2009-02-26 22:56:11 UTC (rev 1530) @@ -0,0 +1,132 @@ +/* +# Concordance XMPP Service Framework +# +# Copyright (C) 2009 Copyleft Games Group +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program; if not, see http://www.gnu.org/licenses +# +# $Id: Core.c 1485 2009-01-17 03:19:45Z ArcRiley $ +*/ + +#include "concordance.h" + +static PyObject* +concordStep() { /*\ + cdef : \*/ + concordCore_Object* self = (concordCore_Object*) s; + PyObject* output; + concordCore_QueueMsg* popped; + GTimeVal popEnd; + + /* calculate end time to wait for next callback, 0.5 seconds ahead + + void g_get_current_time (GTimeVal *result); + void g_time_val_add (GTimeVal *time_, + glong microseconds); + */ + g_get_current_time(&popEnd); + g_time_val_add(&popEnd, 50000); + + /* release the GIL while waiting for the next callback + + gpointer g_async_queue_timed_pop (GAsyncQueue *queue, + GTimeVal *end_time); + */ + Py_BEGIN_ALLOW_THREADS + popped = g_async_queue_timed_pop(self->queueRecv, &popEnd); + Py_END_ALLOW_THREADS + + /* return if the pop call timed out */ + if (!popped) + return; + + /* call our handler + + PyObject* PyObject_CallMethod (PyObject *o, + char *method, + char *format, ...) + + O (object) [PyObject *] + Pass a Python object untouched (except for its reference count, + which is incremented by one). If the object passed in is a NULL + pointer, it is assumed that this was caused because the call + producing the argument found an error and set an exception. + Therefore, Py_BuildValue will return NULL but won’t raise an + exception. If no exception has been raised yet, SystemError is set. + + U# (string) [char *, int] + Convert a C string and its length to a Python unicode object. If the + C string pointer is NULL, the length is ignored and None is returned. + */ + output = PyEval_CallMethod(s, "clientHandle", "OU#", + popped->session->self, + popped->message->str, popped->message->len); + + if (!output) { + /* free message struct and exit here if callback raised an error */ + concordCore_queueFreeMsg(popped); + break; + } + + /* if output is None, decref it, free message struct, and continue */ + if (output == Py_None) { + Py_DECREF(output); + concordCore_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); + concordCore_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, + gpointer data); + */ + popped->message = g_string_assign(popped->message, + concordPyUnicodeToUTF8(output)); + g_async_queue_push(self->queueSend, popped); + } + else + /* free message struct since we didn't use it */ + concordCore_queueFreeMsg(popped); + + /* free the output object + + void Py_DECREF (PyObject *o); + */ + Py_DECREF(output); +} _______________________________________________ PySoy-SVN mailing list PySoy-SVN@pysoy.org http://www.pysoy.org/mailman/listinfo/pysoy-svn