Mercurial > hg > freeDiameter
diff extensions/dbg_interactive/routing.i @ 640:237cf6339546
dbg_interactive almost complete
author | Sebastien Decugis <sdecugis@nict.go.jp> |
---|---|
date | Mon, 20 Dec 2010 19:36:40 +0900 |
parents | 22e8fac3b2d6 |
children | 4ffbc9f1e922 |
line wrap: on
line diff
--- a/extensions/dbg_interactive/routing.i Mon Dec 20 13:07:06 2010 +0900 +++ b/extensions/dbg_interactive/routing.i Mon Dec 20 19:36:40 2010 +0900 @@ -76,6 +76,8 @@ } } + + %extend rtd_candidate { void dump() { fd_log_debug("candidate %p\n", $self); @@ -85,3 +87,161 @@ } } + +%{ +/* call it (will be called from a different thread than the interpreter, when message arrives) */ +static int call_the_python_rt_fwd_callback(void * pycb, struct msg **msg) { + PyObject *PyMsg; + PyObject *cb, *result = NULL; + int ret = 0; + + if (!pycb) { + fd_log_debug("Internal error: missing the callback!\n"); + return ENOTSUP; + } + cb = pycb; + + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + /* Convert the arguments */ + PyMsg = SWIG_NewPointerObj((void *)*msg, SWIGTYPE_p_msg, 0 ); + + /* Call the function */ + result = PyEval_CallFunction(cb, "(O)", PyMsg); + + /* The result is supposedly composed of: [ ret, *msg ] */ + if ((result == NULL) || (!PyList_Check(result)) || (PyList_Size(result) != 2)) { + fd_log_debug("Error: The Python callback did not return [ ret, msg ].\n"); + ret = EINVAL; + goto out; + } + + /* Convert the return values */ + if (!SWIG_IsOK(SWIG_AsVal_int(PyList_GetItem(result, 0), &ret))) { + fd_log_debug("Error: Cannot convert the first return value to integer.\n"); + ret = EINVAL; + goto out; + } + if (ret) { + TRACE_DEBUG(INFO, "The Python callback returned the error code %d (%s)\n", ret, strerror(ret)); + goto out; + } + + if (!SWIG_IsOK(SWIG_ConvertPtr(PyList_GetItem(result, 1), (void *)msg, SWIGTYPE_p_msg, SWIG_POINTER_DISOWN))) { + fd_log_debug("Error: Cannot convert the second return value to message.\n"); + ret = EINVAL; + goto out; + } + +out: + Py_XDECREF(result); + + SWIG_PYTHON_THREAD_END_BLOCK; + return ret; +} +%} + + +struct fd_rt_fwd_hdl { +}; + +%extend fd_rt_fwd_hdl{ + fd_rt_fwd_hdl(PyObject * PyCb, enum fd_rt_fwd_dir dir) { + struct fd_rt_fwd_hdl * r = NULL; + int ret; + + Py_XINCREF(PyCb); + + ret = fd_rt_fwd_register( call_the_python_rt_fwd_callback, PyCb, dir, &r ); + if (ret != 0) { + DI_ERROR(ret, NULL, NULL); + return NULL; + } + return r; + } + + ~fd_rt_fwd_hdl() { + PyObject * func; + int ret = fd_rt_fwd_unregister ( $self, (void *) &func ); + if (ret != 0) { + DI_ERROR(ret, NULL, NULL); + return; + } + Py_XDECREF(func); + return; + } +} + + +%{ +/* call it (will be called from a different thread than the interpreter, when message arrives) */ +static int call_the_python_rt_out_callback(void * pycb, struct msg *msg, struct fd_list * candidates) { + PyObject *PyMsg, *PyCands; + PyObject *cb, *result = NULL; + int ret = 0; + + if (!pycb) { + fd_log_debug("Internal error: missing the callback!\n"); + return ENOTSUP; + } + cb = pycb; + + SWIG_PYTHON_THREAD_BEGIN_BLOCK; + /* Convert the arguments */ + PyMsg = SWIG_NewPointerObj((void *)msg, SWIGTYPE_p_msg, 0 ); + PyCands = SWIG_NewPointerObj((void *)candidates, SWIGTYPE_p_fd_list, 0 ); + + /* Call the function */ + result = PyEval_CallFunction(cb, "(OO)", PyMsg, PyCands); + + /* The result is supposedly composed of: [ ret, *msg ] */ + if (result == NULL){ + fd_log_debug("Error: The Python callback raised an exception.\n"); + ret = EINVAL; + goto out; + } + + /* Convert the return values */ + if (!SWIG_IsOK(SWIG_AsVal_int(result, &ret))) { + fd_log_debug("Error: Cannot convert the return value to integer.\n"); + ret = EINVAL; + goto out; + } +out: + Py_XDECREF(result); + + SWIG_PYTHON_THREAD_END_BLOCK; + return ret; +} +%} + + +struct fd_rt_out_hdl { +}; + +%extend fd_rt_out_hdl{ + fd_rt_out_hdl(PyObject * PyCb, int priority = 0) { + struct fd_rt_out_hdl * r = NULL; + int ret; + + Py_XINCREF(PyCb); + + ret = fd_rt_out_register( call_the_python_rt_out_callback, PyCb, priority, &r ); + if (ret != 0) { + DI_ERROR(ret, NULL, NULL); + return NULL; + } + return r; + } + + ~fd_rt_out_hdl() { + PyObject * func; + int ret = fd_rt_out_unregister ( $self, (void *) &func ); + if (ret != 0) { + DI_ERROR(ret, NULL, NULL); + return; + } + Py_XDECREF(func); + return; + } +} +