[xiph-commits] r16632 - in icecast/branches/kh/icecast: . src win32
karl at svn.xiph.org
karl at svn.xiph.org
Sat Oct 10 18:20:05 PDT 2009
Author: karl
Date: 2009-10-10 18:20:04 -0700 (Sat, 10 Oct 2009)
New Revision: 16632
Modified:
icecast/branches/kh/icecast/NEWS
icecast/branches/kh/icecast/config.h.vc6
icecast/branches/kh/icecast/configure.in
icecast/branches/kh/icecast/src/client.c
icecast/branches/kh/icecast/src/client.h
icecast/branches/kh/icecast/src/connection.c
icecast/branches/kh/icecast/src/format.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/source.h
icecast/branches/kh/icecast/win32/icecast2.iss
Log:
bump to kh17. fix failing relay crash case. fix flashpolcy crash case.
fix memory corruption case when moving clients between workers.
some minor timing changes
Modified: icecast/branches/kh/icecast/NEWS
===================================================================
--- icecast/branches/kh/icecast/NEWS 2009-10-10 19:54:17 UTC (rev 16631)
+++ icecast/branches/kh/icecast/NEWS 2009-10-11 01:20:04 UTC (rev 16632)
@@ -16,6 +16,13 @@
any extra tags are show in the conf/icecast.xml.dist file
+2.3.2-kh17
+. fix possible memory corruption when using multiple workers
+. a few minor timing changes, nothing major.
+. fix possible race case in multiple file handle close
+. kh16b. fix possible crash case with relay failing
+. kh16a. some fserve changes exposed a crash bug with flash clients.
+
2.3.2-kh16
. you can now fallback to file if the initial mountpont is not available as long
as there is a limit-rate set at some point within the fallback chain.
Modified: icecast/branches/kh/icecast/config.h.vc6
===================================================================
--- icecast/branches/kh/icecast/config.h.vc6 2009-10-10 19:54:17 UTC (rev 16631)
+++ icecast/branches/kh/icecast/config.h.vc6 2009-10-11 01:20:04 UTC (rev 16632)
@@ -95,7 +95,7 @@
#define PACKAGE_NAME "Icecast"
/* Version number of package */
-#define VERSION "2.3.2-kh16"
+#define VERSION "2.3.2-kh17"
/* Define to the version of this package. */
#define PACKAGE_VERSION VERSION
Modified: icecast/branches/kh/icecast/configure.in
===================================================================
--- icecast/branches/kh/icecast/configure.in 2009-10-10 19:54:17 UTC (rev 16631)
+++ icecast/branches/kh/icecast/configure.in 2009-10-11 01:20:04 UTC (rev 16632)
@@ -1,4 +1,4 @@
-AC_INIT([Icecast], [2.3.2-kh16], [karl at xiph.org])
+AC_INIT([Icecast], [2.3.2-kh17], [karl at xiph.org])
AC_PREREQ(2.59)
AC_CONFIG_SRCDIR(src/main.c)
Modified: icecast/branches/kh/icecast/src/client.c
===================================================================
--- icecast/branches/kh/icecast/src/client.c 2009-10-10 19:54:17 UTC (rev 16631)
+++ icecast/branches/kh/icecast/src/client.c 2009-10-11 01:20:04 UTC (rev 16632)
@@ -317,29 +317,37 @@
}
-void client_change_worker (client_t *client, worker_t *dest_worker)
+static void worker_add_client (worker_t *worker, client_t *client)
{
+ *worker->last_p = client;
+ worker->last_p = &client->next_on_worker;
+ client->worker = worker;
+ ++worker->count;
+ if (worker->wakeup_ms - worker->time_ms > 15)
+ thread_cond_signal (&worker->cond); /* wake thread if required */
+}
+
+
+int client_change_worker (client_t *client, worker_t *dest_worker)
+{
worker_t *this_worker = client->worker;
+ if (dest_worker->running == 0)
+ return 0;
// make sure this client list is ok
*this_worker->current_p = client->next_on_worker;
+ if (client->next_on_worker == NULL)
+ this_worker->last_p = this_worker->current_p;
this_worker->count--;
thread_mutex_unlock (&this_worker->lock);
client->next_on_worker = NULL;
thread_mutex_lock (&dest_worker->lock);
- if (dest_worker->running)
- {
- client->worker = dest_worker;
- *dest_worker->last_p = client;
- dest_worker->last_p = &client->next_on_worker;
- dest_worker->count++;
- client->flags |= CLIENT_HAS_CHANGED_THREAD;
- // make client inactive so that the destination thread does not run it straight away
- client->flags &= ~CLIENT_ACTIVE;
- }
+ worker_add_client (dest_worker, client);
+
thread_mutex_unlock (&dest_worker->lock);
thread_mutex_lock (&this_worker->lock);
+ return 1;
}
@@ -354,12 +362,7 @@
thread_rwlock_unlock (&workers_lock);
client->schedule_ms = handler->time_ms;
- *handler->last_p = client;
- handler->last_p = &client->next_on_worker;
- client->worker = handler;
- ++handler->count;
- if (handler->wakeup_ms - handler->time_ms > 15)
- thread_cond_signal (&handler->cond); /* wake thread if required */
+ worker_add_client (handler, client);
thread_mutex_unlock (&handler->lock);
}
@@ -406,13 +409,9 @@
ret = client->ops->process (client);
/* special handler, client has moved away to another worker */
- if (client->flags & CLIENT_HAS_CHANGED_THREAD)
+ if (ret > 0)
{
- client->flags &= ~CLIENT_HAS_CHANGED_THREAD;
- client->flags |= CLIENT_ACTIVE;
client = *prevp;
- if (client == NULL)
- handler->last_p = prevp;
continue;
}
if (ret < 0)
Modified: icecast/branches/kh/icecast/src/client.h
===================================================================
--- icecast/branches/kh/icecast/src/client.h 2009-10-10 19:54:17 UTC (rev 16631)
+++ icecast/branches/kh/icecast/src/client.h 2009-10-11 01:20:04 UTC (rev 16632)
@@ -131,7 +131,7 @@
int client_read_bytes (client_t *client, void *buf, unsigned len);
void client_set_queue (client_t *client, refbuf_t *refbuf);
-void client_change_worker (client_t *client, worker_t *dest_worker);
+int client_change_worker (client_t *client, worker_t *dest_worker);
void client_add_worker (client_t *client);
worker_t *find_least_busy_handler (void);
void workers_adjust (int new_count);
@@ -141,7 +141,7 @@
#define CLIENT_ACTIVE (001)
#define CLIENT_AUTHENTICATED (002)
#define CLIENT_IS_SLAVE (004)
-#define CLIENT_HAS_CHANGED_THREAD (010)
+
#define CLIENT_NO_CONTENT_LENGTH (020)
#define CLIENT_HAS_INTRO_CONTENT (040)
#define CLIENT_FORMAT_BIT (01000)
Modified: icecast/branches/kh/icecast/src/connection.c
===================================================================
--- icecast/branches/kh/icecast/src/connection.c 2009-10-10 19:54:17 UTC (rev 16631)
+++ icecast/branches/kh/icecast/src/connection.c 2009-10-11 01:20:04 UTC (rev 16632)
@@ -704,6 +704,7 @@
fb.flags = FS_NORMAL|FS_USE_ADMIN;
fb.fallback = NULL;
fb.limit = 0;
+ client->respcode = 200;
refbuf_release (refbuf);
client->shared_data = NULL;
client->check_buffer = format_generic_write_to_client;
Modified: icecast/branches/kh/icecast/src/format.c
===================================================================
--- icecast/branches/kh/icecast/src/format.c 2009-10-10 19:54:17 UTC (rev 16631)
+++ icecast/branches/kh/icecast/src/format.c 2009-10-11 01:20:04 UTC (rev 16632)
@@ -66,11 +66,20 @@
if (format == NULL)
return;
rate_free (format->in_bitrate);
+ format->in_bitrate = NULL;
rate_free (format->out_bitrate);
+ format->out_bitrate = NULL;
free (format->charset);
format->charset = NULL;
if (format->free_plugin)
format->free_plugin (format);
+ format->get_buffer = NULL;
+ format->write_buf_to_client = NULL;
+ format->write_buf_to_file = NULL;
+ format->create_client_data = NULL;
+ format->free_plugin = NULL;
+ format->set_tag = NULL;
+ format->apply_settings = NULL;
}
Modified: icecast/branches/kh/icecast/src/fserve.c
===================================================================
--- icecast/branches/kh/icecast/src/fserve.c 2009-10-10 19:54:17 UTC (rev 16631)
+++ icecast/branches/kh/icecast/src/fserve.c 2009-10-11 01:20:04 UTC (rev 16632)
@@ -188,6 +188,7 @@
static int _delete_fh (void *mapping)
{
fh_node *fh = mapping;
+ fh->refcount--;
if (fh->refcount)
WARN2 ("handle for %s has refcount %d", fh->finfo.mount, fh->refcount);
else
@@ -242,6 +243,7 @@
{
free (fh);
thread_mutex_lock (&result->lock);
+ avl_tree_unlock (fh_cache);
result->refcount++;
if (client)
{
@@ -259,7 +261,6 @@
}
}
DEBUG2 ("refcount now %d for %s", result->refcount, result->finfo.mount);
- avl_tree_unlock (fh_cache);
return result;
}
@@ -578,11 +579,11 @@
// fh must be locked before calling this
static void fh_release (fh_node *fh)
{
- fh->refcount--;
if (fh->finfo.mount[0])
DEBUG2 ("refcount now %d on %s", fh->refcount, fh->finfo.mount);
- if (fh->refcount)
+ if (fh->refcount > 1)
{
+ fh->refcount--;
thread_mutex_unlock (&fh->lock);
return;
}
@@ -592,7 +593,7 @@
thread_mutex_unlock (&fh->lock);
avl_tree_wlock (fh_cache);
thread_mutex_lock (&fh->lock);
- if (fh->refcount)
+ if (fh->refcount > 1)
thread_mutex_unlock (&fh->lock);
else
avl_delete (fh_cache, fh, _delete_fh);
@@ -732,7 +733,7 @@
if (written > 30000)
break;
}
- client->schedule_ms = client->worker->time_ms + 150;
+ client->schedule_ms = client->worker->time_ms + 100;
return 0;
}
Modified: icecast/branches/kh/icecast/src/slave.c
===================================================================
--- icecast/branches/kh/icecast/src/slave.c 2009-10-10 19:54:17 UTC (rev 16631)
+++ icecast/branches/kh/icecast/src/slave.c 2009-10-11 01:20:04 UTC (rev 16632)
@@ -1259,8 +1259,7 @@
source->flags &= ~SOURCE_RUNNING;
if (relay->on_demand && source->listeners == 0)
source->flags &= ~SOURCE_RUNNING;
- source_read (source);
- return 0;
+ return source_read (source);
}
if (relay->running && relay->enable)
{
Modified: icecast/branches/kh/icecast/src/source.c
===================================================================
--- icecast/branches/kh/icecast/src/source.c 2009-10-10 19:54:17 UTC (rev 16631)
+++ icecast/branches/kh/icecast/src/source.c 2009-10-11 01:20:04 UTC (rev 16632)
@@ -72,8 +72,8 @@
static int http_source_listener (client_t *client);
static int http_source_intro (client_t *client);
static int locate_start_on_queue (source_t *source, client_t *client);
-static void listener_change_worker (client_t *client, source_t *source);
-static void source_change_worker (source_t *source);
+static int listener_change_worker (client_t *client, source_t *source);
+static int source_change_worker (source_t *source);
static int source_client_callback (client_t *client);
#ifdef _WIN32
@@ -412,7 +412,7 @@
* and sent back, however NULL is also valid as in the case of a short
* timeout and there's no data pending.
*/
-void source_read (source_t *source)
+int source_read (source_t *source)
{
client_t *client = source->client;
refbuf_t *refbuf = NULL;
@@ -445,11 +445,10 @@
}
if (current >= source->client_stats_update)
{
- source_change_worker (source);
update_source_stats (source);
source->client_stats_update = current + source->stats_interval;
- thread_mutex_unlock (&source->lock);
- return;
+ if (source_change_worker (source))
+ return 1;
}
if (source->limit_rate)
{
@@ -486,6 +485,8 @@
source->skip_duration = 30;
else
source->skip_duration = (long)(source->skip_duration * 1.8);
+ if (source->skip_duration > 700)
+ source->skip_duration = 700;
break;
}
source->skip_duration = (long)(source->skip_duration * 0.9);
@@ -570,6 +571,7 @@
if (skip)
client->schedule_ms = client->worker->time_ms + source->skip_duration;
thread_mutex_unlock (&source->lock);
+ return 0;
}
@@ -585,7 +587,7 @@
INFO1 ("streaming duration expired on %s", source->mount);
}
if (source_running (source))
- source_read (source);
+ return source_read (source);
else
{
if ((source->flags & SOURCE_TERMINATING) == 0)
@@ -845,7 +847,8 @@
// do we migrate this listener to the same handler as the source client
if (source->client && source->client->worker != client->worker)
- listener_change_worker (client, source);
+ if (listener_change_worker (client, source))
+ return 1;
client->schedule_ms = client->worker->time_ms;
while (loop)
@@ -867,12 +870,12 @@
if (bytes < 0)
break; /* can't write any more */
- client->schedule_ms += 100;
+ client->schedule_ms += 40;
total_written += bytes;
loop--;
}
if (loop == 0)
- client->schedule_ms -= 500;
+ client->schedule_ms -= 190;
rate_add (source->format->out_bitrate, total_written, client->worker->time_ms);
global_add_bitrates (global.out_bitrate, total_written, client->worker->time_ms);
source->bytes_sent_since_update += total_written;
@@ -1852,10 +1855,11 @@
/* check to see if the source client can be moved to a less busy worker thread.
* we only move the source client, not the listeners, they will move later
*/
-void source_change_worker (source_t *source)
+int source_change_worker (source_t *source)
{
client_t *client = source->client;
worker_t *this_worker = client->worker, *worker;
+ int ret = 0;
thread_rwlock_rlock (&workers_lock);
worker = find_least_busy_handler ();
@@ -1864,22 +1868,26 @@
if (worker->count + source->listeners + 10 < client->worker->count)
{
thread_mutex_unlock (&source->lock);
- client_change_worker (client, worker);
- DEBUG2 ("moving source from %p to %p", this_worker, worker);
- thread_mutex_lock (&source->lock);
+ ret = client_change_worker (client, worker);
+ if (ret)
+ DEBUG2 ("moving source from %p to %p", this_worker, worker);
+ else
+ thread_mutex_lock (&source->lock);
}
}
thread_rwlock_unlock (&workers_lock);
+ return ret;
}
/* move listener client to worker theread that the source is on. This will
* help cache but prevent overloading a single worker with many listeners.
*/
-void listener_change_worker (client_t *client, source_t *source)
+int listener_change_worker (client_t *client, source_t *source)
{
worker_t *this_worker = client->worker, *dest_worker;
long diff;
+ int ret = 0;
thread_rwlock_rlock (&workers_lock);
dest_worker = source->client->worker;
@@ -1888,10 +1896,13 @@
if (diff < 1000 && this_worker != dest_worker)
{
thread_mutex_unlock (&source->lock);
- client_change_worker (client, dest_worker);
- DEBUG2 ("moving listener from %p to %p", this_worker, dest_worker);
- thread_mutex_lock (&source->lock);
+ ret = client_change_worker (client, dest_worker);
+ if (ret)
+ DEBUG2 ("moving listener from %p to %p", this_worker, dest_worker);
+ else
+ thread_mutex_lock (&source->lock);
}
thread_rwlock_unlock (&workers_lock);
+ return ret;
}
Modified: icecast/branches/kh/icecast/src/source.h
===================================================================
--- icecast/branches/kh/icecast/src/source.h 2009-10-10 19:54:17 UTC (rev 16631)
+++ icecast/branches/kh/icecast/src/source.h 2009-10-11 01:20:04 UTC (rev 16632)
@@ -106,7 +106,7 @@
void source_main(source_t *source);
void source_recheck_mounts (int update_all);
int source_add_listener (const char *mount, mount_proxy *mountinfo, client_t *client);
-void source_read (source_t *source);
+int source_read (source_t *source);
void source_setup_listener (source_t *source, client_t *client);
void source_init (source_t *source);
void source_shutdown (source_t *source, int with_fallback);
Modified: icecast/branches/kh/icecast/win32/icecast2.iss
===================================================================
--- icecast/branches/kh/icecast/win32/icecast2.iss 2009-10-10 19:54:17 UTC (rev 16631)
+++ icecast/branches/kh/icecast/win32/icecast2.iss 2009-10-11 01:20:04 UTC (rev 16632)
@@ -3,7 +3,7 @@
[Setup]
AppName=Icecast2-KH
-AppVerName=Icecast v2.3.2-kh16
+AppVerName=Icecast v2.3.2-kh17
AppPublisherURL=http://www.icecast.org
AppSupportURL=http://www.icecast.org
AppUpdatesURL=http://www.icecast.org
@@ -13,10 +13,10 @@
LicenseFile=..\COPYING
InfoAfterFile=..\README
OutputDir=.
-OutputBaseFilename=icecast2_win32_v2.3.2-kh16_setup
+OutputBaseFilename=icecast2_win32_v2.3.2-kh17_setup
WizardImageFile=icecast2logo2.bmp
WizardImageStretch=no
-VersionInfoProductVersion=kh16
+VersionInfoProductVersion=kh17
VersionInfoVersion=2.3.2
; uncomment the following line if you want your installation to run on NT 3.51 too.
; MinVersion=4,3.51
More information about the commits
mailing list