output/httpd: move code to methods Delay(), Play(), Cancel()

This commit is contained in:
Max Kellermann 2013-12-31 17:01:08 +01:00
parent e2425592b6
commit 69a9d29190
2 changed files with 46 additions and 22 deletions

View File

@ -213,6 +213,9 @@ struct HttpdOutput final : private ServerSocket {
*/ */
void SendHeader(HttpdClient &client) const; void SendHeader(HttpdClient &client) const;
gcc_pure
unsigned Delay() const;
/** /**
* Reads data from the encoder (as much as available) and * Reads data from the encoder (as much as available) and
* returns it as a new #page object. * returns it as a new #page object.
@ -235,6 +238,10 @@ struct HttpdOutput final : private ServerSocket {
void SendTag(const Tag *tag); void SendTag(const Tag *tag);
size_t Play(const void *chunk, size_t size, Error &error);
void CancelAllClients();
private: private:
virtual void OnAccept(int fd, const sockaddr &address, virtual void OnAccept(int fd, const sockaddr &address,
size_t address_length, int uid) override; size_t address_length, int uid) override;

View File

@ -361,17 +361,15 @@ HttpdOutput::SendHeader(HttpdClient &client) const
client.PushPage(header); client.PushPage(header);
} }
static unsigned inline unsigned
httpd_output_delay(struct audio_output *ao) HttpdOutput::Delay() const
{ {
HttpdOutput *httpd = HttpdOutput::Cast(ao); if (!LockHasClients() && base.pause) {
if (!httpd->LockHasClients() && httpd->base.pause) {
/* if there's no client and this output is paused, /* if there's no client and this output is paused,
then httpd_output_pause() will not do anything, it then httpd_output_pause() will not do anything, it
will not fill the buffer and it will not update the will not fill the buffer and it will not update the
timer; therefore, we reset the timer here */ timer; therefore, we reset the timer here */
httpd->timer->Reset(); timer->Reset();
/* some arbitrary delay that is long enough to avoid /* some arbitrary delay that is long enough to avoid
consuming too much CPU, and short enough to notice consuming too much CPU, and short enough to notice
@ -379,11 +377,19 @@ httpd_output_delay(struct audio_output *ao)
return 1000; return 1000;
} }
return httpd->timer->IsStarted() return timer->IsStarted()
? httpd->timer->GetDelay() ? timer->GetDelay()
: 0; : 0;
} }
static unsigned
httpd_output_delay(struct audio_output *ao)
{
HttpdOutput *httpd = HttpdOutput::Cast(ao);
return httpd->Delay();
}
void void
HttpdOutput::BroadcastPage(Page *page) HttpdOutput::BroadcastPage(Page *page)
{ {
@ -426,22 +432,28 @@ HttpdOutput::EncodeAndPlay(const void *chunk, size_t size, Error &error)
return true; return true;
} }
inline size_t
HttpdOutput::Play(const void *chunk, size_t size, Error &error)
{
if (LockHasClients()) {
if (!EncodeAndPlay(chunk, size, error))
return 0;
}
if (!timer->IsStarted())
timer->Start();
timer->Add(size);
return size;
}
static size_t static size_t
httpd_output_play(struct audio_output *ao, const void *chunk, size_t size, httpd_output_play(struct audio_output *ao, const void *chunk, size_t size,
Error &error) Error &error)
{ {
HttpdOutput *httpd = HttpdOutput::Cast(ao); HttpdOutput *httpd = HttpdOutput::Cast(ao);
if (httpd->LockHasClients()) { return httpd->Play(chunk, size, error);
if (!httpd->EncodeAndPlay(chunk, size, error))
return 0;
}
if (!httpd->timer->IsStarted())
httpd->timer->Start();
httpd->timer->Add(size);
return size;
} }
static bool static bool
@ -515,14 +527,19 @@ httpd_output_tag(struct audio_output *ao, const Tag *tag)
httpd->SendTag(tag); httpd->SendTag(tag);
} }
inline void
HttpdOutput::CancelAllClients()
{
const ScopeLock protect(mutex);
for (auto &client : clients)
client.CancelQueue();
}
static void static void
httpd_output_cancel(struct audio_output *ao) httpd_output_cancel(struct audio_output *ao)
{ {
HttpdOutput *httpd = HttpdOutput::Cast(ao); HttpdOutput *httpd = HttpdOutput::Cast(ao);
httpd->CancelAllClients();
const ScopeLock protect(httpd->mutex);
for (auto &client : httpd->clients)
client.CancelQueue();
} }
const struct audio_output_plugin httpd_output_plugin = { const struct audio_output_plugin httpd_output_plugin = {