[xiph-cvs] cvs commit: icecast/src event.c event.h Makefile.am config.c config.h configtest.c connection.c connection.h fserve.c main.c sighandler.c slave.c source.c util.c yp.c

Michael Smith msmith at xiph.org
Wed Mar 5 05:03:36 PST 2003



msmith      03/03/05 08:03:35

  Modified:    .        TODO
               src      Makefile.am config.c config.h configtest.c
                        connection.c connection.h fserve.c main.c
                        sighandler.c slave.c source.c util.c yp.c
  Added:       .        News
               src      event.c event.h
  Removed:     .        ChangeLog
  Log:
  Allow rereading config files.
  Lots of new locking happening so that it's safe to have the config file
  disappear under the rest of the program
  
  Does NOT affect currently-running sources at the moment

Revision  Changes    Path
1.11      +4 -2      icecast/TODO

Index: TODO
===================================================================
RCS file: /usr/local/cvsroot/icecast/TODO,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- TODO	24 Feb 2003 13:37:15 -0000	1.10
+++ TODO	5 Mar 2003 13:03:35 -0000	1.11
@@ -50,6 +50,8 @@
 
 - option to use ipv6 (equiv to using <bind-address>::</bindaddress>, I think.
 
-- per-mountpoint listener maximums.
-
+- abstract all admin functionality to a set of commands, and command handlers.
+  Make /admin/* just parse according to a set of rules, and dispatch generic
+  commands through that.
+  Use this for alternative admin interfaces (GUI? telnet interface?)
 

<p><p>1.1                  icecast/News

Index: News
===================================================================
2003-03-05
    Implemented the ability to reread the config file on SIGHUP. For now, this
    does not affect configuration for currently running sources (only new
    sources and global parameters like max-listeners)

2003-03-02 
    More features:	 
    -- per mountpoint listener maxima   
    -- static configuration of mountpoint fallbacks   
    -- stream dumping (write incoming stream to disk)

2003-02-27
    Fix log buffering on win32 - previously, logs were never flushed, so they
    only got output every few tens or hundreds of lines.

2003-02-27
        Support new icy-audio-info header, to communicate various parameters to
    clients and yp servers, including sample rate, quality, channels, bitrate

2003-02-25
    Full support for relaying mp3 metadata (if turned on in config file)

2003-02-25
    Allow configuration of maximum client queue length (in bytes)

2003-02-14
    Finished full IPv6 support. 

2003-02-12
        Allow configuring local mountpoint seperately from remote mountpoint for
    relays

2003-02-12
        Per mountpoint usernames and passwords (for sources)

2003-02-11
        Now that it's been officially assigned, use application/ogg instead of
        application/x-ogg

2003-02-07
    Allow relaying of mp3 streams from icecast 1.x and shoutcast

2003-02-07
    Added ability to configure individual relays (rather than just all streams
    from a single server).

2003-02-03
    Added support for YP directory services listings
        are only used by the yp listing routines

2003-02-03
    Support command line parameter -b to run in the background (not supported
    on win32)

2002-12-31 
    Implement configurable mountpoint fallbacks (on source exit, clients are
    transferred to another mountpoint automatically, without disconnecting
    them)

2002-12-31
    Implemented full mp3 metadata support.

(older stuff is missing from here)

<p><p><p>1.13      +2 -2      icecast/src/Makefile.am

Index: Makefile.am
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/Makefile.am,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- Makefile.am	2 Feb 2003 14:24:12 -0000	1.12
+++ Makefile.am	5 Mar 2003 13:03:35 -0000	1.13
@@ -8,10 +8,10 @@
 
 noinst_HEADERS = config.h os.h logging.h sighandler.h connection.h global.h\
          util.h slave.h source.h stats.h refbuf.h client.h format.h format_vorbis.h\
-	 compat.h format_mp3.h fserve.h xslt.h geturl.h yp.h
+	 compat.h format_mp3.h fserve.h xslt.h geturl.h yp.h event.h
 icecast_SOURCES = config.c main.c logging.c sighandler.c connection.c global.c\
          util.c slave.c source.c stats.c refbuf.c client.c format.c format_vorbis.c\
-	 format_mp3.c xslt.c fserve.c geturl.c yp.c
+	 format_mp3.c xslt.c fserve.c geturl.c yp.c event.c
     
 icecast_LDADD = net/libicenet.la thread/libicethread.la httpp/libicehttpp.la\
                 log/libicelog.la avl/libiceavl.la timing/libicetiming.la

<p><p>1.29      +228 -162  icecast/src/config.c

Index: config.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/config.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- config.c	2 Mar 2003 10:36:24 -0000	1.28
+++ config.c	5 Mar 2003 13:03:35 -0000	1.29
@@ -3,6 +3,8 @@
 #include <string.h>
 #include <libxml/xmlmemory.h>
 #include <libxml/parser.h>
+
+#include "thread/thread.h"
 #include "config.h"
 #include "refbuf.h"
 #include "client.h"
@@ -45,36 +47,59 @@
 #define CONFIG_DEFAULT_WEBROOT_DIR ".\\webroot"
 #endif
 
-ice_config_t _configuration;
-char *_config_filename;
+ice_config_t _current_configuration;
+ice_config_locks _locks;
+
+static void _set_defaults(ice_config_t *c);
+static void _parse_root(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
+static void _parse_limits(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
+static void _parse_directory(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
+static void _parse_paths(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
+static void _parse_logging(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
+static void _parse_security(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
+static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node, 
+        ice_config_t *c);
+static void _parse_relay(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
+static void _parse_mount(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
+static void _add_server(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
+
+static void create_locks() {
+    thread_mutex_create(&_locks.relay_lock);
+    thread_mutex_create(&_locks.mounts_lock);
+    thread_mutex_create(&_locks.config_lock);
+}
 
-static void _set_defaults(void);
-static void _parse_root(xmlDocPtr doc, xmlNodePtr node);
-static void _parse_limits(xmlDocPtr doc, xmlNodePtr node);
-static void _parse_directory(xmlDocPtr doc, xmlNodePtr node);
-static void _parse_paths(xmlDocPtr doc, xmlNodePtr node);
-static void _parse_logging(xmlDocPtr doc, xmlNodePtr node);
-static void _parse_security(xmlDocPtr doc, xmlNodePtr node);
-static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node);
-static void _parse_relay(xmlDocPtr doc, xmlNodePtr node);
-static void _parse_mount(xmlDocPtr doc, xmlNodePtr node);
-static void _add_server(xmlDocPtr doc, xmlNodePtr node);
-
-void config_initialize(void)
-{
-	memset(&_configuration, 0, sizeof(ice_config_t));
-	_set_defaults();
-	_config_filename = NULL;
+static void release_locks() {
+    thread_mutex_destroy(&_locks.relay_lock);
+    thread_mutex_destroy(&_locks.mounts_lock);
+    thread_mutex_destroy(&_locks.config_lock);
 }
 
-void config_shutdown(void)
+void config_initialize(void) {
+    create_locks();
+}
+
+void config_shutdown(void) {
+    config_get_config();
+    config_clear(&_current_configuration);
+    config_release_config();
+    release_locks();
+}
+
+void config_init_configuration(ice_config_t *configuration)
+{
+	memset(configuration, 0, sizeof(ice_config_t));
+	_set_defaults(configuration);
+}
+
+void config_clear(ice_config_t *c)
 {
         ice_config_dir_t *dirnode, *nextdirnode;
-    ice_config_t *c = &_configuration;
     relay_server *relay, *nextrelay;
     mount_proxy *mount, *nextmount;
 
-	if (_config_filename) free(_config_filename);
+    if (c->config_filename)
+        free(c->config_filename);
 
         if (c->location && c->location != CONFIG_DEFAULT_LOCATION) 
         xmlFree(c->location);
@@ -105,7 +130,9 @@
     if (c->master_password) xmlFree(c->master_password);
     if (c->user) xmlFree(c->user);
     if (c->group) xmlFree(c->group);
-    relay = _configuration.relay;
+
+    thread_mutex_lock(&(_locks.relay_lock));
+    relay = c->relay;
     while(relay) {
         nextrelay = relay->next;
         xmlFree(relay->server);
@@ -115,7 +142,10 @@
         free(relay);
         relay = nextrelay;
     }
-    mount = _configuration.mounts;
+    thread_mutex_unlock(&(_locks.relay_lock));
+
+    thread_mutex_lock(&(_locks.mounts_lock));
+    mount = c->mounts;
     while(mount) {
         nextmount = mount->next;
         xmlFree(mount->mountname);
@@ -126,7 +156,9 @@
         free(mount);
         mount = nextmount;
     }
-    dirnode = _configuration.dir_list;
+    thread_mutex_unlock(&(_locks.mounts_lock));
+
+    dirnode = c->dir_list;
     while(dirnode) {
         nextdirnode = dirnode->next;
         xmlFree(dirnode->host);
@@ -137,17 +169,21 @@
     memset(c, 0, sizeof(ice_config_t));
 }
 
-int config_parse_file(const char *filename)
+int config_initial_parse_file(const char *filename)
+{
+    /* Since we're already pointing at it, we don't need to copy it in place */
+    return config_parse_file(filename, &_current_configuration);
+}
+
+int config_parse_file(const char *filename, ice_config_t *configuration)
 {
         xmlDocPtr doc;
         xmlNodePtr node;
 
         if (filename == NULL || strcmp(filename, "") == 0) return CONFIG_EINSANE;
         
-	_config_filename = (char *)strdup(filename);
-
     xmlInitParser();
-	doc = xmlParseFile(_config_filename);
+	doc = xmlParseFile(filename);
         if (doc == NULL) {
                 return CONFIG_EPARSE;
         }
@@ -165,7 +201,11 @@
                 return CONFIG_EBADROOT;
         }
 
