Author: ArcRiley
Date: 2009-01-13 16:45:14 -0500 (Tue, 13 Jan 2009)
New Revision: 1475

Modified:
   trunk/concordance/examples/register.py
   trunk/concordance/src/Core.c
   trunk/concordance/src/Core.h
   trunk/concordance/src/Session.c
   trunk/concordance/src/__init__.h
Log:
Python callback now receives a concord.Session object
  * many cleanups to concordCore_call
  * mutex lock for keeping everything in sync
  * start of proper cleanup code
  * updated API in examples/register.py


Modified: trunk/concordance/examples/register.py
===================================================================
--- trunk/concordance/examples/register.py      2009-01-13 05:10:20 UTC (rev 
1474)
+++ trunk/concordance/examples/register.py      2009-01-13 21:45:14 UTC (rev 
1475)
@@ -43,7 +43,7 @@
         ElementTree.SubElement(out_query, field)
 
 
-  def clientHandle(self, input) :
+  def clientHandle(self, session, input) :
     # get xml root of input
     in_root = ElementTree.fromstring(input)
 

Modified: trunk/concordance/src/Core.c
===================================================================
--- trunk/concordance/src/Core.c        2009-01-13 05:10:20 UTC (rev 1474)
+++ trunk/concordance/src/Core.c        2009-01-13 21:45:14 UTC (rev 1475)
@@ -249,9 +249,6 @@
     cdef :                                                                \*/
       static char*           kwlist[] = {0};
       concordCore_Object*    self = (concordCore_Object*) s;
-      PyObject*              handle;
-      PyObject*              sinput;
-      PyObject*              tinput;
       PyObject*              output;
       concordCore_QueueMsg*  popped;
       GTimeVal               popEnd;
@@ -288,34 +285,58 @@
       if (!popped)
         continue;
 
-      /* build argument tuple
+      /* lock, then create Python instance of Session only if needed
 
-         PyObject*      PyUnicode_FromStringAndSize   (const char *u,
-                                                       Py_ssize_t size)
-         PyObject*      PyTuple_Pack                  (Py_ssize_t n,
-                                                       ...)
+         void           g_mutex_lock             (GMutex *mutex);
+         PyObject*      PyObject_CallFunction    (PyObject *callable,
+                                                  char *format,
+                                                  ...)
+         The format may be NULL, indicating that no arguments are provided.
+         Returns the result of the call on success, or NULL on failure.
       */
-      sinput = PyUnicode_FromStringAndSize(popped->message->str,
-                                           popped->message->len);
-      tinput = PyTuple_Pack(1, sinput);
+      g_mutex_lock(popped->session->lock);
+      if (!popped->session->self)
+        popped->session->self = PyObject_CallFunction((PyObject*)
+                                                      &concordSession_Type,
+                                                      NULL);
+      
+      /* connect session data, or exit on error, unlock in either case
 
+         void           g_mutex_lock             (GMutex *mutex);
+         void           g_mutex_unlock           (GMutex *mutex);
+      */
+      if (popped->session->self) {
+        ((concordSession_Object*) popped->session->self)->data = 
+        popped->session;
+        g_mutex_unlock(popped->session->lock);
+      }
+      else {
+        g_mutex_unlock(popped->session->lock);
+        concordCore_queueFreeMsg(popped);
+        break;
+      }
+
       /* call our handler
 
-         PyObject*      PyObject_GetAttrString   (PyObject *o,
-                                                  const char *attr_name)
-         PyObject*      PyEval_CallObject        (PyObject*,
-                                                  PyObject*);
-      */
-      handle = PyObject_GetAttrString(s, "clientHandle");
-      output = PyEval_CallObject(handle, tinput);
+         PyObject*      PyObject_CallMethod      (PyObject *o,
+                                                  char *method,
+                                                  char *format, ...)
 
-      /* free the objects we're done with
+         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.
 
-         void           Py_DECREF                (PyObject *o);
+         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.
       */
-      Py_DECREF(handle);
-      Py_DECREF(tinput);
-      Py_DECREF(sinput);
+      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 */

Modified: trunk/concordance/src/Core.h
===================================================================
--- trunk/concordance/src/Core.h        2009-01-13 05:10:20 UTC (rev 1474)
+++ trunk/concordance/src/Core.h        2009-01-13 21:45:14 UTC (rev 1475)
@@ -33,8 +33,8 @@
 
 
 typedef struct {
+  concordSession_Data*  session;
   GString*              message;
-  concordSession_Data*  session;
 } concordCore_QueueMsg;
 
 

Modified: trunk/concordance/src/Session.c
===================================================================
--- trunk/concordance/src/Session.c     2009-01-13 05:10:20 UTC (rev 1474)
+++ trunk/concordance/src/Session.c     2009-01-13 21:45:14 UTC (rev 1475)
@@ -46,6 +46,8 @@
 
     if (self)
       self->data = NULL;
+
+    /* return either the new instance or NULL */
     return (PyObject*) self;
   }
 
@@ -72,7 +74,18 @@
   static void
   concordSession_dealloc(concordSession_Object* self) {                   /*\
     cdef :                                                                \*/
+    
+    if (self->data) {
+      /* lock data mutex, clear ourselves from it, then unlock
 
+         void           g_mutex_lock             (GMutex *mutex);
+         void           g_mutex_unlock           (GMutex *mutex);
+      */
+      g_mutex_lock(self->data->lock);
+      self->data->self = NULL;
+      g_mutex_unlock(self->data->lock);
+    }
+
     PyObject_Del(self);
   }
 
@@ -101,11 +114,14 @@
     cdef :                                                                \*/
       concordSession_Data* session;
 
-    /* create new session, store the pointer to parent Core
+    /* create new session, create lock, and store the pointer to parent Core
 
        gpointer         g_malloc                 (gsize n_bytes);
+       GMutex *         g_mutex_new              ();
     */
     session = g_malloc(sizeof(concordSession_Data));
+    session->self = NULL;
+    session->lock = g_mutex_new();
     session->core = core;
 
     /* create channel and add it to our context watchlist
@@ -176,6 +192,18 @@
   }
 
 
+  static void
+  concordSession_destroy(concordSession_Data* session) {                  /*\
+    cdef :                                                                \*/
+
+    /* free the mutex lock
+
+       void             g_mutex_free             (GMutex *mutex);
+    */
+    g_mutex_free(session->lock);
+  }
+
+
   void
   concordSession_send(concordSession_Data* session, gchar* str,
                       gint len) {                                         /*\

Modified: trunk/concordance/src/__init__.h
===================================================================
--- trunk/concordance/src/__init__.h    2009-01-13 05:10:20 UTC (rev 1474)
+++ trunk/concordance/src/__init__.h    2009-01-13 21:45:14 UTC (rev 1475)
@@ -47,6 +47,7 @@
 
 typedef struct {
   PyObject*             self;          /* Session object for this or NULL */
+  GMutex*               lock;          /* Mutex for self test/add/remove */
   concordCore_Object*   core;          /* Core this session belongs to */
   GIOChannel*           chan;          /* Glib IO channel for this session */
   Gsasl_session*        sctx;          /* gsasl session context */

_______________________________________________
PySoy-SVN mailing list
PySoy-SVN@pysoy.org
http://www.pysoy.org/mailman/listinfo/pysoy-svn

Reply via email to