output/httpd: bind port when output is enabled

Implement the methods enable() and disable().  Bind the HTTP port in
the enable() method, but reject all incoming connections until the
output is opened.
This commit is contained in:
Max Kellermann 2009-11-05 23:47:29 +01:00
parent 979cd5a768
commit 945287358b
3 changed files with 51 additions and 14 deletions

3
NEWS
View File

@ -28,6 +28,7 @@ ver 0.16 (20??/??/??)
- twolame: new encoder plugin based on libtwolame
* output:
- recorder: new output plugin for recording radio streams
- alsa: don't recover on CANCEL
- openal: new output plugin
- pulse: announce "media.role=music"
- pulse: renamed context to "Music Player Daemon"
@ -38,8 +39,8 @@ ver 0.16 (20??/??/??)
- jack: added option "client_name"
- jack: clear ring buffers before activating
- jack: support mono input
- httpd: bind port when output is enabled
- wildcards allowed in audio_format configuration
- alsa: don't recover on CANCEL
- consistently lock audio output objects
* mixers:
- removed support for legacy mixer configuration

View File

@ -30,10 +30,17 @@
#include <glib.h>
#include <sys/socket.h>
#include <stdbool.h>
struct httpd_client;
struct httpd_output {
/**
* True if the audio output is open and accepts client
* connections.
*/
bool open;
/**
* The configured encoder plugin.
*/

View File

@ -151,8 +151,9 @@ httpd_listen_in_event(G_GNUC_UNUSED GIOChannel *source,
fd = accept(httpd->fd, (struct sockaddr*)&sa, &sa_length);
if (fd >= 0) {
/* can we allow additional client */
if (!httpd->clients_max ||
httpd->clients_cnt < httpd->clients_max)
if (httpd->open &&
(httpd->clients_max == 0 ||
httpd->clients_cnt < httpd->clients_max))
httpd_client_add(httpd, fd);
else
close(fd);
@ -208,31 +209,56 @@ httpd_output_encoder_open(struct httpd_output *httpd,
}
static bool
httpd_output_open(void *data, struct audio_format *audio_format,
GError **error)
httpd_output_enable(void *data, GError **error_r)
{
struct httpd_output *httpd = data;
bool success;
GIOChannel *channel;
g_mutex_lock(httpd->mutex);
httpd->open = false;
/* create and set up listener socket */
httpd->fd = socket_bind_listen(PF_INET, SOCK_STREAM, 0,
(struct sockaddr *)&httpd->address,
httpd->address_size,
16, error);
if (httpd->fd < 0) {
g_mutex_unlock(httpd->mutex);
16, error_r);
if (httpd->fd < 0)
return false;
}
g_mutex_lock(httpd->mutex);
channel = g_io_channel_unix_new(httpd->fd);
httpd->source_id = g_io_add_watch(channel, G_IO_IN,
httpd_listen_in_event, httpd);
g_io_channel_unref(channel);
g_mutex_unlock(httpd->mutex);
return true;
}
static void
httpd_output_disable(void *data)
{
struct httpd_output *httpd = data;
g_mutex_lock(httpd->mutex);
g_source_remove(httpd->source_id);
close(httpd->fd);
g_mutex_unlock(httpd->mutex);
}
static bool
httpd_output_open(void *data, struct audio_format *audio_format,
GError **error)
{
struct httpd_output *httpd = data;
bool success;
g_mutex_lock(httpd->mutex);
/* open the encoder */
success = httpd_output_encoder_open(httpd, audio_format, error);
@ -249,6 +275,8 @@ httpd_output_open(void *data, struct audio_format *audio_format,
httpd->clients_cnt = 0;
httpd->timer = timer_new(audio_format);
httpd->open = true;
g_mutex_unlock(httpd->mutex);
return true;
}
@ -267,6 +295,8 @@ static void httpd_output_close(void *data)
g_mutex_lock(httpd->mutex);
httpd->open = false;
timer_free(httpd->timer);
g_list_foreach(httpd->clients, httpd_client_delete, NULL);
@ -277,9 +307,6 @@ static void httpd_output_close(void *data)
encoder_close(httpd->encoder);
g_source_remove(httpd->source_id);
close(httpd->fd);
g_mutex_unlock(httpd->mutex);
}
@ -478,6 +505,8 @@ const struct audio_output_plugin httpd_output_plugin = {
.name = "httpd",
.init = httpd_output_init,
.finish = httpd_output_finish,
.enable = httpd_output_enable,
.disable = httpd_output_disable,
.open = httpd_output_open,
.close = httpd_output_close,
.send_tag = httpd_output_tag,