-	_parse_root(doc, node->xmlChildrenNode);
+    config_init_configuration(configuration);
+
+	configuration->config_filename = (char *)strdup(filename);
+
+	_parse_root(doc, node->xmlChildrenNode, configuration);
 
         xmlFreeDoc(doc);
     xmlCleanupParser();
@@ -178,54 +218,71 @@
         return 0;
 }
 
-int config_rehash(void)
+ice_config_locks *config_locks(void)
 {
-	return 0;
+    return &_locks;
 }
 
-ice_config_t *config_get_config(void)
+void config_release_config(void)
 {
-	return &_configuration;
+    thread_mutex_unlock(&(_locks.config_lock));
 }
 
-static void _set_defaults(void)
+ice_config_t *config_get_config(void)
 {
-	_configuration.location = CONFIG_DEFAULT_LOCATION;
-	_configuration.admin = CONFIG_DEFAULT_ADMIN;
-	_configuration.client_limit = CONFIG_DEFAULT_CLIENT_LIMIT;
-	_configuration.source_limit = CONFIG_DEFAULT_SOURCE_LIMIT;
-	_configuration.queue_size_limit = CONFIG_DEFAULT_QUEUE_SIZE_LIMIT;
-	_configuration.threadpool_size = CONFIG_DEFAULT_THREADPOOL_SIZE;
-	_configuration.client_timeout = CONFIG_DEFAULT_CLIENT_TIMEOUT;
-	_configuration.header_timeout = CONFIG_DEFAULT_HEADER_TIMEOUT;
-	_configuration.source_timeout = CONFIG_DEFAULT_SOURCE_TIMEOUT;
-	_configuration.source_password = CONFIG_DEFAULT_SOURCE_PASSWORD;
-	_configuration.relay_password = CONFIG_DEFAULT_RELAY_PASSWORD;
-	_configuration.ice_login = CONFIG_DEFAULT_ICE_LOGIN;
-	_configuration.fileserve = CONFIG_DEFAULT_FILESERVE;
-	_configuration.touch_interval = CONFIG_DEFAULT_TOUCH_FREQ;
-	_configuration.dir_list = NULL;
-	_configuration.hostname = CONFIG_DEFAULT_HOSTNAME;
-	_configuration.port = CONFIG_DEFAULT_PORT;
-	_configuration.bind_address = NULL;
-	_configuration.master_server = NULL;
-	_configuration.master_server_port = CONFIG_DEFAULT_PORT;
-    _configuration.master_update_interval = CONFIG_MASTER_UPDATE_INTERVAL;
-	_configuration.master_password = NULL;
-	_configuration.base_dir = CONFIG_DEFAULT_BASE_DIR;
-	_configuration.log_dir = CONFIG_DEFAULT_LOG_DIR;
-    _configuration.webroot_dir = CONFIG_DEFAULT_WEBROOT_DIR;
-	_configuration.access_log = CONFIG_DEFAULT_ACCESS_LOG;
-	_configuration.error_log = CONFIG_DEFAULT_ERROR_LOG;
-	_configuration.loglevel = CONFIG_DEFAULT_LOG_LEVEL;
-    _configuration.chroot = CONFIG_DEFAULT_CHROOT;
-    _configuration.chuid = CONFIG_DEFAULT_CHUID;
-    _configuration.user = CONFIG_DEFAULT_USER;
-    _configuration.group = CONFIG_DEFAULT_GROUP;
-    _configuration.num_yp_directories = 0;
+    thread_mutex_lock(&(_locks.config_lock));
+	return &_current_configuration;
+}
+
+/* MUST be called with the lock held! */
+void config_set_config(ice_config_t *config) {
+    memcpy(&_current_configuration, config, sizeof(ice_config_t));
+}
+
+ice_config_t *config_get_config_unlocked(void)
+{
+	return &_current_configuration;
+}
+
+static void _set_defaults(ice_config_t *configuration)
+{
+	configuration->location = CONFIG_DEFAULT_LOCATION;
+	configuration->admin = CONFIG_DEFAULT_ADMIN;
+	configuration->client_limit = CONFIG_DEFAULT_CLIENT_LIMIT;
+	configuration->source_limit = CONFIG_DEFAULT_SOURCE_LIMIT;
+	configuration->queue_size_limit = CONFIG_DEFAULT_QUEUE_SIZE_LIMIT;
+	configuration->threadpool_size = CONFIG_DEFAULT_THREADPOOL_SIZE;
+	configuration->client_timeout = CONFIG_DEFAULT_CLIENT_TIMEOUT;
+	configuration->header_timeout = CONFIG_DEFAULT_HEADER_TIMEOUT;
+	configuration->source_timeout = CONFIG_DEFAULT_SOURCE_TIMEOUT;
+	configuration->source_password = CONFIG_DEFAULT_SOURCE_PASSWORD;
+	configuration->relay_password = CONFIG_DEFAULT_RELAY_PASSWORD;
+	configuration->ice_login = CONFIG_DEFAULT_ICE_LOGIN;
+	configuration->fileserve = CONFIG_DEFAULT_FILESERVE;
+	configuration->touch_interval = CONFIG_DEFAULT_TOUCH_FREQ;
+	configuration->dir_list = NULL;
+	configuration->hostname = CONFIG_DEFAULT_HOSTNAME;
+	configuration->port = CONFIG_DEFAULT_PORT;
+	configuration->bind_address = NULL;
+	configuration->master_server = NULL;
+	configuration->master_server_port = CONFIG_DEFAULT_PORT;
+    configuration->master_update_interval = CONFIG_MASTER_UPDATE_INTERVAL;
+	configuration->master_password = NULL;
+	configuration->base_dir = CONFIG_DEFAULT_BASE_DIR;
+	configuration->log_dir = CONFIG_DEFAULT_LOG_DIR;
+    configuration->webroot_dir = CONFIG_DEFAULT_WEBROOT_DIR;
+	configuration->access_log = CONFIG_DEFAULT_ACCESS_LOG;
+	configuration->error_log = CONFIG_DEFAULT_ERROR_LOG;
+	configuration->loglevel = CONFIG_DEFAULT_LOG_LEVEL;
+    configuration->chroot = CONFIG_DEFAULT_CHROOT;
+    configuration->chuid = CONFIG_DEFAULT_CHUID;
+    configuration->user = CONFIG_DEFAULT_USER;
+    configuration->group = CONFIG_DEFAULT_GROUP;
+    configuration->num_yp_directories = 0;
 }
 
