aboutsummaryrefslogtreecommitdiff
path: root/src/pulse-manager.c
diff options
context:
space:
mode:
authorConor Curran <conor.curran@canonical.com>2010-02-26 12:29:16 +0000
committerConor Curran <conor.curran@canonical.com>2010-02-26 12:29:16 +0000
commit11f1982a7b23d55be2306ab6da80879d2f9d8e03 (patch)
tree885bad6773a30a3c259931e1684bfb0cccd746fe /src/pulse-manager.c
parent191f8934b194f2728e175b228f1931f28c1ab8fa (diff)
downloadayatana-indicator-sound-11f1982a7b23d55be2306ab6da80879d2f9d8e03.tar.gz
ayatana-indicator-sound-11f1982a7b23d55be2306ab6da80879d2f9d8e03.tar.bz2
ayatana-indicator-sound-11f1982a7b23d55be2306ab6da80879d2f9d8e03.zip
handles pulseaudio flapping without memory leaks - solid
Diffstat (limited to 'src/pulse-manager.c')
-rw-r--r--src/pulse-manager.c43
1 files changed, 37 insertions, 6 deletions
diff --git a/src/pulse-manager.c b/src/pulse-manager.c
index 9b9d7cd..4436561 100644
--- a/src/pulse-manager.c
+++ b/src/pulse-manager.c
@@ -31,7 +31,6 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
static GHashTable *sink_hash = NULL;
static SoundServiceDbus *dbus_service = NULL;
-// Until we find a satisfactory default sink this index should remain < 0
static gint DEFAULT_SINK_INDEX = -1;
static gboolean pa_server_available = FALSE;
// PA related
@@ -46,6 +45,7 @@ static void update_sink_info(pa_context *c, const pa_sink_info *info, int eol, v
static void pulse_source_info_callback(pa_context *c, const pa_source_info *i, int eol, void *userdata);
static void destroy_sink_info(void *value);
static gboolean determine_sink_availability();
+static void reconnect_to_pulse();
/**
@@ -65,14 +65,19 @@ void establish_pulse_activities(SoundServiceDbus *service)
g_assert(pulse_context);
sink_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, destroy_sink_info);
+
// Establish event callback registration
pa_context_set_state_callback(pulse_context, context_state_callback, NULL);
- pa_context_connect(pulse_context, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL);
+ // BUILD MENU ANYWHO - it will be updated
+ update_pa_state(FALSE, FALSE, FALSE, 0);
+
+ pa_context_connect(pulse_context, NULL, PA_CONTEXT_NOFAIL, NULL);
}
void close_pulse_activites()
{
- if (pulse_context){
+ if (pulse_context != NULL){
+ g_debug("freeing the pulse context");
pa_context_unref(pulse_context);
pulse_context = NULL;
}
@@ -82,6 +87,30 @@ void close_pulse_activites()
g_debug("I just closed communication with Pulse");
}
+/**
+reconnect_to_pulse()
+In the event of Pulseaudio flapping in the wind handle gracefully without
+memory leaks !
+*/
+static void reconnect_to_pulse()
+{
+ // reset
+ if (pulse_context != NULL){
+ g_debug("freeing the pulse context");
+ pa_context_unref(pulse_context);
+ pulse_context = NULL;
+ }
+ g_hash_table_destroy(sink_hash);
+
+ // reconnect
+ pulse_context = pa_context_new(pa_glib_mainloop_get_api(pa_main_loop), "ayatana.indicator.sound");
+ g_assert(pulse_context);
+ sink_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, destroy_sink_info);
+ // Establish event callback registration
+ pa_context_set_state_callback(pulse_context, context_state_callback, NULL);
+ update_pa_state(FALSE, FALSE, FALSE, 0);
+ pa_context_connect(pulse_context, NULL, PA_CONTEXT_NOFAIL, NULL);
+}
static void destroy_sink_info(void *value)
{
@@ -186,6 +215,8 @@ Use the base volume stored in the sink struct to calculate actual linear volumes
*/
void set_sink_volume(gdouble percent)
{
+ if(pa_server_available == FALSE)
+ return;
g_debug("in the pulse manager:set_sink_volume with percent %f", percent);
if(DEFAULT_SINK_INDEX < 0)
{
@@ -474,7 +505,7 @@ static void context_state_callback(pa_context *c, void *userdata) {
g_debug("unconnected");
break;
case PA_CONTEXT_CONNECTING:
- g_debug("connecting");
+ g_debug("connecting - waiting for the server to become available");
break;
case PA_CONTEXT_AUTHORIZING:
g_debug("authorizing");
@@ -484,8 +515,8 @@ static void context_state_callback(pa_context *c, void *userdata) {
break;
case PA_CONTEXT_FAILED:
g_warning("FAILED to retrieve context - Is PulseAudio Daemon running ?");
- //Update the indicator to show PA either is not ready or has no available sink
- update_pa_state(FALSE, FALSE, TRUE, 0);
+ pa_server_available = FALSE;
+ reconnect_to_pulse();
break;
case PA_CONTEXT_TERMINATED:
g_debug("context terminated");