Changeset 638:9448cba86673 in freeDiameter for extensions/dbg_interactive/dispatch.i
- Timestamp:
- Dec 17, 2010, 6:41:19 PM (13 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
extensions/dbg_interactive/dispatch.i
r637 r638 36 36 /* Do not include this directly, use dbg_interactive.i instead */ 37 37 38 /****** DISPATCH *********/ 39 40 41 %{ 42 /* store the python callback function here */ 43 static PyObject * py_dispatch_cb = NULL; 44 static int py_dispatch_cb_n = 0; 45 /* call it (will be called from a different thread than the interpreter, when message arrives) */ 46 static 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); 94 out: 95 Py_XDECREF(result); 96 97 SWIG_PYTHON_THREAD_END_BLOCK; 98 return ret; 99 } 100 %} 101 102 struct 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.