-static void _parse_root(xmlDocPtr doc, xmlNodePtr node)
+static void _parse_root(xmlDocPtr doc, xmlNodePtr node, 
+        ice_config_t *configuration)
 {
         char *tmp;
 
@@ -234,13 +291,13 @@
                 if (xmlIsBlankNode(node)) continue;
 
                 if (strcmp(node->name, "location") == 0) {
-			if (_configuration.location && _configuration.location != CONFIG_DEFAULT_LOCATION) xmlFree(_configuration.location);
-			_configuration.location = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+			if (configuration->location && configuration->location != CONFIG_DEFAULT_LOCATION) xmlFree(configuration->location);
+			configuration->location = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
                 } else if (strcmp(node->name, "admin") == 0) {
-			if (_configuration.admin && _configuration.admin != CONFIG_DEFAULT_ADMIN) xmlFree(_configuration.admin);
-			_configuration.admin = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+			if (configuration->admin && configuration->admin != CONFIG_DEFAULT_ADMIN) xmlFree(configuration->admin);
+			configuration->admin = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
                 } else if(strcmp(node->name, "authentication") == 0) {
-			_parse_authentication(doc, node->xmlChildrenNode);
+			_parse_authentication(doc, node->xmlChildrenNode, configuration);
         } else if (strcmp(node->name, "source-password") == 0) {
             /* TODO: This is the backwards-compatibility location */
             char *mount, *pass;
@@ -249,62 +306,63 @@
                 /* FIXME: This is a placeholder for per-mount passwords */
             }
             else {
-			    if (_configuration.source_password && _configuration.source_password != CONFIG_DEFAULT_SOURCE_PASSWORD) xmlFree(_configuration.source_password);
-			    _configuration.source_password = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+			    if (configuration->source_password && configuration->source_password != CONFIG_DEFAULT_SOURCE_PASSWORD) xmlFree(configuration->source_password);
+			    configuration->source_password = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
             }
         } else if (strcmp(node->name, "relay-password") == 0) {
             /* TODO: This is the backwards-compatibility location */
-			if (_configuration.relay_password && _configuration.relay_password != CONFIG_DEFAULT_RELAY_PASSWORD) xmlFree(_configuration.relay_password);
-			_configuration.relay_password = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+			if (configuration->relay_password && configuration->relay_password != CONFIG_DEFAULT_RELAY_PASSWORD) xmlFree(configuration->relay_password);
+			configuration->relay_password = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
                 } else if (strcmp(node->name, "icelogin") == 0) {
                         tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
-			_configuration.ice_login = atoi(tmp);
+			configuration->ice_login = atoi(tmp);
                         if (tmp) xmlFree(tmp);
                 } else if (strcmp(node->name, "fileserve") == 0) {
                         tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
-			_configuration.fileserve = atoi(tmp);
+			configuration->fileserve = atoi(tmp);
                         if (tmp) xmlFree(tmp);
                 } else if (strcmp(node->name, "hostname") == 0) {
-			if (_configuration.hostname && _configuration.hostname != CONFIG_DEFAULT_HOSTNAME) xmlFree(_configuration.hostname);
-			_configuration.hostname = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+			if (configuration->hostname && configuration->hostname != CONFIG_DEFAULT_HOSTNAME) xmlFree(configuration->hostname);
+			configuration->hostname = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
                 } else if (strcmp(node->name, "port") == 0) {
                         tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
-			_configuration.port = atoi(tmp);
+			configuration->port = atoi(tmp);
                         if (tmp) xmlFree(tmp);
                 } else if (strcmp(node->name, "bind-address") == 0) {
-			if (_configuration.bind_address) xmlFree(_configuration.bind_address);
-			_configuration.bind_address = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+			if (configuration->bind_address) xmlFree(configuration->bind_address);
+			configuration->bind_address = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
                 } else if (strcmp(node->name, "master-server") == 0) {
-			if (_configuration.master_server) xmlFree(_configuration.master_server);
-			_configuration.master_server = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+			if (configuration->master_server) xmlFree(configuration->master_server);
+			configuration->master_server = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
                 } else if (strcmp(node->name, "master-password") == 0) {
-			if (_configuration.master_password) xmlFree(_configuration.master_password);
-			_configuration.master_password = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+			if (configuration->master_password) xmlFree(configuration->master_password);
+			configuration->master_password = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
                 } else if (strcmp(node->name, "master-server-port") == 0) {
                         tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
-			_configuration.master_server_port = atoi(tmp);
+			configuration->master_server_port = atoi(tmp);
         } else if (strcmp(node->name, "master-update-interval") == 0) {
             tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
-            _configuration.master_update_interval = atoi(tmp);
+            configuration->master_update_interval = atoi(tmp);
                 } else if (strcmp(node->name, "limits") == 0) {
-			_parse_limits(doc, node->xmlChildrenNode);
+			_parse_limits(doc, node->xmlChildrenNode, configuration);
                 } else if (strcmp(node->name, "relay") == 0) {
-			_parse_relay(doc, node->xmlChildrenNode);
+			_parse_relay(doc, node->xmlChildrenNode, configuration);
                 } else if (strcmp(node->name, "mount") == 0) {
-			_parse_mount(doc, node->xmlChildrenNode);
+			_parse_mount(doc, node->xmlChildrenNode, configuration);
                 } else if (strcmp(node->name, "directory") == 0) {
-			_parse_directory(doc, node->xmlChildrenNode);
+			_parse_directory(doc, node->xmlChildrenNode, configuration);
                 } else if (strcmp(node->name, "paths") == 0) {
-			_parse_paths(doc, node->xmlChildrenNode);
+			_parse_paths(doc, node->xmlChildrenNode, configuration);
                 } else if (strcmp(node->name, "logging") == 0) {
-			_parse_logging(doc, node->xmlChildrenNode);
+			_parse_logging(doc, node->xmlChildrenNode, configuration);
         } else if (strcmp(node->name, "security") == 0) {
-            _parse_security(doc, node->xmlChildrenNode);
+            _parse_security(doc, node->xmlChildrenNode, configuration);
                 }
         } while ((node = node->next));
 }
 
-static void _parse_limits(xmlDocPtr doc, xmlNodePtr node)
+static void _parse_limits(xmlDocPtr doc, xmlNodePtr node, 
+        ice_config_t *configuration)
 {
         char *tmp;
 
@@ -314,41 +372,42 @@
 
                 if (strcmp(node->name, "clients") == 0) {
                         tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
-			_configuration.client_limit = atoi(tmp);
+			configuration->client_limit = atoi(tmp);
                         if (tmp) xmlFree(tmp);
                 } else if (strcmp(node->name, "sources") == 0) {
                         tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
-			_configuration.source_limit = atoi(tmp);
+			configuration->source_limit = atoi(tmp);
                         if (tmp) xmlFree(tmp);
                 } else if (strcmp(node->name, "queue-size") == 0) {
                         tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
-			_configuration.queue_size_limit = atoi(tmp);
+			configuration->queue_size_limit = atoi(tmp);
                         if (tmp) xmlFree(tmp);
                 } else if (strcmp(node->name, "threadpool") == 0) {
                         tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
-			_configuration.threadpool_size = atoi(tmp);
+			configuration->threadpool_size = atoi(tmp);
                         if (tmp) xmlFree(tmp);
                 } else if (strcmp(node->name, "client-timeout") == 0) {
                         tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
-			_configuration.client_timeout = atoi(tmp);
+			configuration->client_timeout = atoi(tmp);
                         if (tmp) xmlFree(tmp);
                 } else if (strcmp(node->name, "header-timeout") == 0) {
                         tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
-			_configuration.header_timeout = atoi(tmp);
+			configuration->header_timeout = atoi(tmp);
                         if (tmp) xmlFree(tmp);
                 } else if (strcmp(node->name, "source-timeout") == 0) {
                         tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
-			_configuration.source_timeout = atoi(tmp);
+			configuration->source_timeout = atoi(tmp);
                         if (tmp) xmlFree(tmp);
                 }
         } while ((node = node->next));
 }
 
