#include <unistd.h>
#include <sndfile.h>
+#include <pthread.h>
#include <pulse/pulseaudio.h>
typedef struct {
}
}
+static void *_cleanup_thread_func(void *userdata)
+{
+ pa_threaded_mainloop *m = (pa_threaded_mainloop *)userdata;
+
+ if (m) {
+ debug_error("now stop and free threaded_mainloop(%p) here", m);
+ pa_threaded_mainloop_stop(m);
+ pa_threaded_mainloop_free(m);
+ } else {
+ debug_warning("thread mainloop is already null");
+ }
+
+ pthread_exit(NULL);
+}
+
+static void _cleanup_threaded_mainloop(pa_threaded_mainloop *m)
+{
+ int ret = 0;
+ pthread_t thread_id;
+ pthread_attr_t attr;
+
+ ret = pthread_attr_init(&attr);
+ if (ret != 0) {
+ debug_error("failed to init pthread attr!!! errno=%d", ret);
+ return;
+ }
+
+ ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ if (ret != 0) {
+ debug_error("failed to set detach state!!! errno=%d", ret);
+ goto finish;
+ }
+
+ ret = pthread_create(&thread_id, &attr, _cleanup_thread_func, m);
+ if (ret != 0)
+ debug_error("failed to create _cleanup_thread_func!!! errno=%d", ret);
+
+finish:
+ ret = pthread_attr_destroy(&attr);
+ if (ret != 0)
+ debug_error("failed to destroy pthread attr!!! errno=%d", ret);
+
+ return;
+}
+
+
static void _pa_context_drain_complete_callback(pa_context *c, void *userdata)
{
+ debug_msg("context drain completed, cleanup context and mainloop");
+
pa_context_disconnect(c);
+ pa_context_unref(c);
+
+ _cleanup_threaded_mainloop((pa_threaded_mainloop *)userdata);
}
/* Stream Callbacks */
pa_stream_unref(h->s);
h->s = NULL;
- if (!(o = pa_context_drain(h->c, _pa_context_drain_complete_callback, h)))
+ if (!(o = pa_context_drain(h->c, _pa_context_drain_complete_callback, h->m))) {
+ debug_error("failed to drain context!");
pa_context_disconnect(h->c);
- else
+ pa_context_unref(h->c);
+ h->c = NULL;
+ } else {
pa_operation_unref(o);
+ }
debug_msg("Call stop callback(%p, %d) of mgr_codec", h->stop_cb, h->cb_param);
if (h->stop_cb)
o = pa_stream_drain(s, _pa_stream_drain_complete_callback, h);
if (o)
pa_operation_unref(o);
+ else
+ debug_error("failed to drain stream %p", s);
}
}
h->s = NULL;
}
if (h->c) {
+ pa_context_disconnect(h->c);
pa_context_unref(h->c);
h->c = NULL;
}