Fix some Python reference count + Handle thread concurrency in Python code called from C.

This commit is contained in:
Ghislain MARY 2014-08-01 17:46:05 +02:00
parent ee446299b8
commit 6d53248011
2 changed files with 26 additions and 8 deletions

View file

@ -1,6 +1,10 @@
static void pylinphone_log(const char *level, int indent, const char *fmt, va_list args) {
static int current_indent = 1;
PyObject *linphone_module = PyImport_ImportModule("linphone");
PyObject *linphone_module;
PyGILState_STATE gstate;
gstate = PyGILState_Ensure();
linphone_module = PyImport_ImportModule("linphone");
if ((linphone_module != NULL) && PyObject_HasAttrString(linphone_module, "__log_handler")) {
PyObject *log_handler = PyObject_GetAttrString(linphone_module, "__log_handler");
if ((log_handler != NULL) && PyFunction_Check(log_handler)) {
@ -17,8 +21,11 @@ static void pylinphone_log(const char *level, int indent, const char *fmt, va_li
if (vsnprintf(logstr + i, sizeof(logstr) - i, fmt, args) > 0) {
PyEval_CallFunction(log_handler, "ss", level, logstr);
}
Py_DECREF(log_handler);
}
Py_DECREF(linphone_module);
}
PyGILState_Release(gstate);
}
static PYLINPHONE_INLINE void pylinphone_trace(int indent, const char *fmt, ...) {
@ -47,17 +54,27 @@ static const char * pylinphone_ortp_log_level_to_string(OrtpLogLevel lev) {
}
static void pylinphone_module_log_handler(OrtpLogLevel lev, const char *fmt, va_list args) {
PyObject *linphone_module = PyImport_ImportModule("linphone");
const char *level = pylinphone_ortp_log_level_to_string(lev);
PyGILState_STATE gstate;
PyObject *linphone_module;
const char *level;
gstate = PyGILState_Ensure();
linphone_module = PyImport_ImportModule("linphone");
level = pylinphone_ortp_log_level_to_string(lev);
if ((linphone_module != NULL) && PyObject_HasAttrString(linphone_module, "__log_handler")) {
PyObject *log_handler = PyObject_GetAttrString(linphone_module, "__log_handler");
if ((log_handler != NULL) && PyFunction_Check(log_handler)) {
char logstr[4096];
if (vsnprintf(logstr, sizeof(logstr), fmt, args) > 0) {
PyEval_CallFunction(log_handler, "ss", level, logstr);
if (PyEval_CallFunction(log_handler, "ss", level, logstr) == NULL) {
PyErr_Print();
}
}
Py_DECREF(log_handler);
}
Py_DECREF(linphone_module);
}
PyGILState_Release(gstate);
}
static void pylinphone_init_logging(void) {

View file

@ -556,7 +556,8 @@ class EventCallbackMethodDefinition(MethodDefinition):
def format_local_variables_definition(self):
common = \
""" pylinphone_CoreObject *pylc = (pylinphone_CoreObject *)linphone_core_get_user_data(lc);
PyObject *func = PyDict_GetItemString(pylc->vtable_dict, "{name}");""".format(name=self.class_['event_name'])
PyObject *func = PyDict_GetItemString(pylc->vtable_dict, "{name}");
PyGILState_STATE pygil_state;""".format(name=self.class_['event_name'])
specific = ''
for xml_method_arg in self.xml_method_args:
arg_name = 'py' + xml_method_arg.get('name')
@ -568,7 +569,7 @@ class EventCallbackMethodDefinition(MethodDefinition):
return "{common}\n{specific}".format(common=common, specific=specific)
def format_arguments_parsing(self):
body = ''
body = "\tpygil_state = PyGILState_Ensure();\n"
for xml_method_arg in self.xml_method_args:
arg_name = xml_method_arg.get('name')
arg_type = xml_method_arg.get('type')
@ -629,10 +630,10 @@ class EventCallbackMethodDefinition(MethodDefinition):
""".format(fmt=fmt, args=args)
def format_return_trace(self):
return "\tpylinphone_trace(-1, \"[PYLINPHONE] <<< %s\", __FUNCTION__);"
return "\tpylinphone_trace(-1, \"[PYLINPHONE] <<< %s\", __FUNCTION__);\n"
def format_return_result(self):
return ''
return '\tPyGILState_Release(pygil_state);'
def format(self):
body = MethodDefinition.format(self)