[xiph-commits] r17362 - in icecast/branches/kh/icecast: . src win32
karl at svn.xiph.org
karl at svn.xiph.org
Tue Aug 3 17:59:21 PDT 2010
Author: karl
Date: 2010-08-03 17:59:21 -0700 (Tue, 03 Aug 2010)
New Revision: 17362
Modified:
icecast/branches/kh/icecast/NEWS
icecast/branches/kh/icecast/config.h.vc6
icecast/branches/kh/icecast/configure.in
icecast/branches/kh/icecast/src/admin.c
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/client.h
icecast/branches/kh/icecast/src/connection.c
icecast/branches/kh/icecast/src/flv.c
icecast/branches/kh/icecast/src/format_mp3.c
icecast/branches/kh/icecast/src/format_ogg.c
icecast/branches/kh/icecast/src/fserve.c
icecast/branches/kh/icecast/src/mpeg.c
icecast/branches/kh/icecast/src/mpeg.h
icecast/branches/kh/icecast/src/slave.c
icecast/branches/kh/icecast/src/source.c
icecast/branches/kh/icecast/src/util.c
icecast/branches/kh/icecast/src/yp.c
icecast/branches/kh/icecast/win32/icecast.dsp
icecast/branches/kh/icecast/win32/icecast2.iss
Log:
kh25. worker thread update (reduces locking), client schedule tuning, build
cleanups, a couple of odd case crash fixes
Modified: icecast/branches/kh/icecast/NEWS
===================================================================
--- icecast/branches/kh/icecast/NEWS 2010-08-03 23:23:38 UTC (rev 17361)
+++ icecast/branches/kh/icecast/NEWS 2010-08-04 00:59:21 UTC (rev 17362)
@@ -16,6 +16,27 @@
any extra tags are show in the conf/icecast.xml.dist file
+2.3.2-kh25
+. FLV clients could skip frames on a truncated write, leading to playback problems.
+. various client scheduling tunings, allows quicker reschedule when only some data
+ was written. This seems to affect win32 more than others, especially with burst
+. fix shoutcast-inline metadata bug involving a URL
+. per listener mpeg checking only verifies 1 frame as queue is already checked
+. set non-ogg intial blocksize to 1400 again, now that blocks can be more flexible
+ in size
+. filter out multiple / in requests
+. the 2.3 log archive setting wasn't handled correctly.
+. certain relay configuration (multiple addresses) could leak a file descriptor
+ on failure.
+. possible NULL pointer crash in metadata update.
+. possible sources count not decreased if relay fails.
+. fix for possible relay change restart
+. worker lock changes, now we only take the lock when adding clients. This reduces
+ some lock order complexity when moving clients around and means that no locking
+ is done for most of the time.
+. relay changes are tagged and changed by the client functions.
+. compile cleanups
+
2.3.2-kh24
. Allow for per-listener wrapping of existing mp3/aac streams when requested with
a type=.flv as a query arg. The actual trigger could be anything we want but this
Modified: icecast/branches/kh/icecast/config.h.vc6
===================================================================
--- icecast/branches/kh/icecast/config.h.vc6 2010-08-03 23:23:38 UTC (rev 17361)
+++ icecast/branches/kh/icecast/config.h.vc6 2010-08-04 00:59:21 UTC (rev 17362)
@@ -95,7 +95,7 @@
#define PACKAGE_NAME "Icecast"
/* Version number of package */
-#define VERSION "2.3.2-kh24"
+#define VERSION "2.3.2-kh25"
/* Define to the version of this package. */
#define PACKAGE_VERSION VERSION
@@ -136,6 +136,7 @@
#define vsnprintf _vsnprintf
#define getpid _getpid
#define atoll _atoi64
+#define pipe(x) _pipe(x,255,O_BINARY)
#define fseeko fseek
#define PRIdMAX "ld"
Modified: icecast/branches/kh/icecast/configure.in
===================================================================
--- icecast/branches/kh/icecast/configure.in 2010-08-03 23:23:38 UTC (rev 17361)
+++ icecast/branches/kh/icecast/configure.in 2010-08-04 00:59:21 UTC (rev 17362)
@@ -1,4 +1,4 @@
-AC_INIT([Icecast], [2.3.2-kh24], [karl at xiph.org])
+AC_INIT([Icecast], [2.3.2-kh25], [karl at xiph.org])
LT_INIT
AC_PREREQ(2.59)
Modified: icecast/branches/kh/icecast/src/admin.c
===================================================================
--- icecast/branches/kh/icecast/src/admin.c 2010-08-03 23:23:38 UTC (rev 17361)
+++ icecast/branches/kh/icecast/src/admin.c 2010-08-04 00:59:21 UTC (rev 17362)
@@ -1040,9 +1040,10 @@
COMMAND_OPTIONAL(client, "charset", charset);
plugin = source->format;
- if (source->client && strcmp (client->connection.ip, source->client->connection.ip) != 0)
- if (response == RAW && connection_check_admin_pass (client->parser) == 0)
- same_ip = 0;
+ if (source_running (source))
+ if (strcmp (client->connection.ip, source->client->connection.ip) != 0)
+ if (response == RAW && connection_check_admin_pass (client->parser) == 0)
+ same_ip = 0;
do
{
Modified: icecast/branches/kh/icecast/src/auth.c
===================================================================
--- icecast/branches/kh/icecast/src/auth.c 2010-08-03 23:23:38 UTC (rev 17361)
+++ icecast/branches/kh/icecast/src/auth.c 2010-08-04 00:59:21 UTC (rev 17362)
@@ -351,9 +351,7 @@
if (worker)
{
/* wakeup worker for new client */
- thread_mutex_lock (&worker->lock);
- thread_cond_signal (&worker->cond);
- thread_mutex_unlock (&worker->lock);
+ worker_wakeup (worker);
}
}
Modified: icecast/branches/kh/icecast/src/cfgfile.c
===================================================================
--- icecast/branches/kh/icecast/src/cfgfile.c 2010-08-03 23:23:38 UTC (rev 17361)
+++ icecast/branches/kh/icecast/src/cfgfile.c 2010-08-04 00:59:21 UTC (rev 17362)
@@ -692,11 +692,11 @@
if (config->access_log.size == 0)
config->access_log.size = old_trigger_size;
}
- if (old_archive > 0)
+ if (old_archive > -1)
{
- if (config->error_log.archive == 0)
+ if (config->error_log.archive == -1)
config->error_log.archive = old_archive;
- if (config->access_log.archive == 0)
+ if (config->access_log.archive == -1)
config->access_log.archive = old_archive;
}
return 0;
Modified: icecast/branches/kh/icecast/src/cfgfile.h
===================================================================
--- icecast/branches/kh/icecast/src/cfgfile.h 2010-08-03 23:23:38 UTC (rev 17361)
+++ icecast/branches/kh/icecast/src/cfgfile.h 2010-08-04 00:59:21 UTC (rev 17362)
@@ -178,18 +178,18 @@
typedef struct _relay_server
{
+ struct _relay_server *next, *new_details;
+ struct source_tag *source;
relay_server_master *masters;
char *username;
char *password;
char *localmount;
- struct source_tag *source;
int interval;
int mp3metadata;
int on_demand;
int running;
int cleanup;
time_t start;
- struct _relay_server *next;
} relay_server;
Modified: icecast/branches/kh/icecast/src/client.c
===================================================================
--- icecast/branches/kh/icecast/src/client.c 2010-08-03 23:23:38 UTC (rev 17361)
+++ icecast/branches/kh/icecast/src/client.c 2010-08-04 00:59:21 UTC (rev 17362)
@@ -22,12 +22,14 @@
#include <stdlib.h>
#include <string.h>
+#include <fcntl.h>
#include "thread/thread.h"
#include "avl/avl.h"
#include "httpp/httpp.h"
#include "timing/timing.h"
+#include "client.h"
#include "cfgfile.h"
#include "connection.h"
#include "refbuf.h"
@@ -39,6 +41,7 @@
#include "logging.h"
#include "slave.h"
#include "global.h"
+#include "util.h"
#undef CATMODULE
#define CATMODULE "client"
@@ -328,36 +331,28 @@
}
+/* worker mutex should be already locked */
static void worker_add_client (worker_t *worker, client_t *client)
{
- *worker->last_p = client;
- worker->last_p = &client->next_on_worker;
+ ++worker->pending_count;
+ client->next_on_worker = NULL;
+ *worker->pending_clients_tail = client;
+ worker->pending_clients_tail = &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);
+ thread_spin_lock (&dest_worker->lock);
worker_add_client (dest_worker, client);
+ thread_spin_unlock (&dest_worker->lock);
+ worker_wakeup (dest_worker);
- thread_mutex_unlock (&dest_worker->lock);
- thread_mutex_lock (&this_worker->lock);
return 1;
}
@@ -369,60 +364,139 @@
thread_rwlock_rlock (&workers_lock);
/* add client to the handler with the least number of clients */
handler = find_least_busy_handler();
- thread_mutex_lock (&handler->lock);
+ thread_spin_lock (&handler->lock);
thread_rwlock_unlock (&workers_lock);
- client->schedule_ms = handler->time_ms;
worker_add_client (handler, client);
- thread_mutex_unlock (&handler->lock);
+ thread_spin_unlock (&handler->lock);
+ worker_wakeup (handler);
}
+#ifdef _WIN32
+#define pipe_create sock_create_pipe_emulation
+#define pipe_write(A, B, C) send(A, B, C, 0)
+#define pipe_read(A,B,C) recv(A, B, C, 0)
+#else
+#define pipe_create pipe
+#define pipe_write write
+#define pipe_read read
+#endif
+static void worker_move_clients (worker_t *from)
+{
+ client_t *client = from->clients;
+
+ if (workers == NULL || from == NULL || workers->running == 0)
+ return;
+ while (client)
+ {
+ client->worker = workers;
+ client = client->next_on_worker;
+ }
+ thread_spin_lock (&workers->lock);
+ *workers->pending_clients_tail = from->clients;
+ workers->pending_clients_tail = from->last_p;
+ workers->pending_count += from->count;
+ thread_spin_unlock (&workers->lock);
+ from->count = 0;
+ from->clients = NULL;
+ from->last_p = &from->clients;
+}
+
+static void worker_add_pending_clients (worker_t *worker)
+{
+ if (worker && worker->pending_clients)
+ {
+ unsigned count;
+ thread_spin_lock (&worker->lock);
+ *worker->last_p = worker->pending_clients;
+ worker->last_p = worker->pending_clients_tail;
+ worker->count += worker->pending_count;
+ count = worker->pending_count;
+ worker->pending_clients = NULL;
+ worker->pending_clients_tail = &worker->pending_clients;
+ worker->pending_count = 0;
+ thread_spin_unlock (&worker->lock);
+ DEBUG2 ("Added %d pending clients to %p", count, worker);
+ }
+}
+
+
+static void worker_wait (worker_t *worker)
+{
+ uint64_t now = timing_get_time();
+ int ret, duration = (int)(worker->wakeup_ms - now);
+ char ca[30];
+
+ if (duration > 60000) /* make duration between 5 and 60ms */
+ duration = 60000;
+ if (duration < 3)
+ duration = 3;
+
+ ret = util_timed_wait_for_fd (worker->wakeup_fd[0], duration);
+ if (ret > 0) /* may of been several wakeup attempts */
+ pipe_read (worker->wakeup_fd[0], ca, sizeof ca);
+
+ worker_add_pending_clients (worker);
+
+ worker->time_ms = timing_get_time();
+ worker->current_time.tv_sec = worker->time_ms/1000;
+ worker->current_time.tv_nsec = worker->current_time.tv_sec - (worker->time_ms*1000);
+ worker->wakeup_ms = worker->time_ms + 60000;
+}
+
+
void *worker (void *arg)
{
worker_t *handler = arg;
client_t *client, **prevp;
long prev_count = -1;
- struct timespec wakeup_time;
handler->running = 1;
- thread_mutex_lock (&handler->lock);
- thread_get_timespec (&handler->current_time);
- handler->time_ms = THREAD_TIME_MS (&handler->current_time);
- wakeup_time = handler->current_time;
-
+ handler->wakeup_ms = (int64_t)0;
prevp = &handler->clients;
while (1)
{
- if (handler->running == 0 && handler->count == 0)
- break;
+ if (handler->running == 0)
+ {
+ handler->wakeup_ms = handler->time_ms + 50;
+ worker_add_pending_clients (handler);
+ if (handler->count == 0)
+ break;
+ worker_move_clients (handler);
+ }
if (prev_count != handler->count)
{
DEBUG2 ("%p now has %d clients", handler, handler->count);
prev_count = handler->count;
}
- thread_cond_timedwait (&handler->cond, &handler->lock, &wakeup_time);
- thread_get_timespec (&handler->current_time);
- handler->time_ms = THREAD_TIME_MS (&handler->current_time);
- handler->wakeup_ms = handler->time_ms + 60000;
+
+ worker_wait (handler);
client = handler->clients;
prevp = &handler->clients;
while (client)
{
+ if (client->worker != handler)
+ abort();
/* process client details but skip those that are not ready yet */
if (client->flags & CLIENT_ACTIVE)
{
- if (client->schedule_ms <= handler->time_ms+15)
+ if (client->schedule_ms <= handler->time_ms+10)
{
int ret;
+ client_t *nx = client->next_on_worker;
- handler->current_p = prevp;
+ client->schedule_ms = handler->time_ms;
ret = client->ops->process (client);
/* special handler, client has moved away to another worker */
if (ret > 0)
{
- client = *prevp;
+ handler->count--;
+ if (nx == NULL) /* moved last client */
+ handler->last_p = prevp;
+ *prevp = nx;
+ client = nx;
continue;
}
if (ret < 0)
@@ -446,12 +520,7 @@
prevp = &client->next_on_worker;
client = *prevp;
}
- handler->wakeup_ms += 10; /* allow a small sleep */
-
- wakeup_time.tv_sec = (long)(handler->wakeup_ms/1000);
- wakeup_time.tv_nsec = (long)((handler->wakeup_ms - (wakeup_time.tv_sec*1000))*1000000);
}
- thread_mutex_unlock (&handler->lock);
INFO0 ("shutting down");
return NULL;
}
@@ -461,8 +530,13 @@
{
worker_t *handler = calloc (1, sizeof(worker_t));
- thread_mutex_create (&handler->lock);
- thread_cond_create (&handler->cond);
+ if (pipe_create (&handler->wakeup_fd[0]) < 0)
+ {
+ ERROR0 ("pipe failed, fd limit?");
+ abort();
+ }
+ handler->pending_clients_tail = &handler->pending_clients;
+ thread_spin_create (&handler->lock);
thread_rwlock_wlock (&workers_lock);
handler->last_p = &handler->clients;
handler->next = workers;
@@ -475,8 +549,6 @@
static void worker_stop (void)
{
worker_t *handler;
- client_t *clients = NULL, **last;
- int count;
if (workers == NULL)
return;
@@ -486,45 +558,30 @@
worker_count--;
thread_rwlock_unlock (&workers_lock);
- thread_mutex_lock (&handler->lock);
handler->running = 0;
- thread_cond_signal (&handler->cond);
- thread_mutex_unlock (&handler->lock);
+ worker_wakeup (handler);
- thread_sleep (10000);
- thread_mutex_lock (&handler->lock);
- clients = handler->clients;
- last = handler->last_p;
- count = handler->count;
- thread_cond_signal (&handler->cond);
- thread_mutex_unlock (&handler->lock);
- if (clients)
- {
- if (worker_count == 0)
- WARN0 ("clients left unprocessed");
- else
- {
- thread_mutex_lock (&workers->lock);
- *workers->last_p = clients;
- workers->last_p = last;
- workers->count += count;
- thread_mutex_unlock (&workers->lock);
- }
- }
thread_join (handler->thread);
- thread_mutex_destroy (&handler->lock);
- thread_cond_destroy (&handler->cond);
+ thread_spin_destroy (&handler->lock);
+
+ sock_close (handler->wakeup_fd[1]);
+ sock_close (handler->wakeup_fd[0]);
free (handler);
}
void workers_adjust (int new_count)
{
+ INFO1 ("requested worker count %d", new_count);
while (worker_count != new_count)
{
if (worker_count < new_count)
worker_start ();
- else
+ else if (worker_count > new_count)
worker_stop ();
}
}
+void worker_wakeup (worker_t *worker)
+{
+ pipe_write (worker->wakeup_fd[1], "W", 1);
+}
Modified: icecast/branches/kh/icecast/src/client.h
===================================================================
--- icecast/branches/kh/icecast/src/client.h 2010-08-03 23:23:38 UTC (rev 17361)
+++ icecast/branches/kh/icecast/src/client.h 2010-08-04 00:59:21 UTC (rev 17362)
@@ -31,11 +31,14 @@
struct _worker_t
{
int running;
- int count;
- mutex_t lock;
- cond_t cond;
- client_t *clients;
- client_t **current_p, **last_p;
+ int count, pending_count;
+ spin_t lock;
+ int wakeup_fd[2];
+
+ client_t *pending_clients;
+ client_t **pending_clients_tail,
+ *clients;
+ client_t **last_p;
thread_type *thread;
struct timespec current_time;
uint64_t time_ms;
@@ -134,6 +137,7 @@
void client_add_worker (client_t *client);
worker_t *find_least_busy_handler (void);
void workers_adjust (int new_count);
+void worker_wakeup (worker_t *worker);
/* client flags bitmask */
Modified: icecast/branches/kh/icecast/src/connection.c
===================================================================
--- icecast/branches/kh/icecast/src/connection.c 2010-08-03 23:23:38 UTC (rev 17361)
+++ icecast/branches/kh/icecast/src/connection.c 2010-08-04 00:59:21 UTC (rev 17362)
@@ -878,7 +878,6 @@
ERROR0("Bad HTTP protocol detected");
return -1;
}
- client->schedule_ms = client->worker->time_ms + 20;
auth_check_http (client);
switch (client->parser->req_type)
{
@@ -897,8 +896,9 @@
default:
WARN0("unhandled request type from client");
client_send_400 (client, "unknown request");
+ return 0;
}
- return 0;
+ return client->ops->process(client);
}
/* invalid http request */
return -1;
Modified: icecast/branches/kh/icecast/src/flv.c
===================================================================
--- icecast/branches/kh/icecast/src/flv.c 2010-08-03 23:23:38 UTC (rev 17361)
+++ icecast/branches/kh/icecast/src/flv.c 2010-08-04 00:59:21 UTC (rev 17362)
@@ -57,7 +57,7 @@
static void flv_hdr (struct flv *flv, unsigned int len)
{
- unsigned long v = flv->prev_tagsize;
+ long v = flv->prev_tagsize;
v = flv->prev_tagsize;
flv->tag [3] = v & 0xFF;
@@ -66,21 +66,21 @@
v >>= 8;
flv->tag [1] = v & 0xFF; // assume less than 2^24
- v = len;
- flv->tag [7] = v & 0xFF;
+ v = (long)len;
+ flv->tag [7] = (unsigned char)(v & 0xFF);
v >>= 8;
- flv->tag [6] = v & 0xFF;
+ flv->tag [6] = (unsigned char)(v & 0xFF);
v >>= 8;
- flv->tag [5] = v & 0xFF;
+ flv->tag [5] = (unsigned char)(v & 0xFF);
- v = flv->prev_ms;
- flv->tag [10] = v & 0xFF;
+ v = (long)flv->prev_ms;
+ flv->tag [10] = (unsigned char)(v & 0xFF);
v >>= 8;
- flv->tag [9] = v & 0xFF;
+ flv->tag [9] = (unsigned char)(v & 0xFF);
v >>= 8;
- flv->tag [8] = v & 0xFF;
+ flv->tag [8] = (unsigned char)(v & 0xFF);
v >>= 8;
- flv->tag [11] = v & 0xFF;
+ flv->tag [11] = (unsigned char)(v & 0xFF);
}
@@ -109,7 +109,7 @@
}
memcpy (mp->raw->data + mp->raw_offset, &flv->tag[0], 16);
flv->samples += mp->sample_count;
- flv->prev_ms = (flv->samples / (mp->samplerate/1000.0)) + 0.5;
+ flv->prev_ms = (int64_t)(flv->samples / (mp->samplerate/1000.0));
// The extra byte is for the flv audio id, usually 0x2F
flv->prev_tagsize = (len + FLVHEADER + 1);
mp->raw_offset += 16;
@@ -129,7 +129,7 @@
// a single frame (headerless) follows this
memcpy (mp->raw->data + mp->raw_offset, &flv->tag[0], 17);
flv->samples += mp->sample_count;
- flv->prev_ms = (flv->samples / (mp->samplerate/1000.0)) + 0.5;
+ flv->prev_ms = (int64_t)(flv->samples / (mp->samplerate/1000.0));
// frame length + FLVHEADER + AVHEADER
flv->prev_tagsize = (len + 11 + 2);
mp->raw_offset += 17;
@@ -179,17 +179,18 @@
static int send_flv_buffer (client_t *client, struct flv *flv)
{
- int ret;
+ int ret = 0;
char *buf = flv->mpeg_sync.raw->data + flv->block_pos;
unsigned int len = flv->mpeg_sync.raw_offset - flv->block_pos;
- if (len <= 0)
- return 0;
- ret = client_send_bytes (client, buf, len);
- if (ret < (int)len)
- client->schedule_ms += 300;
- if (ret > 0)
- flv->block_pos += ret;
+ if (len > 0)
+ {
+ ret = client_send_bytes (client, buf, len);
+ if (ret < (int)len)
+ client->schedule_ms += (ret ? 20 : 150);
+ if (ret > 0)
+ flv->block_pos += ret;
+ }
if (flv->block_pos == flv->mpeg_sync.raw_offset)
flv->block_pos = flv->mpeg_sync.raw_offset = 0;
return ret;
@@ -201,11 +202,8 @@
refbuf_t *ref = client->refbuf, *scmeta = ref->associated;
mp3_client_data *client_mp3 = client->format_data;
struct flv *flv = client_mp3->specific;
- int unprocessed, ret = -1;
+ int ret;
- if (flv->block_pos)
- return send_flv_buffer (client, flv);
-
/* check for metadata updates and insert if needed */
if (flv->seen_metadata != scmeta)
{
@@ -247,15 +245,20 @@
flv->seen_metadata = ref->associated;
}
- unprocessed = mpeg_complete_frames (&flv->mpeg_sync, ref, client->pos);
- client->pos = ref->len;
- client->queue_pos += ref->len;
- if (unprocessed >= 0)
+ if (flv->mpeg_sync.raw_offset == 0)
{
- ret = send_flv_buffer (client, flv);
+ int unprocessed = mpeg_complete_frames (&flv->mpeg_sync, ref, client->pos);
+ if (unprocessed < 0)
+ return -1;
if (unprocessed > 0)
ref->len += unprocessed; /* output was truncated, so revert changes */
}
+ ret = send_flv_buffer (client, flv);
+ if (flv->mpeg_sync.raw_offset == 0)
+ {
+ client->pos = ref->len;
+ client->queue_pos += client->refbuf->len;
+ }
return ret;
}
@@ -273,11 +276,25 @@
char *ptr;
refbuf_t *buffer = refbuf_new (sizeof (struct flvmeta) + len + 30);
struct flvmeta *flvm = (struct flvmeta *)buffer->data;
+
memset (flvm, 0, sizeof (struct flvmeta));
ptr = buffer->data + sizeof (struct flvmeta);
memcpy (ptr, "\002\000\012onMetaData", 13);
memcpy (ptr+13, "\010\000\000\000\000", 5);
- flvm->meta_pos = sizeof (struct flvmeta) + 18;
+ flvm->meta_pos = 18;
+ flvm->arraylen = 0;
+
+#if 0
+ flvm->arraylen = 1;
+ memcpy (ptr+18, "\000\010duration\000", 11);
+ flvm->meta_pos += 2+8+1;
+ {
+ // 1 billion as a double, endian matters. hex 00 41 cd cd 65 00 00 00 00
+ memcpy (ptr+flvm->meta_pos, "\101\315\315\145\000\000\000\000", 8);
+ flvm->meta_pos += 8;
+ }
+#endif
+ flvm->meta_pos += sizeof (struct flvmeta);
return buffer;
}
@@ -324,6 +341,7 @@
char *ptr = client->refbuf->data;
mpeg_setup (&flv->mpeg_sync, plugin->mount);
+ mpeg_check_numframes (&flv->mpeg_sync, 1);
client_mp3->specific = flv;
bytes = snprintf (ptr, 200, "HTTP/1.0 200 OK\r\n"
Modified: icecast/branches/kh/icecast/src/format_mp3.c
===================================================================
--- icecast/branches/kh/icecast/src/format_mp3.c 2010-08-03 23:23:38 UTC (rev 17361)
+++ icecast/branches/kh/icecast/src/format_mp3.c 2010-08-04 00:59:21 UTC (rev 17362)
@@ -205,7 +205,7 @@
source_mp3->interval = -1;
free (format->charset);
format->charset = NULL;
- source_mp3->queue_block_size = 2900;
+ source_mp3->queue_block_size = 1400;
if (mount)
{
@@ -259,7 +259,7 @@
{
char *end = strstr (source_mp3->inline_url, "';");
if (end)
- len += end - source_mp3->inline_url+2;
+ len += end - source_mp3->inline_url + strlen (streamurl) + 2;
}
else if (source_mp3->url)
len += strlen (source_mp3->url) + strlen (streamurl) + 2;
@@ -300,10 +300,13 @@
if (source_mp3->inline_url)
{
char *end = strstr (source_mp3->inline_url, "';");
- int urllen = size;
- if (end) urllen = end - source_mp3->inline_url + 2;
- if (size-r > urllen)
- snprintf (p->data+r, size-r, "StreamUrl='%s';", source_mp3->inline_url+11);
+ if (end)
+ {
+ int urllen = end - source_mp3->inline_url;
+ int len = urllen + strlen("StreamUrl='") + 3;
+ if (size-r > len);
+ snprintf (p->data+r, len, "StreamUrl='%.*s';", urllen, source_mp3->inline_url);
+ }
}
else if (source_mp3->url)
{
@@ -384,14 +387,14 @@
{
client_mp3->metadata_offset += (ret - remaining);
client->flags |= CLIENT_IN_METADATA;
- client->schedule_ms += 300;
+ client->schedule_ms += 200;
}
client_mp3->since_meta_block = 0;
client->pos += remaining;
client->queue_pos += remaining;
return ret;
}
- client->schedule_ms += 300;
+ client->schedule_ms += 200;
if (ret > 0)
{
client_mp3->since_meta_block += ret;
@@ -411,7 +414,7 @@
}
if (ret > 0)
client_mp3->metadata_offset += ret;
- client->schedule_ms += 300;
+ client->schedule_ms += 200;
client->flags |= CLIENT_IN_METADATA;
return ret > 0 ? ret : 0;
@@ -427,7 +430,7 @@
mp3_client_data *client_mp3 = client->format_data;
refbuf_t *refbuf = client->refbuf;
char *buf = refbuf->data + client->pos;
- size_t len = refbuf->len - client->pos;
+ unsigned int len = refbuf->len - client->pos;
do
{
@@ -477,7 +480,7 @@
} while (0);
if (ret < 0)
- client->schedule_ms += 250;
+ client->schedule_ms += (written ? 25 : 50);
if (ret > 0)
written += ret;
return written == 0 ? -1 : written;
@@ -724,6 +727,8 @@
yp_touch (source->mount);
free (title);
source_mp3->inline_url = strstr (meta->data+1, "StreamUrl='");
+ if (source_mp3->inline_url)
+ source_mp3->inline_url += 11;
flv_meta_append (flvmeta, NULL, NULL);
meta->associated = flvmeta;
refbuf_release (source_mp3->metadata);
@@ -787,6 +792,7 @@
{
client_mp3->specific = calloc (1, sizeof(mpeg_sync));
mpeg_setup (client_mp3->specific, plugin->mount);
+ mpeg_check_numframes (client_mp3->specific, 1);
}
if (format_general_headers (plugin, client) < 0)
Modified: icecast/branches/kh/icecast/src/format_ogg.c
===================================================================
--- icecast/branches/kh/icecast/src/format_ogg.c 2010-08-03 23:23:38 UTC (rev 17361)
+++ icecast/branches/kh/icecast/src/format_ogg.c 2010-08-04 00:59:21 UTC (rev 17362)
@@ -533,7 +533,7 @@
}
if (ret < (int)len)
{
- client->schedule_ms += 250;
+ client->schedule_ms += 50;
return written ? written : -1;
}
if (client_data->pos == refbuf->len)
@@ -584,7 +584,7 @@
}
if (ret < (int)len)
- client->schedule_ms += 250;
+ client->schedule_ms += 50;
} while (0);
return written ? written : -1;
Modified: icecast/branches/kh/icecast/src/fserve.c
===================================================================
--- icecast/branches/kh/icecast/src/fserve.c 2010-08-03 23:23:38 UTC (rev 17361)
+++ icecast/branches/kh/icecast/src/fserve.c 2010-08-04 00:59:21 UTC (rev 17362)
@@ -56,6 +56,7 @@
#include "compat.h"
#include "fserve.h"
+#include "format_mp3.h"
#undef CATMODULE
#define CATMODULE "fserve"
@@ -818,6 +819,7 @@
time_t now = client->worker->current_time.tv_sec;
unsigned long secs = now - client->timer_start;
unsigned int rate = secs ? ((client->counter+1400)/secs) : 0;
+ unsigned int limit = fh->finfo.limit;
if (fserve_running == 0 || client->connection.error)
return -1;
@@ -829,7 +831,9 @@
return 0;
}
thread_mutex_lock (&fh->lock);
- if (rate >= fh->finfo.limit)
+ if (client->flags & CLIENT_WANTS_FLV) /* increase limit for flv clients as wrapping takes more space */
+ limit = (unsigned long)(limit * 1.02);
+ if (rate > limit)
{
client->schedule_ms = client->worker->time_ms + (1000*(rate - fh->finfo.limit))/fh->finfo.limit;
rate_add (fh->format->out_bitrate, 0, client->worker->time_ms);
@@ -916,10 +920,8 @@
client->schedule_ms = client->worker->time_ms;
else
{
- thread_mutex_lock (&client->worker->lock);
client->flags |= CLIENT_ACTIVE;
- thread_cond_signal (&client->worker->cond);
- thread_mutex_unlock (&client->worker->lock);
+ worker_wakeup (client->worker);
}
return 0;
}
Modified: icecast/branches/kh/icecast/src/mpeg.c
===================================================================
--- icecast/branches/kh/icecast/src/mpeg.c 2010-08-03 23:23:38 UTC (rev 17361)
+++ icecast/branches/kh/icecast/src/mpeg.c 2010-08-04 00:59:21 UTC (rev 17362)
@@ -124,11 +124,11 @@
bitrate *= 1000;
if (mp->layer == LAYER_1)
{
- frame_len = (12 * bitrate / mp->samplerate + padding) * 4; // ??
+ frame_len = (int)(12 * bitrate / mp->samplerate + padding) * 4; // ??
}
else
{
- frame_len = samples / 8 * bitrate / mp->samplerate + padding;
+ frame_len = (int)(samples / 8 * bitrate / mp->samplerate + padding);
}
}
return frame_len;
@@ -163,7 +163,7 @@
v = (p[2] << 8) + p[3],
channels_idx = (v & 0x1C0) >> 6;
int id = p[1] & 0x8;
- int checking = 4;
+ int checking = mp->check_numframes;
unsigned char *fh = p;
while (checking)
@@ -208,7 +208,7 @@
mp->ver = (p[1] & 0x18) >> 3;
if (mp->layer && version [mp->ver] && layer[mp->layer])
{
- int checking = 4;
+ int checking = mp->check_numframes;
unsigned char *fh = p;
int samplerates [4][4] = {
{ 11025, 0, 22050, 44100},
@@ -381,9 +381,16 @@
void mpeg_setup (mpeg_sync *mpsync, const char *mount)
{
memset (mpsync, 0, sizeof (mpeg_sync));
+ mpsync->check_numframes = 4;
mpsync->mount = mount;
}
+void mpeg_check_numframes (mpeg_sync *mpsync, unsigned count)
+{
+ if (count && count < 100)
+ mpsync->check_numframes = count;
+}
+
void mpeg_cleanup (mpeg_sync *mpsync)
{
if (mpsync)
Modified: icecast/branches/kh/icecast/src/mpeg.h
===================================================================
--- icecast/branches/kh/icecast/src/mpeg.h 2010-08-03 23:23:38 UTC (rev 17361)
+++ icecast/branches/kh/icecast/src/mpeg.h 2010-08-04 00:59:21 UTC (rev 17362)
@@ -32,11 +32,13 @@
int layer;
int samplerate;
int channels;
+ int check_numframes;
const char *mount;
} mpeg_sync;
void mpeg_setup (mpeg_sync *mpsync, const char *mount);
void mpeg_cleanup (mpeg_sync *mpsync);
+void mpeg_check_numframes (mpeg_sync *mpsync, unsigned count);
int mpeg_complete_frames (mpeg_sync *mp, refbuf_t *new_block, unsigned offset);
void mpeg_data_insert (mpeg_sync *mp, refbuf_t *inserted);
Modified: icecast/branches/kh/icecast/src/slave.c
===================================================================
--- icecast/branches/kh/icecast/src/slave.c 2010-08-03 23:23:38 UTC (rev 17361)
+++ icecast/branches/kh/icecast/src/slave.c 2010-08-04 00:59:21 UTC (rev 17362)
@@ -223,13 +223,13 @@
#endif
_slave_thread ();
slave_running = 0;
+ workers_adjust(0);
}
void slave_shutdown(void)
{
yp_stop();
- workers_adjust (0);
thread_rwlock_destroy (&slaves_lock);
thread_rwlock_destroy (&workers_lock);
thread_spin_destroy (&relay_start_lock);
@@ -383,24 +383,16 @@
else
INFO3 ("connecting to %s:%d for %s", server, port, relay->localmount);
- thread_mutex_unlock (&client->worker->lock);
streamsock = sock_connect_wto_bind (server, port, bind, timeout);
free (bind);
if (connection_init (con, streamsock, server) < 0)
{
WARN2 ("Failed to connect to %s:%d", server, port);
- thread_mutex_lock (&client->worker->lock);
break;
}
parser = get_relay_response (con, mount, server, ask_for_metadata, auth_header);
- thread_mutex_lock (&client->worker->lock);
- if (relay != client->shared_data) /* unusual but possible */
- {
- INFO0 ("detected relay change, retrying");
- break;
- }
if (parser == NULL)
{
ERROR4 ("Problem trying to start relay on %s (%s:%d%s)", relay->localmount,
@@ -465,6 +457,7 @@
free (auth_header);
if (parser)
httpp_destroy (parser);
+ connection_close (con);
return -1;
}
@@ -485,11 +478,6 @@
ret = open_relay_connection (client, relay, master);
thread_mutex_lock (&src->lock);
- if (relay != client->shared_data)
- {
- relay = client->shared_data; // relay data may of changed
- master = relay->masters;
- }
if (ret < 0)
continue;
@@ -510,6 +498,7 @@
relay_server *relay;
source_t *src;
int failed = 1, sources;
+ time_t start = time (NULL);
global_lock();
sources = ++global.sources;
@@ -519,7 +508,6 @@
{
ice_config_t *config = config_get_config();
- thread_mutex_lock (&client->worker->lock);
relay = client->shared_data;
src = relay->source;
@@ -541,13 +529,12 @@
failed = 0;
} while (0);
- relay = client->shared_data; // relay may of changed during open_relay
client->ops = &relay_client_ops;
client->schedule_ms = timing_get_time();
if (failed)
{
- /* failed to start, better clean up and reset */
+ /* failed to start any connection, better clean up and reset */
if (relay->on_demand)
src->flags &= ~SOURCE_ON_DEMAND;
else
@@ -556,11 +543,23 @@
INFO2 ("listener count remaining on %s is %d", src->mount, src->listeners);
src->flags &= ~SOURCE_PAUSE_LISTENERS;
thread_mutex_unlock (&src->lock);
- relay->start = client->schedule_ms/1000;
+ relay->start = (time_t)(client->schedule_ms/1000);
if (relay->on_demand)
- relay->start += 5;
+ relay->start += 3;
else
- relay->start += relay->interval;
+ {
+ if (relay->running && start - relay->start < 300)
+ {
+ INFO1 ("relay %s terminated too quickly, will restart in 30s", relay->localmount);
+ relay->start += 30;
+ }
+ else
+ relay->start += relay->interval;
+ }
+ global_lock();
+ global.sources--;
+ stats_event_args (NULL, "sources", "%d", global.sources);
+ global_unlock();
}
thread_spin_lock (&relay_start_lock);
@@ -568,8 +567,7 @@
thread_spin_unlock (&relay_start_lock);
client->flags |= CLIENT_ACTIVE;
- thread_cond_signal (&client->worker->cond);
- thread_mutex_unlock (&client->worker->lock);
+ worker_wakeup (client->worker);
return NULL;
}
@@ -612,9 +610,11 @@
client->ops = &relay_startup_ops;
if (relay->on_demand)
{
- ice_config_t *config = config_get_config();
- mount_proxy *mountinfo = config_find_mount (config, source->mount);
+ ice_config_t *config;
+ mount_proxy *mountinfo;
thread_mutex_lock (&source->lock);
+ config = config_get_config();
+ mountinfo = config_find_mount (config, source->mount);
source->flags |= SOURCE_ON_DEMAND;
source_update_settings (config, source, mountinfo);
thread_mutex_unlock (&source->lock);
@@ -685,19 +685,19 @@
if (global.running == ICE_RUNNING && relay_has_changed (relay, existing_relay))
{
- client_t *client = existing_relay->source->client;
+ source_t *source = existing_relay->source;
new = relay_copy (relay);
- thread_mutex_lock (&client->worker->lock);
- existing_relay->cleanup = 0;
- client->shared_data = new;
- new->source = existing_relay->source;
- existing_relay->source = NULL;
- new->running = 1;
- thread_mutex_unlock (&client->worker->lock);
INFO1 ("relay details changed on \"%s\", restarting", new->localmount);
+ existing_relay->new_details = new;
+ if (source && source->client)
+ {
+ /* wakeup client to change relay details */
+ client_t *client = source->client;
+ client->schedule_ms = 0;
+ worker_wakeup (client->worker);
+ }
}
- else
- *existing_p = existing_relay->next;
+ *existing_p = existing_relay->next; /* leave client to free structure */
new->next = new_list;
new_list = new;
break;
@@ -1247,10 +1247,26 @@
redirect->server, redirect->port);
}
+static relay_server *get_relay_details (client_t *client)
+{
+ relay_server *relay = client->shared_data;
+ if (relay && relay->new_details)
+ {
+ relay_server *old_details = relay;
+ INFO1 ("Detected change in relay details for %s", relay->localmount);
+ client->shared_data = relay->new_details;
+ relay->source = old_details->source;
+ old_details->source = NULL;
+ relay_free (relay);
+ relay = client->shared_data;
+ }
+ return relay;
+}
+
static int relay_read (client_t *client)
{
- relay_server *relay = client->shared_data;
+ relay_server *relay = get_relay_details (client);
source_t *source = relay->source;
int ret = -1;
@@ -1275,11 +1291,6 @@
stats_event_args (NULL, "sources", "%d", global.sources);
global_unlock();
global_reduce_bitrate_sampling (global.out_bitrate);
- if (client->worker->current_time.tv_sec - client->connection.con_time < 300)
- {
- INFO1 ("relay %s terminated quickly, will restart in 60s", relay->localmount);
- relay->start = client->worker->current_time.tv_sec + 60;
- }
connection_close (&client->connection);
}
/* don't pause listeners if relay shutting down */
@@ -1333,13 +1344,14 @@
static int relay_startup (client_t *client)
{
- relay_server *relay = client->shared_data;
+ relay_server *relay = get_relay_details (client);
if (relay->cleanup)
{
/* listeners may be still on, do a recheck */
relay->running = 0;
client->ops = &relay_client_ops;
+ client->schedule_ms += 25;
return 0;
}
if (global.running != ICE_RUNNING)
@@ -1379,7 +1391,7 @@
}
if (start_relay == 0)
{
- client->schedule_ms = client->worker->time_ms + 1000;
+ client->schedule_ms += 500;
return 0;
}
INFO1 ("Detected listeners on relay %s", relay->localmount);
@@ -1390,7 +1402,7 @@
if (relays_connecting > 3)
{
thread_spin_unlock (&relay_start_lock);
- client->schedule_ms = client->worker->time_ms + 1000;
+ client->schedule_ms += 500;
return 0;
}
relays_connecting++;
Modified: icecast/branches/kh/icecast/src/source.c
===================================================================
--- icecast/branches/kh/icecast/src/source.c 2010-08-03 23:23:38 UTC (rev 17361)
+++ icecast/branches/kh/icecast/src/source.c 2010-08-04 00:59:21 UTC (rev 17362)
@@ -427,8 +427,7 @@
{
client_t *client = source->client;
refbuf_t *refbuf = NULL;
- int skip = 1;
- int loop = 3;
+ int skip = 1, loop = 3;
time_t current = client->worker->current_time.tv_sec;
int fds = 0;
@@ -471,7 +470,7 @@
{
rate_add (source->format->in_bitrate, 0, current);
source->skip_duration += 300;
- client->schedule_ms = client->worker->time_ms + 150;
+ client->schedule_ms += 150;
thread_mutex_unlock (&source->lock);
return 0;
}
@@ -497,16 +496,15 @@
skip = 0;
break;
}
- source->skip_duration = (long)(source->skip_duration * 1.8);
+ source->skip_duration = (int)(source->skip_duration * 1.6);
if (source->skip_duration > 700)
source->skip_duration = 700;
break;
}
source->skip_duration = (long)(source->skip_duration * 0.9);
- if (source->skip_duration < 5)
+ if (source->skip_duration < 5) /* not too low or else it will not be able to increase */
source->skip_duration = 5;
- skip = 0;
source->last_read = current;
do
{
@@ -555,20 +553,20 @@
/* save stream to file */
if (source->dumpfile && source->format->write_buf_to_file)
source->format->write_buf_to_file (source, refbuf);
- client->schedule_ms = client->worker->time_ms + 5;
+ skip = 0;
}
else
{
- skip = 1;
if (client->connection.error)
{
INFO1 ("End of Stream %s", source->mount);
source->flags &= ~SOURCE_RUNNING;
+ skip = 0;
}
break;
}
loop--;
- } while (0);
+ } while (loop);
/* lets see if we have too much data in the queue */
while (source->queue_size > source->queue_size_limit ||
@@ -585,7 +583,9 @@
} while (0);
if (skip)
- client->schedule_ms = client->worker->time_ms + source->skip_duration;
+ client->schedule_ms += (source->skip_duration | 0xF);
+ else
+ client->schedule_ms += 15;
thread_mutex_unlock (&source->lock);
return 0;
}
@@ -614,7 +614,7 @@
if (source->termination_count && source->termination_count <= source->listeners)
{
DEBUG3 ("%s waiting (%lu, %lu)", source->mount, source->termination_count, source->listeners);
- client->schedule_ms = client->worker->time_ms + 200;
+ client->schedule_ms = client->worker->time_ms + 100;
}
else
{
@@ -637,7 +637,7 @@
if (client->refbuf == NULL && locate_start_on_queue (source, client) < 0)
{
- client->schedule_ms += 200;
+ client->schedule_ms += 150;
return -1;
}
refbuf = client->refbuf;
@@ -647,7 +647,7 @@
{
if (refbuf->next == NULL)
{
- client->schedule_ms = source->client->schedule_ms + 20;
+ client->schedule_ms = source->client->schedule_ms + 5;
return -1;
}
client_set_queue (client, refbuf->next);
@@ -670,8 +670,8 @@
refbuf = source->stream_data_tail;
if (client->intro_offset == -1 && (refbuf->flags & SOURCE_BLOCK_SYNC))
{
- pos = refbuf->len;
- lag = 0;
+ pos = 0;
+ lag = refbuf->len;
}
else
{
@@ -719,16 +719,14 @@
}
if (format_file_read (client, source->intro_file) < 0)
{
- client->schedule_ms = client->worker->time_ms + 1000;
if (source->stream_data_tail)
{
/* better find the right place in queue for this client */
client_set_queue (client, NULL);
client->check_buffer = source_queue_advance;
- if (client->connection.sent_bytes == 0) // no intro
- client->schedule_ms = client->worker->time_ms;
- return 0;
+ return source_queue_advance (client);
}
+ client->schedule_ms += 100;
client->intro_offset = 0; /* replay intro file */
return -1;
}
@@ -740,14 +738,18 @@
{
refbuf_t *refbuf = client->refbuf;
source_t *source = client->shared_data;
+ int ret;
if (refbuf == NULL)
{
client->check_buffer = http_source_intro;
- return -1;
+ return http_source_intro (client);
}
if (source->queue_size == 0)
+ {
+ client->schedule_ms += 500;
return -1; /* postpone processing until data on queue */
+ }
if (client->respcode == 0)
{
@@ -755,8 +757,8 @@
if (source_running (source) == 0)
{
- client->schedule_ms = client->worker->time_ms + 200;
- return 0;
+ client->schedule_ms += 200;
+ return -1;
}
if (source->format->create_client_data)
build_headers = source->format->create_client_data;
@@ -769,6 +771,7 @@
}
stats_event_inc (source->mount, "listener_connections");
}
+ ret = format_generic_write_to_client (client);
if (client->pos == refbuf->len)
{
client->check_buffer = http_source_intro;
@@ -783,9 +786,10 @@
else
client->pos = refbuf->len = 4096;
client->connection.sent_bytes = 0;
- return 0;
+ return ret;
}
- return format_generic_write_to_client (client);
+ client->schedule_ms += 200;
+ return ret;
}
@@ -847,7 +851,7 @@
static int send_listener (source_t *source, client_t *client)
{
int bytes;
- int loop = 6; /* max number of iterations in one go */
+ int loop = 10; /* max number of iterations in one go */
long total_written = 0;
int ret = 0;
@@ -863,10 +867,7 @@
move_failed = move_listener (client, &source->fallback);
thread_mutex_lock (&source->lock);
if (move_failed)
- {
source_setup_listener (source, client);
- client->schedule_ms = client->worker->time_ms + 50;
- }
source->termination_count--;
return 0;
}
@@ -880,7 +881,7 @@
client_set_queue (client, NULL);
client->ops = &listener_pause_ops;
client->flags |= CLIENT_HAS_MOVED;
- client->schedule_ms = client->worker->time_ms + 100;
+ client->schedule_ms = client->worker->time_ms + 60;
return 0;
}
return -1;
@@ -894,7 +895,8 @@
}
if (source_running (source) == 0)
{
- client->schedule_ms = client->worker->time_ms + 200;
+ DEBUG0 ("source not running, listener will wait 200ms");
+ client->schedule_ms += 200;
return 0;
}
@@ -907,7 +909,6 @@
return 1;
/* progessive slowdown if nearing max bandwidth. */
- client->schedule_ms = client->worker->time_ms;
if (global.max_rate)
{
if (throttle_sends > 2) /* exceeded limit, skip 30ms */
@@ -939,20 +940,14 @@
/* lets not send too much to one client in one go, but don't
sleep for too long if more data can be sent */
if (total_written > source->listener_send_trigger)
- {
- client->schedule_ms = client->worker->time_ms;
break;
- }
bytes = client->check_buffer (client);
if (bytes < 0)
break; /* can't write any more */
- client->schedule_ms += 40;
total_written += bytes;
loop--;
}
- if (loop == 0)
- 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;
@@ -1833,7 +1828,7 @@
return 0;
}
-/* call with the source lock heldm, but expect the lock released on exit
+/* call with the source lock held, but expect the lock released on exit
* as the listener may of changed threads and therefore lock needed to be
* released
*/
Modified: icecast/branches/kh/icecast/src/util.c
===================================================================
--- icecast/branches/kh/icecast/src/util.c 2010-08-03 23:23:38 UTC (rev 17361)
+++ icecast/branches/kh/icecast/src/util.c 2010-08-04 00:59:21 UTC (rev 17362)
@@ -343,7 +343,6 @@
ERROR0("Fatal internal logic error in util_url_unescape()");
free(decoded);
return NULL;
- break;
default:
*dst++ = src[i];
break;
@@ -375,6 +374,12 @@
return NULL;
}
+ while (1)
+ {
+ char *s = strstr (path, "//");
+ if (s == NULL) break;
+ memmove (path+1, path+2, strlen (path+2)+1);
+ }
/* We now have a full URI-decoded path. Check it for allowability */
if(verify_path(path))
return path;
Modified: icecast/branches/kh/icecast/src/yp.c
===================================================================
--- icecast/branches/kh/icecast/src/yp.c 2010-08-03 23:23:38 UTC (rev 17361)
+++ icecast/branches/kh/icecast/src/yp.c 2010-08-04 00:59:21 UTC (rev 17362)
@@ -82,6 +82,7 @@
static rwlock_t yp_lock;
static mutex_t yp_pending_lock;
+int yp_initialised;
static volatile struct yp_server *active_yps = NULL, *pending_yps = NULL;
static volatile int yp_update = 0;
@@ -243,7 +244,7 @@
ypclient.counter = 0;
ypclient.schedule_ms = 0;
ypclient.connection.error = 0;
- ypclient.flags = CLIENT_ACTIVE;
+ ypclient.flags = CLIENT_ACTIVE|CLIENT_SKIP_ACCESSLOG;
client_add_worker (&ypclient);
}
@@ -333,6 +334,7 @@
thread_rwlock_create (&yp_lock);
thread_mutex_create (&yp_pending_lock);
yp_recheck_config (config);
+ yp_initialised = 1;
}
@@ -803,11 +805,8 @@
yp_thread = NULL;
/* DEBUG0("YP thread shutdown"); */
- thread_mutex_lock (&ypclient.worker->lock);
ypclient.flags |= CLIENT_ACTIVE;
- DEBUG1 ("wakeup again in %lu secs", ypclient.counter - time(NULL));
- thread_cond_signal (&ypclient.worker->cond);
- thread_mutex_unlock (&ypclient.worker->lock);
+ worker_wakeup (ypclient.worker);
return NULL;
}
@@ -1029,6 +1028,8 @@
void yp_shutdown (void)
{
DEBUG0 ("releasing directory details");
+ if (yp_initialised == 0)
+ return;
thread_rwlock_destroy (&yp_lock);
thread_mutex_destroy (&yp_pending_lock);
@@ -1042,6 +1043,7 @@
free ((char*)server_version);
server_version = NULL;
active_yps = NULL;
+ yp_initialised = 0;
INFO0 ("YP cleanup complete");
}
@@ -1051,11 +1053,9 @@
worker_t *w = ypclient.worker;
if (w)
{
- thread_mutex_lock (&w->lock);
ypclient.connection.error = 1;
ypclient.schedule_ms = 0;
- thread_cond_signal (&w->cond);
- thread_mutex_unlock (&w->lock);
+ worker_wakeup(w);
DEBUG0 ("YP client is now stopped");
}
}
Modified: icecast/branches/kh/icecast/win32/icecast.dsp
===================================================================
--- icecast/branches/kh/icecast/win32/icecast.dsp 2010-08-03 23:23:38 UTC (rev 17361)
+++ icecast/branches/kh/icecast/win32/icecast.dsp 2010-08-04 00:59:21 UTC (rev 17362)
@@ -211,7 +211,7 @@
# End Source File
# Begin Source File
-SOURCE=\src\mpeg.c
+SOURCE=..\src\mpeg.c
# End Source File
# Begin Source File
@@ -375,7 +375,7 @@
# End Source File
# Begin Source File
-SOURCE=\src\mpeg.h
+SOURCE=..\src\mpeg.h
# End Source File
# Begin Source File
Modified: icecast/branches/kh/icecast/win32/icecast2.iss
===================================================================
--- icecast/branches/kh/icecast/win32/icecast2.iss 2010-08-03 23:23:38 UTC (rev 17361)
+++ icecast/branches/kh/icecast/win32/icecast2.iss 2010-08-04 00:59:21 UTC (rev 17362)
@@ -3,7 +3,7 @@
[Setup]
AppName=Icecast2-KH
-AppVerName=Icecast v2.3.2-kh24
+AppVerName=Icecast v2.3.2-kh25
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-kh24_setup
+OutputBaseFilename=icecast2_win32_v2.3.2-kh25_setup
WizardImageFile=icecast2logo2.bmp
WizardImageStretch=no
VersionInfoVersion=2.3.2
@@ -69,9 +69,3 @@
Filename: "{app}\icecastService.exe"; Parameters: "remove"
-
-
-
-
-
-
More information about the commits
mailing list