0
0
mirror of https://gitlab.xiph.org/xiph/icecast-server.git synced 2025-06-30 22:18:19 -04:00

- add_yp_info moved into yp.c

- all yp adds/touches are now done within a single thread.
  This should eliminate any "thread growth" issues and make
  things behave much nicer when yp problems arise.  We should
  eventually change the add/touches to non-blocking sockets,
  which will be needed for large numbers of streams doing adds/touches.

svn path=/trunk/icecast/; revision=5012
This commit is contained in:
oddsock 2003-06-26 13:33:55 +00:00
parent abb6cddbf0
commit 4b92ae2baa
2 changed files with 266 additions and 56 deletions

217
src/yp.c
View File

@ -16,7 +16,13 @@
#define CATMODULE "yp" #define CATMODULE "yp"
static int yp_submit_url(int curl_con, char *yp_url, char *url, char *type, int i) void yp_initialize()
{
thread_create("YP Touch Thread", yp_touch_thread,
(void *)NULL, THREAD_DETACHED);
}
static int yp_submit_url(int curl_con, char *yp_url, char *url, char *type,
int i)
{ {
int ret = 0; int ret = 0;
int timeout; int timeout;
@ -62,7 +68,7 @@ static int yp_submit_url(int curl_con, char *yp_url, char *url, char *type, int
void *yp_touch_thread(void *arg) void *yp_touch_thread(void *arg)
{ {
yp_touch((source_t *)arg); yp_touch();
thread_exit(0); thread_exit(0);
return NULL; return NULL;
} }
@ -113,7 +119,7 @@ int yp_remove(source_t *source)
} }
return 1; return 1;
} }
int yp_touch(source_t *source) int yp_touch()
{ {
char *url = NULL; char *url = NULL;
int url_size = 0; int url_size = 0;
@ -122,9 +128,54 @@ int yp_touch(source_t *source)
int i = 0; int i = 0;
int regen_sid = 0; int regen_sid = 0;
long current_time = 0; long current_time = 0;
avl_node *node;
source_t *source;
char current_song[256];
char tyme[128];
char *s;
while (global.running == ICE_RUNNING) {
avl_tree_rlock(global.source_tree);
node = avl_get_first(global.source_tree);
while (node) {
source = (source_t *)node->key;
current_time = time(NULL); current_time = time(NULL);
if (!source->yp_public) {
continue;
}
for (i=0; i<source->num_yp_directories; i++) { for (i=0; i<source->num_yp_directories; i++) {
if (current_time > (source->ypdata[i]->yp_last_touch +
source->ypdata[i]->yp_touch_interval)) {
current_song[0] = 0;
regen_sid = 0;
if ((s = (char *)stats_get_value(source->mount, "artist"))) {
strncat(current_song, s,
sizeof(current_song) - 1);
if (strlen(current_song) + 4 <
sizeof(current_song))
{
strncat(current_song, " - ", 3);
}
if (s) {
free(s);
}
}
if ((s = (char *)stats_get_value(source->mount, "title"))) {
if (strlen(current_song) + strlen(s)
< sizeof(current_song) -1)
{
strncat(current_song,
s,
sizeof(current_song) - 1 -
strlen(current_song));
}
if (s) {
free(s);
}
}
add_yp_info(source, "current_song", current_song,
YP_CURRENT_SONG);
source->ypdata[i]->yp_last_touch = current_time; source->ypdata[i]->yp_last_touch = current_time;
if (source->ypdata[i]->sid == 0) { if (source->ypdata[i]->sid == 0) {
regen_sid = 1; regen_sid = 1;
@ -135,17 +186,20 @@ int yp_touch(source_t *source)
} }
} }
if (regen_sid) { if (regen_sid) {
if (!yp_add(source, i)) { yp_add(source, i);
return 0;
}
} }
if (source->ypdata[i]->sid != 0) {
if (strlen(source->ypdata[i]->sid) != 0) {
if (source->ypdata) { if (source->ypdata) {
url_size = strlen("action=touch&sid=&st=&listeners=") + 1; url_size =
strlen("action=touch&sid=&st=&listeners=") + 1;
if (source->ypdata[i]->current_song) { if (source->ypdata[i]->current_song) {
url_size += strlen(source->ypdata[i]->current_song); url_size +=
strlen(source->ypdata[i]->current_song);
} }
else { else {
source->ypdata[i]->current_song = (char *)malloc(1); source->ypdata[i]->current_song =
(char *)malloc(1);
source->ypdata[i]->current_song[0] = 0; source->ypdata[i]->current_song[0] = 0;
} }
if (source->ypdata[i]->sid) { if (source->ypdata[i]->sid) {
@ -157,7 +211,8 @@ int yp_touch(source_t *source)
} }
url_size += 1024; url_size += 1024;
url = malloc(url_size); url = malloc(url_size);
sprintf(url, "action=touch&sid=%s&st=%s&listeners=%ld", sprintf(url,
"action=touch&sid=%s&st=%s&listeners=%ld",
source->ypdata[i]->sid, source->ypdata[i]->sid,
source->ypdata[i]->current_song, source->ypdata[i]->current_song,
source->listeners); source->listeners);
@ -168,7 +223,8 @@ int yp_touch(source_t *source)
} }
else { else {
/* specify URL to get */ /* specify URL to get */
ret = yp_submit_url(curl_con, source->ypdata[i]->yp_url, ret = yp_submit_url(curl_con,
source->ypdata[i]->yp_url,
url, "yp_touch", i); url, "yp_touch", i);
if (!ret) { if (!ret) {
source->ypdata[i]->sid[0] = 0; source->ypdata[i]->sid[0] = 0;
@ -178,8 +234,26 @@ int yp_touch(source_t *source)
free(url); free(url);
} }
curl_release_connection(curl_con); curl_release_connection(curl_con);
memset(tyme, '\000', sizeof(tyme));
strftime(tyme, 128, "%Y-%m-%d %H:%M:%S",
localtime(&current_time));
stats_event(source->mount, "yp_last_touch", tyme);
add_yp_info(source, "last_touch",
(void *)current_time,
YP_LAST_TOUCH);
} }
} }
}
}
}
node = avl_get_next(node);
}
avl_tree_unlock(global.source_tree);
thread_sleep(200000);
}
return 1; return 1;
} }
int yp_add(source_t *source, int which) int yp_add(source_t *source, int which)
@ -377,3 +451,124 @@ void yp_destroy_ypdata(ypdata_t *ypdata)
} }
} }
void add_yp_info(source_t *source, char *stat_name,
void *info, int type)
{
char *escaped;
int i;
if (!info) {
return;
}
for (i=0;i<source->num_yp_directories;i++) {
switch (type) {
case YP_SERVER_NAME:
escaped = util_url_escape(info);
if (escaped) {
if (source->ypdata[i]->server_name) {
free(source->ypdata[i]->server_name);
}
source->ypdata[i]->server_name =
malloc(strlen((char *)escaped) +1);
strcpy(source->ypdata[i]->server_name, (char *)escaped);
stats_event(source->mount, stat_name, (char *)info);
free(escaped);
}
break;
case YP_SERVER_DESC:
escaped = util_url_escape(info);
if (escaped) {
if (source->ypdata[i]->server_desc) {
free(source->ypdata[i]->server_desc);
}
source->ypdata[i]->server_desc =
malloc(strlen((char *)escaped) +1);
strcpy(source->ypdata[i]->server_desc, (char *)escaped);
stats_event(source->mount, stat_name, (char *)info);
free(escaped);
}
break;
case YP_SERVER_GENRE:
escaped = util_url_escape(info);
if (escaped) {
if (source->ypdata[i]->server_genre) {
free(source->ypdata[i]->server_genre);
}
source->ypdata[i]->server_genre =
malloc(strlen((char *)escaped) +1);
strcpy(source->ypdata[i]->server_genre, (char *)escaped);
stats_event(source->mount, stat_name, (char *)info);
free(escaped);
}
break;
case YP_SERVER_URL:
escaped = util_url_escape(info);
if (escaped) {
if (source->ypdata[i]->server_url) {
free(source->ypdata[i]->server_url);
}
source->ypdata[i]->server_url =
malloc(strlen((char *)escaped) +1);
strcpy(source->ypdata[i]->server_url, (char *)escaped);
stats_event(source->mount, stat_name, (char *)info);
free(escaped);
}
break;
case YP_BITRATE:
escaped = util_url_escape(info);
if (escaped) {
if (source->ypdata[i]->bitrate) {
free(source->ypdata[i]->bitrate);
}
source->ypdata[i]->bitrate =
malloc(strlen((char *)escaped) +1);
strcpy(source->ypdata[i]->bitrate, (char *)escaped);
stats_event(source->mount, stat_name, (char *)info);
free(escaped);
}
break;
case YP_AUDIO_INFO:
if (source->ypdata[i]->audio_info) {
free(source->ypdata[i]->audio_info);
}
source->ypdata[i]->audio_info =
malloc(strlen((char *)info) +1);
strcpy(source->ypdata[i]->audio_info, (char *)info);
break;
case YP_SERVER_TYPE:
escaped = util_url_escape(info);
if (escaped) {
if (source->ypdata[i]->server_type) {
free(source->ypdata[i]->server_type);
}
source->ypdata[i]->server_type =
malloc(strlen((char *)escaped) +1);
strcpy(source->ypdata[i]->server_type, (char *)escaped);
free(escaped);
}
break;
case YP_CURRENT_SONG:
escaped = util_url_escape(info);
if (escaped) {
if (source->ypdata[i]->current_song) {
free(source->ypdata[i]->current_song);
}
source->ypdata[i]->current_song =
malloc(strlen((char *)escaped) +1);
strcpy(source->ypdata[i]->current_song, (char *)escaped);
stats_event(source->mount, "yp_currently_playing",
(char *)info);
free(escaped);
}
break;
case YP_URL_TIMEOUT:
source->ypdata[i]->yp_url_timeout = (int)info;
break;
case YP_LAST_TOUCH:
source->ypdata[i]->yp_last_touch = (int)info;
break;
case YP_TOUCH_INTERVAL:
source->ypdata[i]->yp_touch_interval = (int)info;
break;
}
}
}

