/** * Unload decoder module. * * @param dec The struct srd_decoder to be unloaded. * * @return SRD_OK upon success, a (negative) error code otherwise. */ SRD_API int srd_decoder_unload(struct srd_decoder *dec) { srd_dbg("Unloading protocol decoder '%s'.", dec->name); /* * Since any instances of this decoder need to be released as well, * but they could be anywhere in the stack, just free the entire * stack. A frontend reloading a decoder thus has to restart all * instances, and rebuild the stack. */ srd_inst_free_all(NULL); free_probes(dec->probes); free_probes(dec->opt_probes); g_free(dec->id); g_free(dec->name); g_free(dec->longname); g_free(dec->desc); g_free(dec->license); /* The module's Decoder class. */ Py_XDECREF(dec->py_dec); /* The module itself. */ Py_XDECREF(dec->py_mod); /* TODO: (g_)free dec itself? */ return SRD_OK; }
SRD_PRIV void srd_inst_free_all(GSList *stack) { GSList *l; struct srd_decoder_inst *di; di = NULL; for (l = stack ? stack : di_list; di == NULL && l != NULL; l = l->next) { di = l->data; if (di->next_di) srd_inst_free_all(di->next_di); srd_inst_free(di); } if (!stack) { g_slist_free(di_list); di_list = NULL; } }
/** * Destroy a decoding session. * * All decoder instances and output callbacks are properly released. * * @param sess The session to be destroyed. * * @return SRD_OK upon success, a (negative) error code otherwise. * * @since 0.3.0 */ SRD_API int srd_session_destroy(struct srd_session *sess) { int session_id; if (!sess) { srd_err("Invalid session."); return SRD_ERR_ARG; } session_id = sess->session_id; if (sess->di_list) srd_inst_free_all(sess, NULL); if (sess->callbacks) g_slist_free_full(sess->callbacks, g_free); sessions = g_slist_remove(sessions, sess); g_free(sess); srd_dbg("Destroyed session %d.", session_id); return SRD_OK; }
/** @private */ SRD_PRIV void srd_inst_free_all(struct srd_session *sess, GSList *stack) { GSList *l; struct srd_decoder_inst *di; if (session_is_valid(sess) != SRD_OK) { srd_err("Invalid session."); return; } di = NULL; for (l = stack ? stack : sess->di_list; di == NULL && l != NULL; l = l->next) { di = l->data; if (di->next_di) srd_inst_free_all(sess, di->next_di); srd_inst_free(di); } if (!stack) { g_slist_free(sess->di_list); sess->di_list = NULL; } }