in source/mqtt_client_connection.c [1025:1083]
static void s_suback_multi_callback(
struct aws_mqtt_client_connection *connection,
uint16_t packet_id,
const struct aws_array_list *topic_subacks, /* contains aws_mqtt_topic_subscription pointers */
int error_code,
void *userdata) {
(void)connection;
/* These must be DECREF'd when function ends */
PyObject *callback = userdata;
PyObject *callback_result = NULL;
PyObject *topic_qos_list = NULL;
PyGILState_STATE state;
if (aws_py_gilstate_ensure(&state)) {
return; /* Python has shut down. Nothing matters anymore, but don't crash */
}
if (error_code) {
goto done_prepping_args;
}
const size_t num_topics = aws_array_list_length(topic_subacks);
/* Create list of (topic,qos) tuples */
topic_qos_list = PyList_New(num_topics);
if (!topic_qos_list) {
error_code = aws_py_raise_error();
goto done_prepping_args;
}
for (size_t i = 0; i < num_topics; ++i) {
struct aws_mqtt_topic_subscription sub_i;
aws_array_list_get_at(topic_subacks, &sub_i, i);
PyObject *tuple = Py_BuildValue("(s#i)", sub_i.topic.ptr, sub_i.topic.len, sub_i.qos);
if (!tuple) {
error_code = aws_py_raise_error();
goto done_prepping_args;
}
PyList_SET_ITEM(topic_qos_list, i, tuple); /* Steals reference to tuple */
}
done_prepping_args:;
/* Don't pass the list if there was an error, since the list might be only partially constructed */
callback_result =
PyObject_CallFunction(callback, "(HOi)", packet_id, (error_code ? Py_None : topic_qos_list), error_code);
if (!callback_result) {
PyErr_WriteUnraisable(PyErr_Occurred());
}
Py_DECREF(callback);
Py_XDECREF(callback_result);
Py_XDECREF(topic_qos_list);
PyGILState_Release(state);
}