aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRoger Bystrøm <roger@remiss.org>2007-06-09 15:51:20 +0000
committerRoger Bystrøm <roger@remiss.org>2007-06-09 15:51:20 +0000
commitd50fc3849a0d68679ffb5db312ccb1ab645d431b (patch)
treeadd918b51c26721c64aa26e943115698a773a7c0 /src
parent50fbab086a3820f5efbd95e316077f78b130accc (diff)
downloadmpd-d50fc3849a0d68679ffb5db312ccb1ab645d431b.tar.gz
mpd-d50fc3849a0d68679ffb5db312ccb1ab645d431b.tar.xz
mpd-d50fc3849a0d68679ffb5db312ccb1ab645d431b.zip
This should resolve some of the timing issues experienced after switching from blocking to non-blocking shout api
* Wait ten seconds before declearing the shout server unreachable * Fix a state where it would never attempt to connect if it had previously failed It isn't perfect yet, but I'd like some testing on it from other setups git-svn-id: https://svn.musicpd.org/mpd/trunk@6523 09075e82-0dd4-0310-85a5-a0d7c8717e4f
Diffstat (limited to '')
-rw-r--r--src/audioOutputs/audioOutput_shout.c84
1 files changed, 76 insertions, 8 deletions
diff --git a/src/audioOutputs/audioOutput_shout.c b/src/audioOutputs/audioOutput_shout.c
index 7d93f8f85..1b235abe6 100644
--- a/src/audioOutputs/audioOutput_shout.c
+++ b/src/audioOutputs/audioOutput_shout.c
@@ -25,6 +25,7 @@
#include "../conf.h"
#include "../log.h"
#include "../pcm_utils.h"
+#include "../timer.h"
#include <string.h>
#include <time.h>
@@ -33,6 +34,7 @@
#include <vorbis/vorbisenc.h>
#define CONN_ATTEMPT_INTERVAL 60
+#define SHOUT_MAX_CONNTIME_US 10000000
static int shoutInitCount;
@@ -66,6 +68,8 @@ typedef struct _ShoutData {
time_t lastAttempt;
int last_err;
+ Timer *timer;
+
/* just a pointer to audioOutput->outAudioFormat */
AudioFormat *audioFormat;
} ShoutData;
@@ -84,6 +88,7 @@ static ShoutData *newShoutData(void)
ret->lastAttempt = 0;
ret->audioFormat = NULL;
ret->last_err = SHOUTERR_UNCONNECTED;
+ ret->timer = NULL;
return ret;
}
@@ -95,9 +100,31 @@ static void freeShoutData(ShoutData * sd)
if (sd->tag)
freeMpdTag(sd->tag);
+ if(sd->timer)
+ timer_free(sd->timer);
+
free(sd);
}
+static void myShout_startTimer(AudioOutput *audioOutput)
+{
+ ShoutData *sd;
+ sd = audioOutput->data;
+ if(sd->timer != NULL)
+ ERROR("sd->timer is not null\n");
+
+ sd->timer = timer_new(&audioOutput->inAudioFormat); // <<--?
+ timer_start(sd->timer);
+}
+
+static void myShout_endTimer(ShoutData *sd)
+{
+ if(sd->timer) {
+ timer_free(sd->timer);
+ sd->timer = NULL;
+ }
+}
+
#define checkBlockParam(name) { \
blockParam = getBlockParam(param, name); \
if (!blockParam) { \
@@ -347,6 +374,10 @@ static void myShout_closeShoutConn(ShoutData * sd)
}
}
+ if(sd->timer) {
+ myShout_endTimer(sd);
+ }
+
sd->last_err = SHOUTERR_UNCONNECTED;
sd->opened = 0;
}
@@ -443,31 +474,44 @@ static int myShout_openShoutConn(AudioOutput * audioOutput)
ShoutData *sd = (ShoutData *) audioOutput->data;
time_t t = time(NULL);
+ if(sd->last_err == SHOUTERR_BUSY)
+ sd->last_err = shout_get_connected(sd->shoutConn);
+ if(sd->last_err == SHOUTERR_BUSY)
+ return 1;
+
if (sd->connAttempts != 0 &&
+ sd->last_err != SHOUTERR_CONNECTED &&
+ sd->last_err != SHOUTERR_SUCCESS &&
(t - sd->lastAttempt) < CONN_ATTEMPT_INTERVAL) {
return -1;
}
- sd->connAttempts++;
+ sd->last_err = shout_get_connected(sd->shoutConn);
- if (sd->last_err == SHOUTERR_UNCONNECTED)
+ if (sd->last_err == SHOUTERR_UNCONNECTED) {
sd->last_err = shout_open(sd->shoutConn);
+ sd->lastAttempt = t;
+ /* start timer */
+ myShout_startTimer(audioOutput);
+ DEBUG("SHOUT: opening connection to shout server\n");
+ }
+
+ sd->connAttempts++;
+
switch (sd->last_err) {
case SHOUTERR_SUCCESS:
case SHOUTERR_CONNECTED:
+ DEBUG("SHOUT: connected!\n");
break;
case SHOUTERR_BUSY:
- sd->last_err = shout_get_connected(sd->shoutConn);
- if (sd->last_err == SHOUTERR_CONNECTED)
- break;
- return -1;
+ return 1;
default:
- sd->lastAttempt = t;
ERROR("problem opening connection to shout server %s:%i "
"(attempt %i): %s\n",
shout_get_host(sd->shoutConn),
shout_get_port(sd->shoutConn),
sd->connAttempts, shout_get_error(sd->shoutConn));
+ DEBUG("SHOUT: connection failed: %s\n", shout_get_error(sd->shoutConn));
return -1;
}
@@ -563,7 +607,31 @@ static int myShout_play(AudioOutput * audioOutput, char *playChunk, int size)
myShout_sendMetadata(sd);
if (!sd->opened) {
- if (myShout_openShoutConn(audioOutput) < 0) {
+ i = myShout_openShoutConn(audioOutput);
+ if (i == 0) {
+ myShout_endTimer(sd);
+ DEBUG("SHOUT: should be connected, ending timer\n");
+ }
+ else if(i == 1) {
+ if(!sd->timer) {
+ myShout_startTimer(audioOutput);
+ DEBUG("SHOUT: starting timer\n");
+ }
+
+ if(timer_get_runtime_us(sd->timer) > SHOUT_MAX_CONNTIME_US) {
+ DEBUG("SHOUT: giving up on getting a connection after 10s\n");
+ audioOutput->open = 0;
+ myShout_endTimer(sd);
+ return -1;
+ }
+
+ timer_add(sd->timer, size);
+ timer_sync(sd->timer);
+ return 0;
+ }
+ else {
+ DEBUG("SHOUT: giving up on trying to get a connection\n");
+ audioOutput->open = 0;
return -1;
}
}