-static void _parse_mount(xmlDocPtr doc, xmlNodePtr node)
+static void _parse_mount(xmlDocPtr doc, xmlNodePtr node, 
+        ice_config_t *configuration)
 {
     char *tmp;
     mount_proxy *mount = calloc(1, sizeof(mount_proxy));
-    mount_proxy *current = _configuration.mounts;
+    mount_proxy *current = configuration->mounts;
     mount_proxy *last=NULL;
     
     while(current) {
@@ -359,7 +418,7 @@
     if(last)
         last->next = mount;
     else
-        _configuration.mounts = mount;
+        configuration->mounts = mount;
 
     mount->max_listeners = -1;
 
@@ -395,11 +454,12 @@
         } while ((node = node->next));
 }
 
-static void _parse_relay(xmlDocPtr doc, xmlNodePtr node)
+static void _parse_relay(xmlDocPtr doc, xmlNodePtr node,
+        ice_config_t *configuration)
 {
     char *tmp;
     relay_server *relay = calloc(1, sizeof(relay_server));
-    relay_server *current = _configuration.relay;
+    relay_server *current = configuration->relay;
     relay_server *last=NULL;
     
     while(current) {
@@ -410,7 +470,7 @@
     if(last)
         last->next = relay;
     else
-        _configuration.relay = relay;
+        configuration->relay = relay;
 
         do {
                 if (node == NULL) break;
@@ -441,7 +501,8 @@
         } while ((node = node->next));
 }
 
-static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node)
+static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node,
+        ice_config_t *configuration)
 {
         do {
                 if (node == NULL) break;
@@ -454,39 +515,40 @@
                 /* FIXME: This is a placeholder for per-mount passwords */
             }
             else {
-			    if (_configuration.source_password && 
-                        _configuration.source_password != 
+			    if (configuration->source_password && 
+                        configuration->source_password != 
                         CONFIG_DEFAULT_SOURCE_PASSWORD) 
-                    xmlFree(_configuration.source_password);
-			    _configuration.source_password = 
+                    xmlFree(configuration->source_password);
+			    configuration->source_password = 
                     (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
             }
         } else if (strcmp(node->name, "relay-password") == 0) {
-			if (_configuration.relay_password && 
-                    _configuration.relay_password != 
+			if (configuration->relay_password && 
+                    configuration->relay_password != 
                     CONFIG_DEFAULT_RELAY_PASSWORD) 
-                xmlFree(_configuration.relay_password);
-			_configuration.relay_password = 
+                xmlFree(configuration->relay_password);
+			configuration->relay_password = 
                 (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
                 } else if (strcmp(node->name, "admin-password") == 0) {
-            if(_configuration.admin_password)
-                xmlFree(_configuration.admin_password);
-            _configuration.admin_password =
+            if(configuration->admin_password)
+                xmlFree(configuration->admin_password);
+            configuration->admin_password =
                 (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
                 } else if (strcmp(node->name, "admin-user") == 0) {
-            if(_configuration.admin_username)
-                xmlFree(_configuration.admin_username);
-            _configuration.admin_username =
+            if(configuration->admin_username)
+                xmlFree(configuration->admin_username);
+            configuration->admin_username =
                 (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
         }
         } while ((node = node->next));
 }
 
-static void _parse_directory(xmlDocPtr doc, xmlNodePtr node)
+static void _parse_directory(xmlDocPtr doc, xmlNodePtr node,
+        ice_config_t *configuration)
 {
         char *tmp;
 
-	if (_configuration.num_yp_directories >= MAX_YP_DIRECTORIES) {
+	if (configuration->num_yp_directories >= MAX_YP_DIRECTORIES) {
                 ERROR0("Maximum number of yp directories exceeded!");
                 return;
         }
@@ -495,68 +557,71 @@
                 if (xmlIsBlankNode(node)) continue;
 
                 if (strcmp(node->name, "yp-url") == 0) {
-			if (_configuration.yp_url[_configuration.num_yp_directories]) 
-                xmlFree(_configuration.yp_url[_configuration.num_yp_directories]);
-			_configuration.yp_url[_configuration.num_yp_directories] = 
+			if (configuration->yp_url[configuration->num_yp_directories]) 
+                xmlFree(configuration->yp_url[configuration->num_yp_directories]);
+			configuration->yp_url[configuration->num_yp_directories] = 
                 (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
         } else if (strcmp(node->name, "yp-url-timeout") == 0) {
             tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
-            _configuration.yp_url_timeout[_configuration.num_yp_directories] = 
+            configuration->yp_url_timeout[configuration->num_yp_directories] = 
                 atoi(tmp);
                 } else if (strcmp(node->name, "server") == 0) {
-			_add_server(doc, node->xmlChildrenNode);
+			_add_server(doc, node->xmlChildrenNode, configuration);
                 } else if (strcmp(node->name, "touch-interval") == 0) {
                         tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
-			_configuration.touch_interval = atoi(tmp);
+			configuration->touch_interval = atoi(tmp);
                         if (tmp) xmlFree(tmp);
                 }
         } while ((node = node->next));
-	_configuration.num_yp_directories++;
+	configuration->num_yp_directories++;
 }
 
-static void _parse_paths(xmlDocPtr doc, xmlNodePtr node)
+static void _parse_paths(xmlDocPtr doc, xmlNodePtr node,
+        ice_config_t *configuration)
 {
         do {
                 if (node == NULL) break;
                 if (xmlIsBlankNode(node)) continue;
 
                 if (strcmp(node->name, "basedir") == 0) {
-			if (_configuration.base_dir && _configuration.base_dir != CONFIG_DEFAULT_BASE_DIR) xmlFree(_configuration.base_dir);
-			_configuration.base_dir = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+			if (configuration->base_dir && configuration->base_dir != CONFIG_DEFAULT_BASE_DIR) xmlFree(configuration->base_dir);
+			configuration->base_dir = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
                 } else if (strcmp(node->name, "logdir") == 0) {
-			if (_configuration.log_dir && _configuration.log_dir != CONFIG_DEFAULT_LOG_DIR) xmlFree(_configuration.log_dir);
-			_configuration.log_dir = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+			if (configuration->log_dir && configuration->log_dir != CONFIG_DEFAULT_LOG_DIR) xmlFree(configuration->log_dir);
+			configuration->log_dir = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
                 } else if (strcmp(node->name, "webroot") == 0) {
-			if (_configuration.webroot_dir && _configuration.webroot_dir != CONFIG_DEFAULT_WEBROOT_DIR) xmlFree(_configuration.webroot_dir);
-			_configuration.webroot_dir = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
-            if(_configuration.webroot_dir[strlen(_configuration.webroot_dir)-1] == '/')
-                _configuration.webroot_dir[strlen(_configuration.webroot_dir)-1] = 0;
+			if (configuration->webroot_dir && configuration->webroot_dir != CONFIG_DEFAULT_WEBROOT_DIR) xmlFree(configuration->webroot_dir);
+			configuration->webroot_dir = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+            if(configuration->webroot_dir[strlen(configuration->webroot_dir)-1] == '/')
+                configuration->webroot_dir[strlen(configuration->webroot_dir)-1] = 0;
 
                 }
         } while ((node = node->next));
 }
 
-static void _parse_logging(xmlDocPtr doc, xmlNodePtr node)
+static void _parse_logging(xmlDocPtr doc, xmlNodePtr node,
+        ice_config_t *configuration)
 {
         do {
                 if (node == NULL) break;
                 if (xmlIsBlankNode(node)) continue;
 
                 if (strcmp(node->name, "accesslog") == 0) {
-			if (_configuration.access_log && _configuration.access_log != CONFIG_DEFAULT_ACCESS_LOG) xmlFree(_configuration.access_log);
-			_configuration.access_log = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+			if (configuration->access_log && configuration->access_log != CONFIG_DEFAULT_ACCESS_LOG) xmlFree(configuration->access_log);
+			configuration->access_log = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
                 } else if (strcmp(node->name, "errorlog") == 0) {
-			if (_configuration.error_log && _configuration.error_log != CONFIG_DEFAULT_ERROR_LOG) xmlFree(_configuration.error_log);
-			_configuration.error_log = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+			if (configuration->error_log && configuration->error_log != CONFIG_DEFAULT_ERROR_LOG) xmlFree(configuration->error_log);
+			configuration->error_log = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
                 } else if (strcmp(node->name, "loglevel") == 0) {
            char *tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
-           _configuration.loglevel = atoi(tmp);
+           configuration->loglevel = atoi(tmp);
            if (tmp) xmlFree(tmp);
         }
         } while ((node = node->next));
 }
 
-static void _parse_security(xmlDocPtr doc, xmlNodePtr node)
+static void _parse_security(xmlDocPtr doc, xmlNodePtr node,
+        ice_config_t *configuration)
 {
    char *tmp;
    xmlNodePtr oldnode;
@@ -567,21 +632,21 @@
 
        if (strcmp(node->name, "chroot") == 0) {
            tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
-           _configuration.chroot = atoi(tmp);
+           configuration->chroot = atoi(tmp);
            if (tmp) xmlFree(tmp);
        } else if (strcmp(node->name, "changeowner") == 0) {
-           _configuration.chuid = 1;
+           configuration->chuid = 1;
            oldnode = node;
            node = node->xmlChildrenNode;
            do {
                if(node == NULL) break;
                if(xmlIsBlankNode(node)) continue;
                if(strcmp(node->name, "user") == 0) {
-                   if(_configuration.user) xmlFree(_configuration.user);
-                   _configuration.user = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+                   if(configuration->user) xmlFree(configuration->user);
+                   configuration->user = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
                } else if(strcmp(node->name, "group") == 0) {
-                   if(_configuration.group) xmlFree(_configuration.group);
-                   _configuration.group = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+                   if(configuration->group) xmlFree(configuration->group);
+                   configuration->group = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
                }
            } while((node = node->next));
            node = oldnode;
@@ -589,14 +654,15 @@
    } while ((node = node->next));
 }
 
-static void _add_server(xmlDocPtr doc, xmlNodePtr node)
+static void _add_server(xmlDocPtr doc, xmlNodePtr node, 
+        ice_config_t *configuration)
 {
         ice_config_dir_t *dirnode, *server;
         int addnode;
         char *tmp;
 
         server = (ice_config_dir_t *)malloc(sizeof(ice_config_dir_t));
-	server->touch_interval = _configuration.touch_interval;
+	server->touch_interval = configuration->touch_interval;
         server->host = NULL;
         addnode = 0;
         
@@ -617,9 +683,9 @@
         } while ((node = node->next));
 
         if (addnode) {
-		dirnode = _configuration.dir_list;
+		dirnode = configuration->dir_list;
                 if (dirnode == NULL) {
-			_configuration.dir_list = server;
+			configuration->dir_list = server;
                 } else {
                         while (dirnode->next) dirnode = dirnode->next;
                         

<p><p>1.17      +20 -1     icecast/src/config.h

Index: config.h
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/config.h,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- config.h	24 Feb 2003 13:37:15 -0000	1.16
+++ config.h	5 Mar 2003 13:03:35 -0000	1.17
@@ -8,6 +8,8 @@
 
 #define MAX_YP_DIRECTORIES 25
 
+#include "thread/thread.h"
+
 typedef struct ice_config_dir_tag
 {
         char *host;
@@ -40,6 +42,8 @@
 
 typedef struct ice_config_tag
 {
+    char *config_filename;
+
         char *location;
         char *admin;
 
@@ -90,15 +94,30 @@
     int num_yp_directories;
 } ice_config_t;
 
+typedef struct {
+    mutex_t config_lock;
+    mutex_t relay_lock;
+    mutex_t mounts_lock;
+} ice_config_locks;
+
 void config_initialize(void);
 void config_shutdown(void);
 
-int config_parse_file(const char *filename);
+int config_parse_file(const char *filename, ice_config_t *configuration);
+int config_initial_parse_file(const char *filename);
 int config_parse_cmdline(int arg, char **argv);
+void config_set_config(ice_config_t *config);
+void config_clear(ice_config_t *config);
 
 int config_rehash(void);
 
+ice_config_locks *config_locks(void);
+
 ice_config_t *config_get_config(void);
+void config_release_config(void);
+
+/* To be used ONLY in one-time startup code */
+ice_config_t *config_get_config_unlocked(void);
 
 #endif  /* __CONFIG_H__ */
 

<p><p>1.4       +1 -1      icecast/src/configtest.c

Index: configtest.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/configtest.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- configtest.c	6 Feb 2003 13:10:48 -0000	1.3
+++ configtest.c	5 Mar 2003 13:03:35 -0000	1.4
@@ -11,7 +11,7 @@
         
         config_parse_file("icecast.xml");
 
-	config = config_get_config();
+	config = config_get_config_unlocked();
 
         _dump_config(config);
 

<p><p>1.57      +88 -17    icecast/src/connection.c

Index: connection.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/connection.c,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -r1.56 -r1.57
--- connection.c	2 Mar 2003 10:36:24 -0000	1.56
+++ connection.c	5 Mar 2003 13:03:35 -0000	1.57
@@ -40,6 +40,7 @@
 #include "geturl.h"
 #include "format.h"
 #include "format_mp3.h"
+#include "event.h"
 
 #define CATMODULE "connection"
 
@@ -112,6 +113,10 @@
         con->con_time = time(NULL);
         con->id = _next_connection_id();
         con->ip = ip;
+
+    con->event_number = EVENT_NO_EVENT;
+    con->event = NULL;
+
         return con;
 }
 
@@ -209,10 +214,13 @@
         int i;
     thread_type *tid;
         char buff[64];
+    int threadpool_size;
 
         config = config_get_config();
+    threadpool_size = config->threadpool_size;
+    config_release_config();
 
-	for (i = 0; i < config->threadpool_size; i++) {
+	for (i = 0; i < threadpool_size; i++) {
                 snprintf(buff, 64, "Connection Thread #%d", i);
                 tid = thread_create(buff, _handle_connection, NULL, THREAD_ATTACHED);
                 _push_thread(&_conhands, tid);
@@ -290,6 +298,16 @@
         return con;
 }
 
+void connection_inject_event(int eventnum, void *event_data) {
+    connection_t *con = calloc(1, sizeof(connection_t));
+
+    con->event_number = eventnum;
+    con->event = event_data;
+
+    _add_connection(con);
+    _signal_pool();
+}
+
 /* TODO: Make this return an appropriate error code so that we can use HTTP
  * codes where appropriate
  */
@@ -297,12 +315,18 @@
         source_t *source;
         char *contenttype;
     mount_proxy *mountproxy, *mountinfo = NULL;
+    int source_limit;
+    ice_config_t *config;
+
+    config = config_get_config();
+    source_limit = config->source_limit;
+    config_release_config();
 
         /* check to make sure this source wouldn't
         ** be over the limit
         */
         global_lock();
-	if (global.sources >= config_get_config()->source_limit) {
+	if (global.sources >= source_limit) {
                 INFO1("Source (%s) logged in, but there are too many sources", mount);
                 global_unlock();
                 return 0;
@@ -312,7 +336,11 @@
 
         stats_event_inc(NULL, "sources");
     
-    mountproxy = config_get_config()->mounts;
+    config = config_get_config();
+    mountproxy = config->mounts;
+    thread_mutex_lock(&(config_locks()->mounts_lock));
+    config_release_config();
+
     while(mountproxy) {
         if(!strcmp(mountproxy->mountname, mount)) {
             mountinfo = mountproxy;
@@ -327,15 +355,18 @@
                 format_type_t format = format_get_type(contenttype);
                 if (format == FORMAT_ERROR) {
                         WARN1("Content-type \"%s\" not supported, dropping source", contenttype);
+            thread_mutex_unlock(&(config_locks()->mounts_lock));
             goto fail;
                 } else {
                         source = source_create(client, con, parser, mount, 
                     format, mountinfo);
+            thread_mutex_unlock(&(config_locks()->mounts_lock));
                 }
         } else {
         format_type_t format = FORMAT_TYPE_MP3;
                 ERROR0("No content-type header, falling back to backwards compatibility mode for icecast 1.x relays. Assuming content is mp3.");
         source = source_create(client, con, parser, mount, format, mountinfo);
+        thread_mutex_unlock(&(config_locks()->mounts_lock));
         }
 
     source->send_return = 1;
@@ -408,17 +439,22 @@
 
 static int _check_relay_pass(http_parser_t *parser)
 {
-    char *pass = config_get_config()->relay_password;
+    ice_config_t *config = config_get_config();
+    char *pass = config->relay_password;
     if(!pass)
-        pass = config_get_config()->source_password;
+        pass = config->source_password;
+    config_release_config();
 
     return _check_pass_http(parser, "relay", pass);
 }
 
 static int _check_admin_pass(http_parser_t *parser)
 {
-    char *pass = config_get_config()->admin_password;
-    char *user = config_get_config()->admin_username;
+    ice_config_t *config = config_get_config();
+    char *pass = config->admin_password;
+    char *user = config->admin_username;
+    config_release_config();
+
     if(!pass || !user)
         return 0;
 
@@ -427,11 +463,16 @@
 
 static int _check_source_pass(http_parser_t *parser, char *mount)
 {
-    char *pass = config_get_config()->source_password;
+    ice_config_t *config = config_get_config();
+    char *pass = config->source_password;
     char *user = "source";
     int ret;
+    int ice_login = config->ice_login;
+
+    mount_proxy *mountinfo = config->mounts;
+    thread_mutex_lock(&(config_locks()->mounts_lock));
+    config_release_config();
 
-    mount_proxy *mountinfo = config_get_config()->mounts;
     while(mountinfo) {
         if(!strcmp(mountinfo->mountname, mount)) {
             if(mountinfo->password)
@@ -443,13 +484,15 @@
         mountinfo = mountinfo->next;
     }
 
+    thread_mutex_unlock(&(config_locks()->mounts_lock));
+
     if(!pass) {
         WARN0("No source password set, rejecting source");
         return 0;
     }
 
     ret = _check_pass_http(parser, user, pass);
-    if(!ret && config_get_config()->ice_login)
+    if(!ret && ice_login)
     {
         ret = _check_pass_ice(parser, pass);
         if(ret)
@@ -627,6 +670,19 @@
     int bytes;
         struct stat statbuf;
         source_t *source;
+    int fileserve;
+    char *host;
+    int port;
+    ice_config_t *config;
+    int client_limit;
+
+    config = config_get_config();
+    fileserve = config->fileserve;
+    host = config->hostname;
+    port = config->port;
+    client_limit = config->client_limit;
+    config_release_config();
+
 
     DEBUG0("Client connected");
 
@@ -689,8 +745,8 @@
         free(fullpath);
         return;
         }
-    else if(config_get_config()->fileserve && 
-            stat(fullpath, &statbuf) == 0) {
+    else if(fileserve && stat(fullpath, &statbuf) == 0) 
+    {
         fserve_client_create(client, fullpath);
         free(fullpath);
         return;
@@ -709,14 +765,14 @@
                     "HTTP/1.0 200 OK\r\n"
                     "Content-Type: audio/x-mpegurl\r\n\r\n"
                     "http://%s:%d%s", 
-                    config_get_config()->hostname, 
-                    config_get_config()->port,
+                    host, 
+                    port,
                     sourceuri
                     );
             if(bytes > 0) client->con->sent_bytes = bytes;
                 client_destroy(client);
         }
-        else if(config_get_config()->fileserve) {
+        else if(fileserve) {
             fullpath = util_get_path_from_normalised_uri(sourceuri);
             if(stat(fullpath, &statbuf) == 0) {
                 fserve_client_create(client, fullpath);
@@ -774,7 +830,7 @@
         }
                                 
         global_lock();
-	if (global.clients >= config_get_config()->client_limit) {
+	if (global.clients >= client_limit) {
         client_send_504(client,
                 "The server is already full. Try again later.");
                 global_unlock();
@@ -788,7 +844,7 @@
         DEBUG0("Source found for client");
                                                 
                 global_lock();
-		if (global.clients >= config_get_config()->client_limit) {
+		if (global.clients >= client_limit) {
             client_send_504(client, 
                     "The server is already full. Try again later.");
                         global_unlock();
@@ -847,6 +903,21 @@
 
                 /* grab a connection and set the socket to blocking */
                 while ((con = _get_connection())) {
+
+            /* Handle meta-connections */
+            if(con->event_number > 0) {
+                switch(con->event_number) {
+                    case EVENT_CONFIG_READ:
+                        event_config_read(con->event);
+                        break;
+                    default:
+                        ERROR1("Unknown event number: %d", con->event_number);
+                        break;
+                }
+                free(con);
+                continue;
+            }
+
                         stats_event_inc(NULL, "connections");
 
                         sock_set_blocking(con->sock, SOCK_BLOCK);

<p><p>1.7       +6 -0      icecast/src/connection.h

Index: connection.h
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/connection.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- connection.h	16 Aug 2002 14:26:48 -0000	1.6
+++ connection.h	5 Mar 2003 13:03:35 -0000	1.7
@@ -21,6 +21,10 @@
 
         char *ip;
         char *host;
+
+    /* For 'fake' connections */
+    int event_number;
+    void *event;
 } connection_t;
 
 void connection_initialize(void);
@@ -30,6 +34,8 @@
 connection_t *create_connection(sock_t sock, char *ip);
 int connection_create_source(struct _client_tag *client, connection_t *con, 
         http_parser_t *parser, char *mount);
+
+void connection_inject_event(int eventnum, void *event_data);
 
 extern rwlock_t _source_shutdown_rwlock;
 

<p><p>1.11      +18 -3     icecast/src/fserve.c

Index: fserve.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/fserve.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- fserve.c	11 Feb 2003 12:18:22 -0000	1.10
+++ fserve.c	5 Mar 2003 13:03:35 -0000	1.11
@@ -78,7 +78,12 @@
 
 void fserve_initialize(void)
 {
-    if(!config_get_config()->fileserve)
+    ice_config_t *config = config_get_config();
+    int serve = config->fileserve;
+
+    config_release_config();
+
+    if(!serve)
         return;
 
     create_mime_mappings(MIMETYPESFILE);
@@ -95,7 +100,12 @@
 
 void fserve_shutdown(void)
 {
-    if(!config_get_config()->fileserve)
+    ice_config_t *config = config_get_config();
+    int serve = config->fileserve;
+
+    config_release_config();
+
+    if(!serve)
         return;
 
     if(!run_fserv)
@@ -345,6 +355,11 @@
 {
     fserve_t *client = calloc(1, sizeof(fserve_t));
     int bytes;
+    int client_limit;
+    ice_config_t *config = config_get_config();
+
+    client_limit = config->client_limit;
+    config_release_config();
 
     client->file = fopen(path, "rb");
     if(!client->file) {
@@ -358,7 +373,7 @@
     client->buf = malloc(BUFSIZE);
 
     global_lock();
-    if(global.clients >= config_get_config()->client_limit) {
+    if(global.clients >= client_limit) {
         httpclient->respcode = 504;
         bytes = sock_write(httpclient->con->sock,
                 "HTTP/1.0 504 Server Full\r\n"

<p><p>1.22      +9 -5      icecast/src/main.c

Index: main.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/main.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- main.c	2 Feb 2003 14:26:54 -0000	1.21
+++ main.c	5 Mar 2003 13:03:35 -0000	1.22
@@ -125,7 +125,7 @@
 {
         char fn_error[FILENAME_MAX];
         char fn_access[FILENAME_MAX];
-	ice_config_t *config = config_get_config();
+	ice_config_t *config = config_get_config_unlocked();
 
         if(strcmp(config->error_log, "-")) {
         snprintf(fn_error, FILENAME_MAX, "%s%s%s", config->log_dir, PATH_SEPARATOR, config->error_log);
@@ -157,9 +157,10 @@
 {
         ice_config_t *config;
 
-	config = config_get_config();
+	config = config_get_config_unlocked();
 
         global.serversock = sock_get_server_socket(config->port, config->bind_address);
+
         if (global.serversock == SOCK_ERROR)
                 return 0;
         
@@ -180,7 +181,8 @@
 static int _server_proc_init(void)
 {
         if (!_setup_socket()) {
-		fprintf(stderr, "Could not create listener socket on port %d\n", config_get_config()->port);
+		fprintf(stderr, "Could not create listener socket on port %d\n", 
+                config_get_config_unlocked()->port);
                 return 0;
         }
 
@@ -205,7 +207,7 @@
 
 static void _ch_root_uid_setup(void)
 {
-   ice_config_t *conf = config_get_config();
+   ice_config_t *conf = config_get_config_unlocked();
 #ifdef CHUID
    struct passwd *user;
    struct group *group;
@@ -291,7 +293,9 @@
             _initialize_subsystems();
 
                 /* parse the config file */
-		ret = config_parse_file(filename);
+        config_get_config();
+		ret = config_initial_parse_file(filename);
+        config_release_config();
                 if (ret < 0) {
                         fprintf(stderr, "FATAL: error parsing config file:");
                         switch (ret) {

<p><p>1.3       +12 -5     icecast/src/sighandler.c

Index: sighandler.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/sighandler.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- sighandler.c	22 Nov 2002 13:00:44 -0000	1.2
+++ sighandler.c	5 Mar 2003 13:03:35 -0000	1.3
@@ -10,6 +10,7 @@
 #include "refbuf.h"
 #include "client.h"
 #include "logging.h"
+#include "event.h"
 
 #include "sighandler.h"
 
@@ -34,16 +35,22 @@
 
 void _sig_hup(int signo)
 {
-	INFO1("Caught signal %d, rehashing config and reopening logfiles (unimplemented)...", signo);
+    /* We do this elsewhere because it's a bad idea to hang around for too
+     * long re-reading an entire config file inside a signal handler. Bad
+     * practice.
+     */
+
+	INFO1("Caught signal %d, scheduling config reread ...", 
+            signo);
 
         /* reread config file */
 
-	/* reopen logfiles */
+    connection_inject_event(EVENT_CONFIG_READ, NULL);
+    
+	/* reopen logfiles (TODO: We don't do this currently) */
 
-#ifdef __linux__
-	/* linux requires us to reattach the signal handler */
+	/* some OSes require us to reattach the signal handler */
         signal(SIGHUP, _sig_hup);
-#endif
 }
 
 void _sig_die(int signo)

<p><p>1.21      +48 -15    icecast/src/slave.c

Index: slave.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/slave.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- slave.c	25 Feb 2003 09:40:34 -0000	1.20
+++ slave.c	5 Mar 2003 13:03:35 -0000	1.21
@@ -49,11 +49,18 @@
 static int _initialized = 0;
 
 void slave_initialize(void) {
+    ice_config_t *config;
         if (_initialized) return;
+
+    config = config_get_config();
     /* Don't create a slave thread if it isn't configured */
-    if (config_get_config()->master_server == NULL && 
-            config_get_config()->relay == NULL)
+    if (config->master_server == NULL && 
+            config->relay == NULL)
+    {
+        config_release_config();
         return;
+    }
+    config_release_config();
 
         _initialized = 1;
         _slave_thread_id = thread_create("Slave Thread", _slave_thread, NULL, THREAD_ATTACHED);
@@ -131,28 +138,48 @@
 static void *_slave_thread(void *arg) {
         sock_t mastersock;
         char buf[256];
-    int interval = config_get_config()->master_update_interval;
+    int interval;
     char *authheader, *data;
     int len;
     char *username = "relay";
-    char *password = config_get_config()->master_password;
+    char *password;
+    int max_interval;
     relay_server *relay;
+    ice_config_t *config;
+    
+    config = config_get_config();
+
+    password = config->master_password;
+    interval = max_interval = config->master_update_interval;
 
     if(password == NULL)
-        password = config_get_config()->source_password;
+        password = config->source_password;
+
+    config_release_config();
 
 
         while (_initialized) {
-        if (config_get_config()->master_update_interval > ++interval) {
+        if (max_interval > ++interval) {
                     thread_sleep(1000000);
             continue;
         }
-        else
+        else {
+            /* In case it's been reconfigured */
+            config = config_get_config();
+            max_interval = config->master_update_interval;
+            config_release_config();
+
             interval = 0;
+        }
+
+        config = config_get_config();
+        if(config->master_server != NULL) {
+            char *server = config->master_server;
+            int port = config->master_server_port;
+            config_release_config();
+
+		    mastersock = sock_connect_wto(server, port, 0);
 
-        if(config_get_config()->master_server != NULL) {
-		    mastersock = sock_connect_wto(config_get_config()->master_server, 
-                    config_get_config()->master_server_port, 0);
                     if (mastersock == SOCK_ERROR) {
                 WARN0("Relay slave failed to contact master server to fetch stream list");
                             continue;
@@ -180,19 +207,23 @@
                             if (!source_find_mount(buf)) {
                                     avl_tree_unlock(global.source_tree);
 
-                    create_relay_stream(
-                            config_get_config()->master_server,
-                            config_get_config()->master_server_port,
-                            buf, NULL, 0);
+                    create_relay_stream(server, port, buf, NULL, 0);
                             } 
                 else
                                 avl_tree_unlock(global.source_tree);
                     }
                     sock_close(mastersock);
         }
+        else {
+            config_release_config();
+        }
 
         /* And now, we process the individual mounts... */
-        relay = config_get_config()->relay;
+        config = config_get_config();
+        relay = config->relay;
+        thread_mutex_lock(&(config_locks()->relay_lock));
+        config_release_config();
+
         while(relay) {
             avl_tree_rlock(global.source_tree);
             if(!source_find_mount(relay->localmount)) {
@@ -205,6 +236,8 @@
                 avl_tree_unlock(global.source_tree);
             relay = relay->next;
         }
+
+        thread_mutex_unlock(&(config_locks()->relay_lock));
         }
         thread_exit(0);
         return NULL;

<p><p>1.41      +29 -20    icecast/src/source.c

Index: source.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/source.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -r1.40 -r1.41
--- source.c	2 Mar 2003 10:36:24 -0000	1.40
+++ source.c	5 Mar 2003 13:03:35 -0000	1.41
@@ -59,7 +59,6 @@
     http_parser_t *parser, const char *mount, format_type_t type, 
     mount_proxy *mountinfo)
 {
-	int	i = 0;
         source_t *src;
 
         src = (source_t *)malloc(sizeof(source_t));
@@ -79,17 +78,6 @@
     src->dumpfilename = NULL;
     src->dumpfile = NULL;
     src->audio_info = util_dict_new();
-	for (i=0;i<config_get_config()->num_yp_directories;i++) {
-		if (config_get_config()->yp_url[i]) {
-			src->ypdata[src->num_yp_directories] = yp_create_ypdata();
-			src->ypdata[src->num_yp_directories]->yp_url = 
-                config_get_config()->yp_url[i];
-			src->ypdata[src->num_yp_directories]->yp_url_timeout = 
-                config_get_config()->yp_url_timeout[i];
-			src->ypdata[src->num_yp_directories]->yp_touch_interval = 0;
-			src->num_yp_directories++;
-		}
-	}
 
     if(mountinfo != NULL) {
         src->fallback_mount = mountinfo->fallback_mount;
@@ -191,9 +179,31 @@
     int	suppress_yp = 0;
     char *ai;
 
-    long queue_limit = config_get_config()->queue_size_limit;
+    long queue_limit;
+    ice_config_t *config;
+    char *hostname;
+    int port;
+
+    config = config_get_config();
+    
+    queue_limit = config->queue_size_limit;
+	timeout = config->source_timeout;
+    hostname = config->hostname;
+    port = config->port;
+
+	for (i=0;i<config->num_yp_directories;i++) {
+		if (config->yp_url[i]) {
+			source->ypdata[source->num_yp_directories] = yp_create_ypdata();
+			source->ypdata[source->num_yp_directories]->yp_url = 
+                config->yp_url[i];
+			source->ypdata[source->num_yp_directories]->yp_url_timeout = 
+                config->yp_url_timeout[i];
+			source->ypdata[source->num_yp_directories]->yp_touch_interval = 0;
+			source->num_yp_directories++;
+		}
+	}
 
-	timeout = config_get_config()->source_timeout;
+    config_release_config();
 
         /* grab a read lock, to make sure we get a chance to cleanup */
         thread_rwlock_rlock(source->shutdown_rwlock);
@@ -273,12 +283,11 @@
                 }
                 /* 6 for max size of port */
                 listen_url_size = strlen("http://") + 
-            strlen(config_get_config()->hostname) + 
+            strlen(hostname) + 
             strlen(":") + 6 + strlen(source->mount) + 1;
                 source->ypdata[i]->listen_url = malloc(listen_url_size);
                 sprintf(source->ypdata[i]->listen_url, "http://%s:%d%s", 
-                config_get_config()->hostname, config_get_config()->port, 
-                source->mount);
+                hostname, port, source->mount);
         }
 
         if(!suppress_yp) {
@@ -609,15 +618,15 @@
         global.sources--;
         global_unlock();
 
+    if(source->dumpfile)
+        fclose(source->dumpfile);
+
         /* release our hold on the lock so the main thread can continue cleaning up */
         thread_rwlock_unlock(source->shutdown_rwlock);
 
         avl_tree_wlock(global.source_tree);
         avl_delete(global.source_tree, source, source_free_source);
         avl_tree_unlock(global.source_tree);
-
-    if(source->dumpfile)
-        fclose(source->dumpfile);
 
         thread_exit(0);
       

<p><p>1.19      +11 -3     icecast/src/util.c

Index: util.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/util.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- util.c	2 Mar 2003 10:13:59 -0000	1.18
+++ util.c	5 Mar 2003 13:03:35 -0000	1.19
@@ -74,8 +74,11 @@
         unsigned long pos;
         char c;
         ice_config_t *config;
+    int header_timeout;
 
         config = config_get_config();
+    header_timeout = config->header_timeout;
+    config_release_config();
 
         read_bytes = 1;
         pos = 0;
@@ -84,7 +87,7 @@
         while ((read_bytes == 1) && (pos < (len - 1))) {
                 read_bytes = 0;
 
-        if (util_timed_wait_for_fd(sock, config->header_timeout*1000) > 0) {
+        if (util_timed_wait_for_fd(sock, header_timeout*1000) > 0) {
 
                         if ((read_bytes = recv(sock, &c, 1, 0))) {
                                 if (c != '\r') buff[pos++] = c;
@@ -199,9 +202,14 @@
 
 char *util_get_path_from_normalised_uri(char *uri) {
     char *fullpath;
+    char *webroot;
+    ice_config_t *config = config_get_config();
 
-    fullpath = malloc(strlen(uri) + strlen(config_get_config()->webroot_dir) + 1);
-    strcpy(fullpath, config_get_config()->webroot_dir);
+    webroot = config->webroot_dir;
+    config_release_config();
+
+    fullpath = malloc(strlen(uri) + strlen(webroot) + 1);
+    strcpy(fullpath, webroot);
 
     strcat(fullpath, uri);
 

<p><p>1.6       +10 -6     icecast/src/yp.c

Index: yp.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/yp.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- yp.c	26 Feb 2003 23:52:23 -0000	1.5
+++ yp.c	5 Mar 2003 13:03:35 -0000	1.6
@@ -15,14 +15,18 @@
 
 #define CATMODULE "yp" 
 
-int yp_submit_url(int curl_con, char *yp_url, char *url, char *type)
+int yp_submit_url(int curl_con, char *yp_url, char *url, char *type, int i)
 {
     int ret = 0;
+    int *timeout;
+    ice_config_t *config = config_get_config();
+
+    timeout = config->yp_url_timeout + i;
+    config_release_config();
 
     curl_easy_setopt(curl_get_handle(curl_con), CURLOPT_URL, yp_url);
     curl_easy_setopt(curl_get_handle(curl_con), CURLOPT_POSTFIELDS, url);
-    curl_easy_setopt(curl_get_handle(curl_con), CURLOPT_TIMEOUT, 
-            config_get_config()->yp_url_timeout);
+    curl_easy_setopt(curl_get_handle(curl_con), CURLOPT_TIMEOUT, timeout);
 
     /* get it! */
     memset(curl_get_result(curl_con), 0, sizeof(struct curl_memory_struct));
@@ -93,7 +97,7 @@
             else {
                 /* specify URL to get */
                 ret = yp_submit_url(curl_con, source->ypdata[i]->yp_url, 
-                        url, "yp_remove");
+                        url, "yp_remove", i);
             }
             if (url) {
                 free(url);
@@ -159,7 +163,7 @@
             else {
                 /* specify URL to get */
                 ret = yp_submit_url(curl_con, source->ypdata[i]->yp_url, 
-                        url, "yp_touch");
+                        url, "yp_touch", i);
                 if (!ret) {
                     source->ypdata[i]->sid[0] = 0;
                 }
@@ -291,7 +295,7 @@
                else {
                    /* specify URL to get */
                    ret = yp_submit_url(curl_con, source->ypdata[i]->yp_url, 
-                           url, "yp_add");
+                           url, "yp_add", i);
 
                    if (ret) {
                        if (strlen(curl_get_header_result(curl_con)->sid) > 0) {

<p><p>1.1                  icecast/src/event.c

Index: event.c
===================================================================
#include "event.h"
#include "config.h"

#include "refbuf.h"
#include "client.h"
#include "logging.h"

#define CATMODULE "event"

void event_config_read(void *arg)
{
    int ret;
    ice_config_t *config;
    ice_config_t new_config;
        /* reread config file */

    config = config_get_config(); /* Both to get the lock, and to be able
                                     to find out the config filename */
    ret = config_parse_file(config->config_filename, &new_config);
    if(ret < 0) {
        ERROR0("Error parsing config, not replacing existing config");
        switch(ret) {
            case CONFIG_EINSANE:
                ERROR0("Config filename null or blank");
                break;
            case CONFIG_ENOROOT:
                ERROR1("Root element not found in %s", config->config_filename);
                break;
            case CONFIG_EBADROOT:
                ERROR1("Not an icecast2 config file: %s",
                        config->config_filename);
                break;
            default:
                ERROR1("Parse error in reading %s", config->config_filename);
                break;
        }
        config_release_config();
    }
    else {
        config_clear(config);
        config_set_config(&new_config);

        config_release_config();
    }
}

<p><p><p>1.1                  icecast/src/event.h

Index: event.h
===================================================================
#ifndef __EVENT_H__
#define __EVENT_H__

#define EVENT_NO_EVENT 0
#define EVENT_CONFIG_READ 1

void event_config_read(void *nothing);

#endif  /* __EVENT_H__ */

<p><p>--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list