[xiph-commits] r17384 - in icecast/branches/kh/icecast: . src win32
karl at svn.xiph.org
karl at svn.xiph.org
Sun Sep 12 14:21:21 PDT 2010
Author: karl
Date: 2010-09-12 14:21:21 -0700 (Sun, 12 Sep 2010)
New Revision: 17384
Modified:
icecast/branches/kh/icecast/NEWS
icecast/branches/kh/icecast/config.h.vc6
icecast/branches/kh/icecast/configure.in
icecast/branches/kh/icecast/src/auth.c
icecast/branches/kh/icecast/src/cfgfile.c
icecast/branches/kh/icecast/src/cfgfile.h
icecast/branches/kh/icecast/src/client.c
icecast/branches/kh/icecast/src/connection.c
icecast/branches/kh/icecast/src/format_mp3.c
icecast/branches/kh/icecast/src/fserve.c
icecast/branches/kh/icecast/src/slave.c
icecast/branches/kh/icecast/src/source.c
icecast/branches/kh/icecast/src/stats.c
icecast/branches/kh/icecast/win32/icecast2.iss
Log:
bump for kh27. mainly down to the non-ogg metadata fix, possible race with
worker wakeup and reducing contention on stats locking.
Modified: icecast/branches/kh/icecast/NEWS
===================================================================
--- icecast/branches/kh/icecast/NEWS 2010-09-12 03:26:30 UTC (rev 17383)
+++ icecast/branches/kh/icecast/NEWS 2010-09-12 21:21:21 UTC (rev 17384)
@@ -17,6 +17,17 @@
any extra tags are show in the conf/icecast.xml.dist file
+2.3.2-kh27
+. use the tree locks instead of stats lock, this should lessen contention with many
+ stats updates, typicaly of setups with many streams.
+. rework previous non-ogg metadata short-write fix, was not complete.
+. previous non-ogg metadata fix exposed problem if file fallback used.
+. remove possible race waking up a worker, could result in crash.
+. add <max-stream-duration> to <mount> (in seconds), could even be used to cycle
+ dump files on a relay.
+. leave public setting as-is when on-demand relay stops.
+. minor legacy code cleanup
+
2.3.2-kh26
. fix possible content corruption on shoutcast metadata inserted streams if a short
send occurs during metadata sending.
Modified: icecast/branches/kh/icecast/config.h.vc6
===================================================================
--- icecast/branches/kh/icecast/config.h.vc6 2010-09-12 03:26:30 UTC (rev 17383)
+++ icecast/branches/kh/icecast/config.h.vc6 2010-09-12 21:21:21 UTC (rev 17384)
@@ -95,7 +95,7 @@
#define PACKAGE_NAME "Icecast"
/* Version number of package */
-#define VERSION "2.3.2-kh26"
+#define VERSION "2.3.2-kh27"
/* Define to the version of this package. */
#define PACKAGE_VERSION VERSION
Modified: icecast/branches/kh/icecast/configure.in
===================================================================
--- icecast/branches/kh/icecast/configure.in 2010-09-12 03:26:30 UTC (rev 17383)
+++ icecast/branches/kh/icecast/configure.in 2010-09-12 21:21:21 UTC (rev 17384)
@@ -1,4 +1,4 @@
-AC_INIT([Icecast], [2.3.2-kh26], [karl at xiph.org])
+AC_INIT([Icecast], [2.3.2-kh27], [karl at xiph.org])
LT_INIT
AC_PREREQ(2.59)
Modified: icecast/branches/kh/icecast/src/auth.c
===================================================================
--- icecast/branches/kh/icecast/src/auth.c 2010-09-12 03:26:30 UTC (rev 17383)
+++ icecast/branches/kh/icecast/src/auth.c 2010-09-12 21:21:21 UTC (rev 17384)
@@ -343,17 +343,7 @@
auth_user->handler = handler->id;
if (auth_user->process)
- {
- worker_t *worker = NULL;
- if (auth_user->client)
- worker = auth_user->client->worker;
auth_user->process (auth_user);
- if (worker)
- {
- /* wakeup worker for new client */
- worker_wakeup (worker);
- }
- }
auth_client_free (auth_user);
Modified: icecast/branches/kh/icecast/src/cfgfile.c
===================================================================
--- icecast/branches/kh/icecast/src/cfgfile.c 2010-09-12 03:26:30 UTC (rev 17383)
+++ icecast/branches/kh/icecast/src/cfgfile.c 2010-09-12 21:21:21 UTC (rev 17384)
@@ -797,6 +797,8 @@
{ "authentication", auth_get_authenticator, &mount->auth },
{ "on-connect", config_get_str, &mount->on_connect },
{ "on-disconnect", config_get_str, &mount->on_disconnect },
+ { "max-stream-duration",
+ config_get_int, &mount->max_stream_duration },
{ "max-listener-duration",
config_get_int, &mount->max_listener_duration },
{ "accesslog", _parse_accesslog, &mount->access_log },
Modified: icecast/branches/kh/icecast/src/cfgfile.h
===================================================================
--- icecast/branches/kh/icecast/src/cfgfile.h 2010-09-12 03:26:30 UTC (rev 17383)
+++ icecast/branches/kh/icecast/src/cfgfile.h 2010-09-12 21:21:21 UTC (rev 17384)
@@ -130,6 +130,7 @@
config_options_t *auth_options; /* Options for this type */
char *on_connect;
char *on_disconnect;
+ unsigned int max_stream_duration;
unsigned int max_listener_duration;
access_log access_log;
Modified: icecast/branches/kh/icecast/src/client.c
===================================================================
--- icecast/branches/kh/icecast/src/client.c 2010-09-12 03:26:30 UTC (rev 17383)
+++ icecast/branches/kh/icecast/src/client.c 2010-09-12 21:21:21 UTC (rev 17384)
@@ -416,7 +416,7 @@
int ret, duration = (int)(worker->wakeup_ms - now);
char ca[30];
- if (duration > 60000) /* make duration between 5 and 60ms */
+ if (duration > 60000) /* make duration between 3ms and 60s */
duration = 60000;
if (duration < 3)
duration = 3;
Modified: icecast/branches/kh/icecast/src/connection.c
===================================================================
--- icecast/branches/kh/icecast/src/connection.c 2010-09-12 03:26:30 UTC (rev 17383)
+++ icecast/branches/kh/icecast/src/connection.c 2010-09-12 21:21:21 UTC (rev 17384)
@@ -380,8 +380,10 @@
void connection_stats (void)
{
+ long banned_IPs = 0;
if (banned_ip.contents)
- stats_event_args (NULL, "banned_IPs", "%ld", (long)banned_ip.contents->length);
+ banned_IPs = (long)banned_ip.contents->length;
+ stats_event_args (NULL, "banned_IPs", "%ld", banned_IPs);
}
/* function to handle the re-populating of the avl tree containing IP addresses
@@ -542,6 +544,7 @@
free (ip);
}
memset (con, 0, sizeof (connection_t));
+ con->sock = SOCK_ERROR;
}
return -1;
}
Modified: icecast/branches/kh/icecast/src/format_mp3.c
===================================================================
--- icecast/branches/kh/icecast/src/format_mp3.c 2010-09-12 03:26:30 UTC (rev 17383)
+++ icecast/branches/kh/icecast/src/format_mp3.c 2010-09-12 21:21:21 UTC (rev 17384)
@@ -365,7 +365,8 @@
}
else
{
- if (associated) /* previously sent metadata does not need to be sent again */
+ /* previously sent metadata does not need to be sent again */
+ if (associated || client->flags & CLIENT_USING_BLANK_META)
{
metadata = "\0";
meta_len = 1;
@@ -392,17 +393,20 @@
ret = client_send_bytes (client, merge, remaining+meta_len);
free (merge);
- if (ret >= (int)remaining)
+ if (ret > (int)remaining)
{
/* did we write all of it? */
if (ret < (int)remaining + meta_len)
{
- client_mp3->metadata_offset += (ret - remaining);
+ client_mp3->metadata_offset = (ret - remaining);
client->flags |= CLIENT_IN_METADATA;
client->schedule_ms += 200;
}
else
+ {
client->flags &= ~CLIENT_IN_METADATA;
+ client_mp3->metadata_offset = 0;
+ }
client_mp3->since_meta_block = 0;
client->pos += remaining;
client->queue_pos += remaining;
@@ -415,7 +419,6 @@
client->pos += ret;
client->queue_pos += ret;
}
- client->flags |= CLIENT_IN_METADATA;
return ret > 0 ? ret : 0;
}
ret = client_send_bytes (client, metadata, meta_len);
@@ -461,8 +464,8 @@
ret = send_stream_metadata (client, refbuf, remaining);
if (client->flags & CLIENT_IN_METADATA)
break;
- buf += remaining;
- len -= remaining;
+ buf = refbuf->data + client->pos;
+ len = refbuf->len - client->pos;
if (ret <= (int)remaining || len > client_mp3->interval)
break;
written += ret;
@@ -862,7 +865,9 @@
else
mpeg_cleanup (client_mp3->specific);
free (client_mp3->specific);
- refbuf_release (client_mp3->associated);
+ if ((client->flags & CLIENT_USING_BLANK_META) == 0)
+ refbuf_release (client_mp3->associated);
+ client_mp3->associated = NULL;
free (client->format_data);
client->format_data = NULL;
}
Modified: icecast/branches/kh/icecast/src/fserve.c
===================================================================
--- icecast/branches/kh/icecast/src/fserve.c 2010-09-12 03:26:30 UTC (rev 17383)
+++ icecast/branches/kh/icecast/src/fserve.c 2010-09-12 21:21:21 UTC (rev 17384)
@@ -929,8 +929,9 @@
client->schedule_ms = client->worker->time_ms;
else
{
+ worker_t *worker = client->worker;
client->flags |= CLIENT_ACTIVE;
- worker_wakeup (client->worker);
+ worker_wakeup (worker); /* worker may of already processed client but make sure */
}
return 0;
}
@@ -938,13 +939,8 @@
void fserve_setup_client (client_t *client, const char *mount)
{
- fbinfo finfo;
- finfo.flags = 0;
- finfo.mount = (char *)mount;
- finfo.fallback = NULL;
- finfo.limit = 0;
client->check_buffer = format_generic_write_to_client;
- fserve_setup_client_fb (client, &finfo);
+ fserve_setup_client_fb (client, NULL);
}
Modified: icecast/branches/kh/icecast/src/slave.c
===================================================================
--- icecast/branches/kh/icecast/src/slave.c 2010-09-12 03:26:30 UTC (rev 17383)
+++ icecast/branches/kh/icecast/src/slave.c 2010-09-12 21:21:21 UTC (rev 17384)
@@ -693,8 +693,9 @@
{
/* wakeup client to change relay details */
client_t *client = source->client;
+ worker_t *worker = client->worker;
client->schedule_ms = 0;
- worker_wakeup (client->worker);
+ worker_wakeup (worker);
}
}
*existing_p = existing_relay->next; /* leave client to free structure */
Modified: icecast/branches/kh/icecast/src/source.c
===================================================================
--- icecast/branches/kh/icecast/src/source.c 2010-09-12 03:26:30 UTC (rev 17383)
+++ icecast/branches/kh/icecast/src/source.c 2010-09-12 21:21:21 UTC (rev 17384)
@@ -1025,6 +1025,8 @@
mountinfo = config_find_mount (config_get_config(), source->mount);
if (mountinfo)
{
+ if (mountinfo->max_stream_duration)
+ source->client->connection.discon_time = source->client->worker->current_time.tv_sec + mountinfo->max_stream_duration;
if (mountinfo->on_connect)
source_run_script (mountinfo->on_connect, source->mount);
auth_stream_start (mountinfo, source->mount);
@@ -1188,7 +1190,7 @@
/* handle header from icecast v2 release */
str = httpp_getvar (parser, "icy-public");
if (str) break;
- str = "0";
+ str = source->yp_public > 0 ? "1" : "0";
} while (0);
val = atoi (str);
}
@@ -1565,7 +1567,7 @@
node = avl_get_first (source->clients);
while (node)
- {
+ {
client_t *existing_client = (client_t *)node->key;
if (existing_client->username &&
strcmp (existing_client->username, client->username) == 0)
Modified: icecast/branches/kh/icecast/src/stats.c
===================================================================
--- icecast/branches/kh/icecast/src/stats.c 2010-09-12 03:26:30 UTC (rev 17383)
+++ icecast/branches/kh/icecast/src/stats.c 2010-09-12 21:21:21 UTC (rev 17384)
@@ -121,7 +121,6 @@
static void process_event (stats_event_t *event);
static void _add_stats_to_stats_client (client_t *client, const char *fmt, va_list ap);
static void stats_listener_send (int flags, const char *fmt, ...);
-static void process_event_unlocked (stats_event_t *event);
unsigned int throttle_sends;
@@ -450,6 +449,7 @@
{
stats_node_t *node = NULL;
+ avl_tree_wlock (_stats.global_tree);
/* DEBUG3("global event %s %s %d", event->name, event->value, event->action); */
if (event->action == STATS_EVENT_REMOVE)
{
@@ -460,6 +460,7 @@
stats_listener_send (node->flags, "DELETE global %s\n", event->name);
avl_delete(_stats.global_tree, (void *)node, _free_stats);
}
+ avl_tree_unlock (_stats.global_tree);
return;
}
node = _find_node(_stats.global_tree, event->name);
@@ -480,6 +481,7 @@
avl_insert(_stats.global_tree, (void *)node);
stats_listener_send (node->flags, "EVENT global %s %s\n", event->name, event->value);
}
+ avl_tree_unlock (_stats.global_tree);
}
@@ -488,13 +490,18 @@
stats_source_t *snode = _find_source(_stats.source_tree, event->source);
stats_node_t *node = NULL;
+ avl_tree_wlock (_stats.source_tree);
+ snode = _find_source(_stats.source_tree, event->source);
if (snode == NULL)
{
if (event->action == STATS_EVENT_REMOVE)
+ {
+ avl_tree_unlock (_stats.source_tree);
return;
+ }
snode = (stats_source_t *)calloc(1,sizeof(stats_source_t));
if (snode == NULL)
- return;
+ abort();
DEBUG1 ("new source stat %s", event->source);
snode->source = (char *)strdup(event->source);
snode->stats_tree = avl_tree_new(_compare_stats, NULL);
@@ -502,15 +509,21 @@
avl_insert(_stats.source_tree, (void *)snode);
}
+ if (event->action == STATS_EVENT_REMOVE)
+ {
+ avl_delete(_stats.source_tree, (void *)snode, _free_source_stats);
+ avl_tree_unlock (_stats.source_tree);
+ return;
+ }
+ avl_tree_wlock (snode->stats_tree);
+ avl_tree_unlock (_stats.source_tree);
if (event->name)
{
node = _find_node (snode->stats_tree, event->name);
if (node == NULL)
{
- if (event->action == STATS_EVENT_REMOVE)
- return;
/* adding node */
- if (event->value)
+ if (event->action != STATS_EVENT_REMOVE && event->value)
{
DEBUG3 ("new node on %s \"%s\" (%s)", event->source, event->name, event->value);
node = (stats_node_t *)calloc(1,sizeof(stats_node_t));
@@ -522,6 +535,7 @@
stats_listener_send (node->flags, "EVENT %s %s %s\n", event->source, event->name, event->value);
avl_insert(snode->stats_tree, (void *)node);
}
+ avl_tree_unlock (snode->stats_tree);
return;
}
if (event->action == STATS_EVENT_REMOVE)
@@ -529,10 +543,12 @@
DEBUG1 ("delete node %s", event->name);
stats_listener_send (node->flags, "DELETE %s %s\n", event->source, event->name);
avl_delete(snode->stats_tree, (void *)node, _free_stats);
+ avl_tree_unlock (snode->stats_tree);
return;
}
modify_node_event (node, event);
stats_listener_send (node->flags, "EVENT %s %s %s\n", event->source, node->name, node->value);
+ avl_tree_unlock (snode->stats_tree);
return;
}
/* change source flags status */
@@ -542,7 +558,10 @@
int visible = 0;
if ((event->flags&STATS_HIDDEN) == (snode->flags&STATS_HIDDEN))
+ {
+ avl_tree_unlock (snode->stats_tree);
return;
+ }
if (snode->flags & STATS_HIDDEN)
{
snode->flags &= ~STATS_HIDDEN;
@@ -566,10 +585,10 @@
stats->flags |= STATS_HIDDEN;
node = avl_get_next (node);
}
+ avl_tree_unlock (snode->stats_tree);
return;
}
- if (event->action == STATS_EVENT_REMOVE)
- avl_delete(_stats.source_tree, (void *)snode, _free_source_stats);
+ avl_tree_unlock (snode->stats_tree);
}
@@ -702,8 +721,10 @@
#endif
}
-static void process_event_unlocked (stats_event_t *event)
+static void process_event (stats_event_t *event)
{
+ if (event == NULL)
+ return;
/* check if we are dealing with a global or source event */
if (event->source == NULL)
process_global_event (event);
@@ -711,16 +732,7 @@
process_source_event (event);
}
-static void process_event (stats_event_t *event)
-{
- if (event == NULL)
- return;
- thread_mutex_lock (&_stats_mutex);
- process_event_unlocked (event);
- thread_mutex_unlock (&_stats_mutex);
-}
-
static int _append_to_bufferv (refbuf_t *refbuf, int max_len, const char *fmt, va_list ap)
{
char *buf = (char*)refbuf->data + refbuf->len;
@@ -806,8 +818,8 @@
avl_node *avlnode;
xmlNodePtr ret = NULL;
- thread_mutex_lock(&_stats_mutex);
/* general stats first */
+ avl_tree_rlock (_stats.global_tree);
avlnode = avl_get_first(_stats.global_tree);
while (avlnode)
{
@@ -816,7 +828,9 @@
xmlNewTextChild (root, NULL, XMLSTR(stat->name), XMLSTR(stat->value));
avlnode = avl_get_next (avlnode);
}
+ avl_tree_unlock (_stats.global_tree);
/* now per mount stats */
+ avl_tree_rlock (_stats.source_tree);
avlnode = avl_get_first(_stats.source_tree);
while (avlnode)
{
@@ -824,8 +838,10 @@
if (((flags&STATS_HIDDEN) || (source->flags&STATS_HIDDEN) == (flags&STATS_HIDDEN)) &&
(show_mount == NULL || strcmp (show_mount, source->source) == 0))
{
- avl_node *avlnode2 = avl_get_first (source->stats_tree);
+ avl_node *avlnode2;
xmlNodePtr xmlnode = xmlNewTextChild (root, NULL, XMLSTR("source"), NULL);
+ avl_tree_rlock (source->stats_tree);
+ avlnode2 = avl_get_first (source->stats_tree);
xmlSetProp (xmlnode, XMLSTR("mount"), XMLSTR(source->source));
if (ret == NULL)
@@ -837,10 +853,11 @@
xmlNewTextChild (xmlnode, NULL, XMLSTR(stat->name), XMLSTR(stat->value));
avlnode2 = avl_get_next (avlnode2);
}
+ avl_tree_unlock (source->stats_tree);
}
avlnode = avl_get_next (avlnode);
}
- thread_mutex_unlock(&_stats_mutex);
+ avl_tree_unlock (_stats.source_tree);
return ret;
}
@@ -859,7 +876,7 @@
build_event (&stats_count, NULL, "stats_connections", buffer);
stats_count.action = STATS_EVENT_INC;
- process_event_unlocked (&stats_count);
+ process_event (&stats_count);
/* first we fill our queue with the current stats */
refbuf = refbuf_new (size);
@@ -943,7 +960,7 @@
client_destroy (client);
build_event (&stats_count, NULL, "stats_connections", buffer);
stats_count.action = STATS_EVENT_DEC;
- process_event_unlocked (&stats_count);
+ process_event (&stats_count);
return;
}
trail = &listener->next;
@@ -1096,7 +1113,7 @@
prelen = strlen (pre);
/* now the stats for each source */
- thread_mutex_lock (&_stats_mutex);
+ avl_tree_rlock (_stats.source_tree);
node = avl_get_first(_stats.source_tree);
while (node)
{
@@ -1122,7 +1139,7 @@
}
node = avl_get_next(node);
}
- thread_mutex_unlock (&_stats_mutex);
+ avl_tree_unlock (_stats.source_tree);
cur->len = STREAMLIST_BLKSIZE - remaining;
return start;
}
@@ -1137,7 +1154,7 @@
{
avl_node *snode;
- thread_mutex_lock (&_stats_mutex);
+ avl_tree_wlock (_stats.source_tree);
snode = avl_get_first(_stats.source_tree);
while (snode)
{
@@ -1158,7 +1175,7 @@
snode = avl_get_next (snode);
}
- thread_mutex_unlock (&_stats_mutex);
+ avl_tree_unlock (_stats.source_tree);
}
@@ -1182,12 +1199,12 @@
build_event (&event, NULL, "outgoing_kbitrate", buffer);
event.flags = STATS_COUNTERS|STATS_HIDDEN;
- thread_mutex_lock (&_stats_mutex);
snprintf (buffer, sizeof(buffer), "%" PRIu64,
(int64_t)global_getrate_avg (global.out_bitrate) * 8 / 1024);
- process_event_unlocked (&event);
+ process_event (&event);
/* retrieve the list of closing down clients */
+ thread_mutex_lock (&_stats_mutex);
listener = _stats.listeners_removed;
_stats.listeners_removed = NULL;
thread_mutex_unlock (&_stats_mutex);
Modified: icecast/branches/kh/icecast/win32/icecast2.iss
===================================================================
--- icecast/branches/kh/icecast/win32/icecast2.iss 2010-09-12 03:26:30 UTC (rev 17383)
+++ icecast/branches/kh/icecast/win32/icecast2.iss 2010-09-12 21:21:21 UTC (rev 17384)
@@ -3,7 +3,7 @@
[Setup]
AppName=Icecast2-KH
-AppVerName=Icecast v2.3.2-kh26
+AppVerName=Icecast v2.3.2-kh27
AppPublisherURL=http://www.icecast.org
AppSupportURL=http://www.icecast.org
AppUpdatesURL=http://www.icecast.org
@@ -13,7 +13,7 @@
LicenseFile=..\COPYING
InfoAfterFile=..\README
OutputDir=.
-OutputBaseFilename=icecast2_win32_v2.3.2-kh26
+OutputBaseFilename=icecast2_win32_v2.3.2-kh27_setup
WizardImageFile=icecast2logo2.bmp
WizardImageStretch=no
VersionInfoVersion=2.3.2
More information about the commits
mailing list