From d50fc3849a0d68679ffb5db312ccb1ab645d431b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Bystr=C3=B8m?= Date: Sat, 9 Jun 2007 15:51:20 +0000 Subject: 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 --- src/audioOutputs/audioOutput_shout.c | 84 ++++++++++++++++++++++++++++++++---- 1 file changed, 76 insertions(+), 8 deletions(-) (limited to 'src') 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 #include @@ -33,6 +34,7 @@ #include #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; } } -- cgit v1.2.3