Commit 4b92ae2b authored by Ed "oddsock" Zaleski's avatar Ed "oddsock" Zaleski

- 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
parent abb6cddb
......@@ -16,7 +16,13 @@
#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 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)
{
yp_touch((source_t *)arg);
yp_touch();
thread_exit(0);
return NULL;
}
......@@ -113,7 +119,7 @@ int yp_remove(source_t *source)
}
return 1;
}
int yp_touch(source_t *source)
int yp_touch()
{
char *url = NULL;
int url_size = 0;
......@@ -122,64 +128,132 @@ int yp_touch(source_t *source)
int i = 0;
int regen_sid = 0;
long current_time = 0;
avl_node *node;
source_t *source;
char current_song[256];
char tyme[128];
char *s;
current_time = time(NULL);
for (i=0; i<source->num_yp_directories; i++) {
source->ypdata[i]->yp_last_touch = current_time;
if (source->ypdata[i]->sid == 0) {
regen_sid = 1;
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);
if (!source->yp_public) {
continue;
}
else {
if (strlen(source->ypdata[i]->sid) == 0) {
regen_sid = 1;
}
}
if (regen_sid) {
if (!yp_add(source, i)) {
return 0;
}
}
if (source->ypdata) {
url_size = strlen("action=touch&sid=&st=&listeners=") + 1;
if (source->ypdata[i]->current_song) {
url_size += strlen(source->ypdata[i]->current_song);
}
else {
source->ypdata[i]->current_song = (char *)malloc(1);
source->ypdata[i]->current_song[0] = 0;
}
if (source->ypdata[i]->sid) {
url_size += strlen(source->ypdata[i]->sid);
}
else {
source->ypdata[i]->sid = (char *)malloc(1);
source->ypdata[i]->sid[0] = 0;
}
url_size += 1024;
url = malloc(url_size);
sprintf(url, "action=touch&sid=%s&st=%s&listeners=%ld",
source->ypdata[i]->sid,
source->ypdata[i]->current_song,
source->listeners);
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);
curl_con = curl_get_connection();
if (curl_con < 0) {
ERROR0("Unable to get auth connection");
}
else {
/* specify URL to get */
ret = yp_submit_url(curl_con, source->ypdata[i]->yp_url,
url, "yp_touch", i);
if (!ret) {
source->ypdata[i]->sid[0] = 0;
source->ypdata[i]->yp_last_touch = current_time;
if (source->ypdata[i]->sid == 0) {
regen_sid = 1;
}
else {
if (strlen(source->ypdata[i]->sid) == 0) {
regen_sid = 1;
}
}
if (regen_sid) {
yp_add(source, i);
}
if (source->ypdata[i]->sid != 0) {
if (strlen(source->ypdata[i]->sid) != 0) {
if (source->ypdata) {
url_size =
strlen("action=touch&sid=&st=&listeners=") + 1;
if (source->ypdata[i]->current_song) {
url_size +=
strlen(source->ypdata[i]->current_song);
}
else {
source->ypdata[i]->current_song =
(char *)malloc(1);
source->ypdata[i]->current_song[0] = 0;
}
if (source->ypdata[i]->sid) {
url_size += strlen(source->ypdata[i]->sid);
}
else {
source->ypdata[i]->sid = (char *)malloc(1);
source->ypdata[i]->sid[0] = 0;
}
url_size += 1024;
url = malloc(url_size);
sprintf(url,
"action=touch&sid=%s&st=%s&listeners=%ld",
source->ypdata[i]->sid,
source->ypdata[i]->current_song,
source->listeners);
curl_con = curl_get_connection();
if (curl_con < 0) {
ERROR0("Unable to get auth connection");
}
else {
/* specify URL to get */
ret = yp_submit_url(curl_con,
source->ypdata[i]->yp_url,
url, "yp_touch", i);
if (!ret) {
source->ypdata[i]->sid[0] = 0;
}
}
if (url) {
free(url);
}
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);
}
}
}
}
if (url) {
free(url);
}
curl_release_connection(curl_con);
}
node = avl_get_next(node);
}
avl_tree_unlock(global.source_tree);
thread_sleep(200000);
}
return 1;
}
int yp_add(source_t *source, int which)
......@@ -311,7 +385,7 @@ int yp_add(source_t *source, int which)
source->ypdata[i]->sid = NULL;
}
source->ypdata[i]->sid = (char *)malloc(
strlen(curl_get_header_result(curl_con)->
strlen(curl_get_header_result(curl_con)->
sid) +1);
strcpy(source->ypdata[i]->sid,
curl_get_header_result(curl_con)->sid);
......@@ -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;
}
}
}
......@@ -4,6 +4,18 @@
#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;
#define YP_ADD_ALL -1
......@@ -28,10 +40,13 @@ typedef struct ypdata_tag
void *yp_touch_thread(void *arg);
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);
ypdata_t *yp_create_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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment