[xiph-cvs] cvs commit: icecast/src format_mp3.c
Karl Heyes
karl at xiph.org
Tue Nov 11 10:21:49 PST 2003
karl 03/11/11 13:21:49
Modified: src format_mp3.c
Log:
While tracking down the bug which causes the zombie thread manager while
streaming mp3 with metadata, this patch has turned out to be successful at
maintaining a working icecast for the few users who have reported the problem
The patch essentially removes the use of the alloca and uses the malloc-type
calls instead.
Revision Changes Path
1.25 +80 -59 icecast/src/format_mp3.c
Index: format_mp3.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/format_mp3.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- format_mp3.c 24 Jul 2003 05:24:00 -0000 1.24
+++ format_mp3.c 11 Nov 2003 18:21:49 -0000 1.25
@@ -16,10 +16,6 @@
# include <strings.h>
#endif
-#ifdef HAVE_ALLOCA_H
-#include <alloca.h>
-#endif
-
#include "refbuf.h"
#include "source.h"
#include "client.h"
@@ -35,7 +31,6 @@
#ifdef WIN32
#define strcasecmp stricmp
#define strncasecmp strnicmp
-#define alloca _alloca
#endif
#define CATMODULE "format-mp3"
@@ -98,78 +93,103 @@
static int send_metadata(client_t *client, mp3_client_data *client_state,
mp3_state *source_state)
{
- int send_metadata;
+ int free_meta = 0;
int len_byte;
int len;
+ int ret = -1;
unsigned char *buf;
- int ret;
int source_age;
- char *fullmetadata = NULL;
- int fullmetadata_size = 0;
+ char *fullmetadata = NULL;
+ int fullmetadata_size = 0;
+ const char meta_fmt[] = "StreamTitle='';";
- thread_mutex_lock(&(source_state->lock));
- if(source_state->metadata == NULL) {
- /* Shouldn't be possible */
- thread_mutex_unlock(&(source_state->lock));
- return 0;
- }
-
- if(source_state->metadata_raw) {
- fullmetadata_size = strlen(source_state->metadata);
- fullmetadata = source_state->metadata;
- }
- else {
- fullmetadata_size = strlen(source_state->metadata) +
- strlen("StreamTitle='';StreamUrl=''") + 1;
+ do
+ {
+ thread_mutex_lock (&(source_state->lock));
+ if (source_state->metadata == NULL)
+ break; /* Shouldn't be possible */
+
+ if (source_state->metadata_raw)
+ {
+ fullmetadata_size = strlen (source_state->metadata);
+ fullmetadata = source_state->metadata;
+ if (fullmetadata_size > 4080)
+ {
+ fullmetadata_size = 4080;
+ }
+ }
+ else
+ {
+ fullmetadata_size = strlen (source_state->metadata) +
+ sizeof (meta_fmt);
+
+ if (fullmetadata_size > 4080)
+ {
+ fullmetadata_size = 4080;
+ }
+ fullmetadata = malloc (fullmetadata_size);
+ if (fullmetadata == NULL)
+ break;
+
+ fullmetadata_size = snprintf (fullmetadata, fullmetadata_size,
+ "StreamTitle='%.*s';", fullmetadata_size-(sizeof (meta_fmt)-1), source_state->metadata);
+ free_meta = 1;
+ }
- fullmetadata = alloca(fullmetadata_size);
+ source_age = source_state->metadata_age;
- sprintf(fullmetadata, "StreamTitle='%s';StreamUrl=''",
- source_state->metadata);
- }
-
- source_age = source_state->metadata_age;
- send_metadata = source_age != client_state->metadata_age;
+ if (fullmetadata_size > 0 && source_age != client_state->metadata_age)
+ {
+ len_byte = (fullmetadata_size-1)/16 + 1; /* to give 1-255 */
+ client_state->metadata_offset = 0;
+ }
+ else
+ len_byte = 0;
+ len = 1 + len_byte*16;
+ buf = malloc (len);
+ if (buf == NULL)
+ break;
+
+ buf[0] = len_byte;
+
+ if (len > 1) {
+ strncpy (buf+1, fullmetadata, len-1);
+ buf[len-1] = '\0';
+ }
- if(send_metadata && strlen(fullmetadata) > 0)
- len_byte = strlen(fullmetadata)/16 + 1 -
- client_state->metadata_offset;
- else
- len_byte = 0;
- len = 1 + len_byte*16;
- buf = alloca(len);
+ thread_mutex_unlock (&(source_state->lock));
- memset(buf, 0, len);
+ /* only write what hasn't been written already */
+ ret = sock_write_bytes (client->con->sock, buf+client_state->metadata_offset, len-client_state->metadata_offset);
- buf[0] = len_byte;
+ if (ret > 0 && ret < len) {
+ client_state->metadata_offset += ret;
+ }
+ else if (ret == len) {
+ client_state->metadata_age = source_age;
+ client_state->offset = 0;
+ client_state->metadata_offset = 0;
+ }
+ free (buf);
+ if (free_meta)
+ free (fullmetadata);
+ return ret;
- if (len > 1) {
- strncpy(buf+1, fullmetadata + client_state->metadata_offset, len-2);
- }
+ } while (0);
thread_mutex_unlock(&(source_state->lock));
-
- ret = sock_write_bytes(client->con->sock, buf, len);
-
- if(ret > 0 && ret < len) {
- client_state->metadata_offset += ret;
- }
- else if(ret == len) {
- client_state->metadata_age = source_age;
- client_state->offset = 0;
- client_state->metadata_offset = 0;
- }
-
- return ret;
+ if (free_meta)
+ free (fullmetadata);
+ return -1;
}
static int format_mp3_write_buf_to_client(format_plugin_t *self,
client_t *client, unsigned char *buf, int len)
{
int ret;
+ mp3_client_data *mp3data = client->format_data;
- if(((mp3_state *)self->_state)->metadata &&
- ((mp3_client_data *)(client->format_data))->use_metadata)
+ if(((mp3_state *)self->_state)->metadata && mp3data->use_metadata)
{
mp3_client_data *state = client->format_data;
int max = state->interval - state->offset;
@@ -363,6 +383,7 @@
http_var_t *var;
avl_node *node;
int bytes;
+ mp3_client_data *mp3data = client->format_data;
client->respcode = 200;
/* TODO: This may need to be ICY/1.0 for shoutcast-compatibility? */
@@ -402,7 +423,7 @@
}
avl_tree_unlock(source->parser->vars);
- if(((mp3_client_data *)(client->format_data))->use_metadata) {
+ if (mp3data->use_metadata) {
int bytes = sock_write(client->con->sock, "icy-metaint:%d\r\n",
ICY_METADATA_INTERVAL);
if(bytes > 0)
@@ -412,6 +433,6 @@
bytes = sock_write(client->con->sock,
"Server: %s\r\n", ICECAST_VERSION_STRING);
if (bytes > 0)
- client->con->sent_bytes += bytes;
+ client->con->sent_bytes += bytes;
}
<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