Navigation



Ignore:
Timestamp:
Dec 17, 2010, 6:41:19 PM (13 years ago)
Author:
Sebastien Decugis <sdecugis@nict.go.jp>
Branch:
default
Phase:
public
Message:

Improved usability of dbg_interactive

File:
1 edited

Legend:

Unmodified
Added
Removed
  • extensions/dbg_interactive/dispatch.i

    r637 r638  
    3636/* Do not include this directly, use dbg_interactive.i instead */
    3737
     38/****** DISPATCH *********/
     39
     40
     41%{
     42/* store the python callback function here */
     43static PyObject * py_dispatch_cb = NULL;
     44static int        py_dispatch_cb_n = 0;
     45/* call it (will be called from a different thread than the interpreter, when message arrives) */
     46static int call_the_python_dispatch_callback(struct msg **msg, struct avp *avp, struct session *session, enum disp_action *action) {
     47        PyObject *PyMsg, *PyAvp, *PySess;
     48        PyObject *result = NULL;
     49        int ret = 0;
     50       
     51        if (!py_dispatch_cb)
     52                return ENOTSUP;
     53       
     54        SWIG_PYTHON_THREAD_BEGIN_BLOCK;
     55        /* Convert the arguments */
     56        PyMsg  = SWIG_NewPointerObj((void *)*msg,     SWIGTYPE_p_msg,     0 );
     57        PyAvp  = SWIG_NewPointerObj((void *) avp,     SWIGTYPE_p_avp,     0 );
     58        PySess = SWIG_NewPointerObj((void *) session, SWIGTYPE_p_session, 0 );
     59       
     60        /* Call the function */
     61        result = PyEval_CallFunction(py_dispatch_cb, "(OOO)", PyMsg, PyAvp, PySess);
     62       
     63        /* The result is supposedly composed of: [ ret, *msg, *action ] */
     64        if ((result == NULL) || (!PyList_Check(result)) || (PyList_Size(result) != 3)) {
     65                fd_log_debug("Error: The Python callback did not return [ ret, msg, action ].\n");
     66                ret = EINVAL;
     67                goto out;
     68        }
     69       
     70        /* Convert the return values */
     71        if (!SWIG_IsOK(SWIG_AsVal_int(PyList_GetItem(result, 0), &ret))) {
     72                fd_log_debug("Error: Cannot convert the first return value to integer.\n");
     73                ret = EINVAL;
     74                goto out;
     75        }
     76        if (ret) {
     77                TRACE_DEBUG(INFO, "The Python callback returned the error code %d (%s)\n", ret, strerror(ret));
     78                goto out;
     79        }
     80       
     81        if (!SWIG_IsOK(SWIG_ConvertPtr(PyList_GetItem(result, 1), (void *)msg, SWIGTYPE_p_msg, SWIG_POINTER_DISOWN))) {
     82                fd_log_debug("Error: Cannot convert the second return value to message.\n");
     83                ret = EINVAL;
     84                goto out;
     85        }
     86       
     87        if (!SWIG_IsOK(SWIG_AsVal_int(PyList_GetItem(result, 2), (int *)action))) {
     88                fd_log_debug("Error: Cannot convert the third return value to integer.\n");
     89                ret = EINVAL;
     90                goto out;
     91        }
     92       
     93        TRACE_DEBUG(FULL, "Python callback return: *action = %d\n", *action);
     94out:   
     95        Py_XDECREF(result);
     96       
     97        SWIG_PYTHON_THREAD_END_BLOCK;
     98        return ret;
     99}
     100%}
     101
     102struct disp_hdl {
     103};
     104
     105%nodefaultctor disp_hdl;
     106%extend disp_hdl {
     107        disp_hdl(PyObject * PyCb, enum disp_how how, struct disp_when * when) {
     108                struct disp_hdl * hdl = NULL;
     109                int ret;
     110                if (py_dispatch_cb && (py_dispatch_cb != PyCb)) {
     111                        DI_ERROR(EINVAL, PyExc_SyntaxError, "Only one dispatch callback is supported at the moment in this extension\n.");
     112                        return NULL;
     113                }
     114                py_dispatch_cb = PyCb;
     115                py_dispatch_cb_n += 1;
     116                Py_XINCREF(py_dispatch_cb);
     117               
     118                ret = fd_disp_register ( call_the_python_dispatch_callback, how, when, &hdl );
     119                if (ret != 0) {
     120                        DI_ERROR(ret, NULL, NULL);
     121                        return NULL;
     122                }
     123                return hdl;
     124        }
     125        ~disp_hdl() {
     126                struct disp_hdl * hdl = self;
     127                int ret = fd_disp_unregister(&hdl);
     128                if (ret != 0) {
     129                        DI_ERROR(ret, NULL, NULL);
     130                }
     131                /* Now free the callback */
     132                Py_XDECREF(py_dispatch_cb);
     133                py_dispatch_cb_n -= 1;
     134                if (!py_dispatch_cb_n)
     135                        py_dispatch_cb = NULL;
     136                return;
     137        }
     138}
     139
     140
     141%extend disp_when {
     142        disp_when(struct dict_object * app = NULL, struct dict_object * command = NULL, struct dict_object * avp = NULL, struct dict_object * value = NULL) {
     143                struct disp_when * w = (struct disp_when *)calloc(1, sizeof(struct disp_when));
     144                if (!w) {
     145                        DI_ERROR_MALLOC;
     146                        return NULL;
     147                }
     148                w->app = app;
     149                w->command = command;
     150                w->avp = avp;
     151                w->value = value;
     152                return w;
     153        }
     154}
Note: See TracChangeset for help on using the changeset viewer.