View File

@ -4,6 +4,18 @@
#include <stdio.h> #include <stdio.h>
#define YP_SERVER_NAME 1
#define YP_SERVER_DESC 2
#define YP_SERVER_GENRE 3
#define YP_SERVER_URL 4
#define YP_BITRATE 5
#define YP_AUDIO_INFO 6
#define YP_SERVER_TYPE 7
#define YP_CURRENT_SONG 8
#define YP_URL_TIMEOUT 9
#define YP_TOUCH_INTERVAL 10
#define YP_LAST_TOUCH 11
struct source_tag; struct source_tag;
#define YP_ADD_ALL -1 #define YP_ADD_ALL -1
@ -28,10 +40,13 @@ typedef struct ypdata_tag
void *yp_touch_thread(void *arg); void *yp_touch_thread(void *arg);
int yp_add(struct source_tag *source, int which); int yp_add(struct source_tag *source, int which);
int yp_touch(struct source_tag *source); int yp_touch();
int yp_remove(struct source_tag *psource); int yp_remove(struct source_tag *psource);
ypdata_t *yp_create_ypdata(); ypdata_t *yp_create_ypdata();
void yp_destroy_ypdata(ypdata_t *ypdata); void yp_destroy_ypdata(ypdata_t *ypdata);
void add_yp_info(struct source_tag *source, char *stat_name, void *info,
int type);
void yp_initialize();
#endif #endif