Пример #1
0
void foo(void)
{
  ENTER_FUNC();
  static int z = 350;
  int q = 450;

  if (!kitsune_is_updating()) {
    y = 202;
    z = 302;
    q = 402;
  }

  NOTE_AND_MIGRATE_STATIC(y);
  NOTE_AND_MIGRATE_LOCAL_STATIC(foo, z);
  NOTE_AND_MIGRATE_LOCAL(q);

  if (kitsune_is_updating()) {
    assert(y == 207);
    assert(z == 307);
    assert(q == 407);
    printf("Sucesss...\n");
  }

  kitsune_update("test");
  EXIT_FUNC();
  return;
}
Пример #2
0
static void
parse_username_password(struct vsf_session* p_sess)
{
  while (1)
  {
    /* Kitsune: update point */
		kitsune_update("prelogin.c"); /**DSU updatepoint */
    /* Kitsune */  
    vsf_sysutil_kitsune_set_update_point("prelogin.c");
    
    vsf_cmdio_get_cmd_and_arg(p_sess, &p_sess->ftp_cmd_str,
                              &p_sess->ftp_arg_str, 1);
    if (str_equal_text(&p_sess->ftp_cmd_str, "USER"))
    {
      handle_user_command(p_sess);
    }
    else if (str_equal_text(&p_sess->ftp_cmd_str, "PASS"))
    {
      handle_pass_command(p_sess);
    }
    else if (str_equal_text(&p_sess->ftp_cmd_str, "QUIT"))
    {
      vsf_cmdio_write(p_sess, FTP_GOODBYE, "Goodbye.");
      vsf_sysutil_exit(0);
    }
    else
    {
      vsf_cmdio_write(p_sess, FTP_LOGINERR,
                      "Please login with USER and PASS.");
    }
  }
}
Пример #3
0
int main(int argc, char **argv) 
{
  if (!kitsune_is_updating()) {
    l = malloc(sizeof(struct list));
    l->dummy = 5;
    l->data0 = malloc(sizeof(int));
    (*(int *)l->data0) = 16;
    l->data1 = NULL;
    l->data2 = (void *)123; /* testing migration of opaque pointer */
    l->next = l;
  }

  MIGRATE_GLOBAL(l);
  MIGRATE_GLOBAL(l2);
    
  if (kitsune_is_updating()) {
    assert(l->dummy == 5);
    assert(l->data0 != NULL && *(int *)l->data0 == 16);
    assert(l->data1 == NULL);
    assert(l->data2 == (void *)123);
    assert(l->next == l);    
    assert(l2 == NULL);    
    printf("Sucesss...\n");
  } else {
    kitsune_signal_update();    
    kitsune_set_next_version(strdup(argv[1]));
  }

  kitsune_update("main");
  return 0;
}
Пример #4
0
void aeMain(aeEventLoop *eventLoop) {
    eventLoop->stop = 0;
    while (!eventLoop->stop) {
      kitsune_update("main_loop"); /**DSU updatepoint */
        if (eventLoop->beforesleep != NULL)
            eventLoop->beforesleep(eventLoop);
        aeProcessEvents(eventLoop, AE_ALL_EVENTS);
    }
}
Пример #5
0
int main(int argc, char **argv)
{

  printf("Inside main.c\n");

  //these 2 calls are no-ops in main.c
  kitsune_do_automigrate();
  kitsune_update("main"); 

  node = (PreprocPostConfigFuncNode *)malloc(sizeof(PreprocPostConfigFuncNode));
  node->data = (int*)7; 
  node->unionfptr.fptr = foo;
  printf("main.c: this should be foo: %p, and foo is = %p\n", node->unionfptr.fptr, foo);

  kitsune_signal_update();    
  kitsune_set_next_version(strdup(argv[1]));
  kitsune_update("main"); // this update point will jump to other version
  return 0;
}
Пример #6
0
static void *yp_update_thread(void *arg)
{
    if (!kitsune_is_updating()) { /**DSU control */
        INFO0("YP update thread started");
        yp_running = 1;
    }

    while (yp_running)
    {
      kitsune_update("yp_update"); /**DSU updatepoint */
        struct yp_server *server;

        thread_sleep (200000);

        /* do the YP communication */
        thread_rwlock_rlock (&yp_lock);
        server = (struct yp_server *)active_yps;
        while (server)
        {
            /* DEBUG1 ("trying %s", server->url); */
            yp_process_server (server);
            server = server->next;
        }
        thread_rwlock_unlock (&yp_lock);

        /* update the local YP structure */
        if (yp_update)
        {
            thread_rwlock_wlock (&yp_lock);
            check_servers ();
            server = (struct yp_server *)active_yps;
            while (server)
            {
                /* DEBUG1 ("Checking yps %s", server->url); */
                add_pending_yp (server);
                delete_marked_yp (server);
                server = server->next;
            }
            yp_update = 0;
            thread_rwlock_unlock (&yp_lock);
        }
    }
    thread_rwlock_destroy (&yp_lock);
    thread_mutex_destroy (&yp_pending_lock);
    /* free server and ypdata left */
    while (active_yps)
    {
        struct yp_server *server = (struct yp_server *)active_yps;
        active_yps = server->next;
        destroy_yp_server (server);
    }

    return NULL;
}
Пример #7
0
int main(int argc, char **argv)
{
  if (!kitsune_is_updating()) {
    x = 101;
  }
   
  if (kitsune_is_updating()) {
    assert(x == 106);
    printf("Sucesss...\n");
  } else {
    kitsune_signal_update();    
    kitsune_set_next_version(strdup(argv[1]));
    kitsune_update("test");
  }
  return 0;
}
Пример #8
0
void
vsf_priv_parent_postlogin(struct vsf_session* p_sess)
{
  /* Kitsune */
	if (!kitsune_is_updating()) {
  	minimize_privilege(p_sess);
	} else {
    /* Set sigchld function pointer (normally done in twoprocess.c) */    
    vsf_sysutil_default_sig(kVSFSysUtilSigCHLD);
    vsf_sysutil_install_async_sighandler(kVSFSysUtilSigCHLD, twoproc_handle_sigchld);
  }
  /* End Kitsune */

  /* We're still here... */
  while (1)
  {
	  kitsune_update("postprivparent.c"); /**DSU updatepoint */
    process_post_login_req(p_sess);
  }
}
Пример #9
0
int main(int argc, char **argv)
{   
  if (kitsune_is_updating()) {
    printf("Updating...\n");
    assert(argc == 4);
    assert(!strcmp(argv[2], "b"));
    assert(!strcmp(argv[3], "c"));
    printf("Success.\n");
  } else {
    printf("Non-updating...\n");
    assert(argc == 4);
    assert(!strcmp(argv[2], "b"));
    assert(!strcmp(argv[3], "c"));

    kitsune_signal_update();    
    kitsune_set_next_version(strdup(argv[1]));
  }

  kitsune_update("test");
  return 0;
}
Пример #10
0
void handle_client(int client)
{
    const int line_size = 1000;
    char * line = calloc(sizeof(char), line_size);
    const char *delim = " \n";
    char *command = NULL, *arg1 = NULL, *arg2 = NULL, *savptr = NULL;

    while (1) {
        kitsune_update("client");

        memset(line, 0, line_size);
        recv(client, line, line_size, 0);

        /* parse command */
        command = strtok_r(line, delim, &savptr);
        if (command == NULL)        /* client sent EOF */
            break;
        arg1 = strtok_r(NULL, delim, &savptr);
        if (strcmp("set", command) == 0)
            arg2 = strtok_r(NULL, delim, &savptr);

        /* handle */
        if (strcmp("set", command) == 0) {
            ENTRY e, *ret = NULL;
            e.key = strdup(arg1);
            e.data = strdup(arg2);
            hsearch_r(e, ENTER, &ret, store);
        } else if (strcmp("get", command) == 0) {
            ENTRY *ret = NULL, e;
            e.key = strdup(arg1);
            hsearch_r(e, FIND, &ret, store);
            if (ret == NULL)
                continue;
            sprintf(line, "%s\n", (char *)ret->data);
            send(client, line, strlen(line) + 1, 0);
        }
    }
    close(client);
}
Пример #11
0
int main(int argc, char *argv[]) {
  char *substr_ptr, *kitsune_app_name;
  
  if (kitsune_is_updating()) {
    printf("Starting up following update.\n");
    kitsune_log("LOG ENTRY 2");

    /* try to open the logfile */
    substr_ptr = strstr(argv[0], ".so");
    if (substr_ptr == NULL) {
      /* the application name didn't use the shared object prefix; use the raw
         name */
      kitsune_app_name = strdup(basename(argv[0]));
    } else {
      argv[0][substr_ptr - argv[0]] = '\0';
      kitsune_app_name = strdup(basename(argv[0]));
    }

    char *logname = malloc(sizeof(char) * 128);
    snprintf(logname, sizeof(char) * 128, 
             "/tmp/kitsune/%s.%d", kitsune_app_name, getpid());
    FILE *logfile = fopen(logname, "r");
    assert(logfile);
    fclose(logfile);    
    assert(unlink(logname) == 0);
    printf("Success!\n");

  } else {
    printf("Starting up normally.\n");
    kitsune_log("LOG ENTRY 1");
    kitsune_signal_update();    
    kitsune_set_next_version(strdup(argv[1]));
  }
  kitsune_update("test");
  return 0;
}
Пример #12
0
void
process_post_login(struct vsf_session* p_sess)
{
  int retval;

  if (p_sess->is_anonymous)
  {
    vsf_sysutil_set_umask(tunable_anon_umask);
    p_sess->bw_rate_max = tunable_anon_max_rate;
  }
  else
  {
    vsf_sysutil_set_umask(tunable_local_umask);
    p_sess->bw_rate_max = tunable_local_max_rate;
  }
  if (tunable_async_abor_enable)
  {
    vsf_sysutil_install_sighandler(kVSFSysUtilSigURG, handle_sigurg, p_sess);
    vsf_sysutil_activate_sigurg(VSFTP_COMMAND_FD);
  }

  /* Kitsune */	
  vsf_sysutil_kitsune_set_update_point("postlogin.c");
  if(!kitsune_is_updating()) {
    /* Handle any login message */
    vsf_banner_dir_changed(p_sess, FTP_LOGINOK);
    vsf_cmdio_write(p_sess, FTP_LOGINOK, "Login successful. Have fun.");
	} else {
    /* Set sigchld function pointer (normally done in twoprocess.c) */    
    vsf_sysutil_default_sig(kVSFSysUtilSigCHLD);
    vsf_sysutil_install_async_sighandler(kVSFSysUtilSigCHLD, twoproc_handle_sigchld);
  }
  /* End Kitsune */

  while(1)
  {
    if (tunable_setproctitle_enable)
    {
      vsf_sysutil_setproctitle("IDLE");
    }

		/* Kitsune update point */
    kitsune_update("postlogin.c");  /**DSU updatepoint */
    
    /* Blocks */
	  vsf_cmdio_get_cmd_and_arg(p_sess, &p_sess->ftp_cmd_str,
	                            &p_sess->ftp_arg_str, 1);
	  if (tunable_setproctitle_enable)
	  {
	    struct mystr proctitle_str = INIT_MYSTR;
	    str_copy(&proctitle_str, &p_sess->ftp_cmd_str);
	    if (!str_isempty(&p_sess->ftp_arg_str))
	    {
	      str_append_char(&proctitle_str, ' ');
	      str_append_str(&proctitle_str, &p_sess->ftp_arg_str);
	    }
	    /* Suggestion from Solar */
	    str_replace_unprintable(&proctitle_str, '?');
	    vsf_sysutil_setproctitle_str(&proctitle_str);
	    str_free(&proctitle_str);
	  }
	  if (str_equal_text(&p_sess->ftp_cmd_str, "QUIT"))
	  {
	    vsf_cmdio_write(p_sess, FTP_GOODBYE, "Goodbye.");
	    vsf_sysutil_exit(0);
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "PWD") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "XPWD"))
	  {
	    handle_pwd(p_sess);
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "CWD") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "XCWD"))
	  {
	    handle_cwd(p_sess);
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "CDUP") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "XCUP"))
	  {
	    handle_cdup(p_sess);
	  }
	  else if (tunable_pasv_enable &&
	           str_equal_text(&p_sess->ftp_cmd_str, "PASV"))
	  {
	    handle_pasv(p_sess);
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "RETR"))
	  {
	    handle_retr(p_sess);
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "NOOP"))
	  {
	    vsf_cmdio_write(p_sess, FTP_NOOPOK, "NOOP ok.");
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "SYST"))
	  {
	    vsf_cmdio_write(p_sess, FTP_SYSTOK, "UNIX Type: L8");
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "HELP"))
	  {
	    vsf_cmdio_write(p_sess, FTP_BADHELP, "Sorry, I don't have help.");
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "LIST"))
	  {
	    handle_list(p_sess);
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "TYPE"))
	  {
	    handle_type(p_sess);
	  }
	  else if (tunable_port_enable &&
	           str_equal_text(&p_sess->ftp_cmd_str, "PORT"))
	  {
	    handle_port(p_sess);
	  }
	  else if (tunable_write_enable &&
	           (tunable_anon_upload_enable || !p_sess->is_anonymous) &&
	           str_equal_text(&p_sess->ftp_cmd_str, "STOR"))
	  {
	    handle_stor(p_sess);
	  }
	  else if (tunable_write_enable &&
	           (tunable_anon_mkdir_write_enable || !p_sess->is_anonymous) &&
	           (str_equal_text(&p_sess->ftp_cmd_str, "MKD") ||
	            str_equal_text(&p_sess->ftp_cmd_str, "XMKD")))
	  {
	    handle_mkd(p_sess);
	  }
	  else if (tunable_write_enable &&
	           (tunable_anon_other_write_enable || !p_sess->is_anonymous) &&
	           (str_equal_text(&p_sess->ftp_cmd_str, "RMD") ||
	            str_equal_text(&p_sess->ftp_cmd_str, "XRMD")))
	  {
	    handle_rmd(p_sess);
	  }
	  else if (tunable_write_enable &&
	           (tunable_anon_other_write_enable || !p_sess->is_anonymous) &&
	           str_equal_text(&p_sess->ftp_cmd_str, "DELE"))
	  {
	    handle_dele(p_sess);
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "REST"))
	  {
	    handle_rest(p_sess);
	  }
	  else if (tunable_write_enable &&
	           (tunable_anon_other_write_enable || !p_sess->is_anonymous) &&
	           str_equal_text(&p_sess->ftp_cmd_str, "RNFR"))
	  {
	    handle_rnfr(p_sess);
	  }
	  else if (tunable_write_enable &&
	           (tunable_anon_other_write_enable || !p_sess->is_anonymous) &&
	           str_equal_text(&p_sess->ftp_cmd_str, "RNTO"))
	  {
	    handle_rnto(p_sess);
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "NLST"))
	  {
	    handle_nlst(p_sess);
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "SIZE"))
	  {
	    handle_size(p_sess);
	  }
	  else if (!p_sess->is_anonymous &&
	           str_equal_text(&p_sess->ftp_cmd_str, "SITE"))
	  {
	    handle_site(p_sess);
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "ABOR"))
	  {
	    vsf_cmdio_write(p_sess, FTP_ABOR_NOCONN, "No transfer to ABOR.");
	  }
	  else if (tunable_write_enable &&
	           (tunable_anon_other_write_enable || !p_sess->is_anonymous) &&
	           str_equal_text(&p_sess->ftp_cmd_str, "APPE"))
	  {
	    handle_appe(p_sess);
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "MDTM"))
	  {
	    handle_mdtm(p_sess);
	  }
	  else if (str_equal_text(&p_sess->ftp_cmd_str, "PASV") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "PORT") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "STOR") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "MKD") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "XMKD") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "RMD") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "XRMD") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "DELE") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "RNFR") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "RNTO") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "SITE") ||
	           str_equal_text(&p_sess->ftp_cmd_str, "APPE"))
	  {
	    vsf_cmdio_write(p_sess, FTP_NOPERM, "Permission denied.");
	  }
	  else
	  {
	    vsf_cmdio_write(p_sess, FTP_BADCMD, "Unknown command.");
	  }
	}

}
Пример #13
0
    /* Continue the processing loop.. */
    return;
  }
  else
  {
    die("priv_sock_get_result");
  }
}

int
vsf_two_process_get_priv_data_sock(struct vsf_session* p_sess)
{
  char res;
  priv_sock_send_cmd(p_sess, PRIV_SOCK_GET_DATA_SOCK);
  res = priv_sock_get_result(p_sess);
  if (res != PRIV_SOCK_RESULT_OK)
  {
    die("could not get privileged socket");
  }
  return priv_sock_child_recv_fd(p_sess);
}

void
vsf_two_process_chown_upload(struct vsf_session* p_sess, int fd)
{
  char res;
  priv_sock_send_cmd(p_sess, PRIV_SOCK_CHOWN);
  priv_sock_child_send_fd(p_sess, fd);
  res = priv_sock_get_result(p_sess);
  if (res != PRIV_SOCK_RESULT_OK)
  {
    die("unexpected failure in vsf_two_process_chown_upload");
  }
}

//static /* Kitsune, make visible to facilitate updating */ 
void
process_login_req(struct vsf_session* p_sess)
{
  enum EVSFPrivopLoginResult e_login_result = kVSFLoginNull;
  if (!kitsune_is_updating()) {  /* Kitsune */
    /* Blocks */
    if (priv_sock_get_cmd(p_sess) != PRIV_SOCK_LOGIN)
    {
      die("bad request");
    }
  }

  /* Kitsune, update point */
  kitsune_update("twoprocess.c"); /**DSU updatepoint */
  /* Kitsune, allow updating from blocking loop */
  vsf_sysutil_kitsune_set_update_point("twoprocess.c");  

  /* Get username and password - we must distrust these */
  {
    struct mystr password_str = INIT_MYSTR;
    priv_sock_get_str(p_sess, &p_sess->user_str);
    priv_sock_get_str(p_sess, &password_str);
    e_login_result = vsf_privop_do_login(p_sess, &password_str);
    str_free(&password_str);
  }
  switch (e_login_result)
  {
    case kVSFLoginFail:
      priv_sock_send_result(p_sess, PRIV_SOCK_RESULT_BAD);
      return;
      break;
    case kVSFLoginAnon:
      str_alloc_text(&p_sess->user_str, tunable_ftp_username);
      common_do_login(p_sess, &p_sess->user_str, 1, 1);
      break;
    case kVSFLoginReal:
      {
        int do_chroot = 0;
        if (tunable_chroot_local_user)
        {
          do_chroot = 1;
        }
        if (tunable_chroot_list_enable)
        {
          struct mystr chroot_list_file = INIT_MYSTR;
          int retval = str_fileread(&chroot_list_file,
                                    tunable_chroot_list_file,
                                    VSFTP_CONF_FILE_MAX);
          if (vsf_sysutil_retval_is_error(retval))
          {
            die("cannot open chroot() user list file");
          }
          if (str_contains_line(&chroot_list_file, &p_sess->user_str))
          {
            if (do_chroot)
            {
              do_chroot = 0;
            }
            else
            {
              do_chroot = 1;
            }
          }
          str_free(&chroot_list_file);
        }
        common_do_login(p_sess, &p_sess->user_str, do_chroot, 0);
      }
      break;
    default:
      bug("weird state in process_login_request");
      break;
  }
  /* NOTREACHED */
}
Пример #14
0
/* Connection thread. Here we take clients off the connection queue and check
 * the contents provided. We set up the parser then hand off to the specific
 * request handler.
 */
static void *_handle_connection(void *arg)
{
    http_parser_t *parser;
    char *rawuri, *uri;

    while (global.running == ICE_RUNNING) {

      kitsune_update("connection_handle"); /**DSU updatepoint */

        client_queue_t *node = _get_connection();

        if (node)
        {
            client_t *client = node->client;

            /* Check for special shoutcast compatability processing */
            if (node->shoutcast) 
            {
                _handle_shoutcast_compatible (node);
                continue;
            }

            /* process normal HTTP headers */
            parser = httpp_create_parser();
            httpp_initialize(parser, NULL);
            client->parser = parser;
            if (httpp_parse (parser, client->refbuf->data, node->offset))
            {
                /* we may have more than just headers, so prepare for it */
                if (node->stream_offset == node->offset)
                    client->refbuf->len = 0;
                else
                {
                    char *ptr = client->refbuf->data;
                    client->refbuf->len = node->offset - node->stream_offset;
                    memmove (ptr, ptr + node->stream_offset, client->refbuf->len);
                }
                free (node);
                
                if (strcmp("ICE",  httpp_getvar(parser, HTTPP_VAR_PROTOCOL)) &&
                    strcmp("HTTP", httpp_getvar(parser, HTTPP_VAR_PROTOCOL))) {
                    ERROR0("Bad HTTP protocol detected");
                    client_destroy (client);
                    continue;
                }

                rawuri = httpp_getvar(parser, HTTPP_VAR_URI);
                uri = util_normalise_uri(rawuri);

                if (uri == NULL)
                {
                    client_destroy (client);
                    continue;
                }

                if (parser->req_type == httpp_req_source) {
                    _handle_source_request (client, uri, ICECAST_SOURCE_AUTH);
                }
                else if (parser->req_type == httpp_req_stats) {
                    _handle_stats_request (client, uri);
                }
                else if (parser->req_type == httpp_req_get) {
                    _handle_get_request (client, uri);
                }
                else {
                    ERROR0("Wrong request type from client");
                    client_send_400 (client, "unknown request");
                }

                free(uri);
            } 
            else
            {
                free (node);
                ERROR0("HTTP request parsing failed");
                client_destroy (client);
            }
            continue;
        }
        thread_sleep (50000);
    }
    DEBUG0 ("Connection thread done");

    return NULL;
}
Пример #15
0
void connection_accept_loop(void)
{
    connection_t *con;

    if (!kitsune_is_updating()) /**DSU control */
        tid = thread_create("connection thread", _handle_connection, NULL, THREAD_ATTACHED);

    while (global.running == ICE_RUNNING)
    {
      kitsune_update("connection_accept"); /**DSU updatepoint */

        con = _accept_connection();

        if (con)
        {
            client_queue_t *node;
            ice_config_t *config;
            int i;
            client_t *client = NULL;

            global_lock();
            if (client_create (&client, con, NULL) < 0)
            {
                global_unlock();
                client_send_404 (client, "Icecast connection limit reached");
                continue;
            }
            global_unlock();

            /* setup client for reading incoming http */
            client->refbuf->data [PER_CLIENT_REFBUF_SIZE-1] = '\000';

            node = calloc (1, sizeof (client_queue_t));
            if (node == NULL)
            {
                client_destroy (client);
                continue;
            }
            node->client = client;

            /* Check for special shoutcast compatability processing */
            config = config_get_config();
            for (i = 0; i < global.server_sockets; i++)
            {
                if (global.serversock[i] == con->serversock)
                {
                    if (config->listeners[i].shoutcast_compat)
                        node->shoutcast = 1;
                }
            }
            config_release_config(); 

            sock_set_blocking (client->con->sock, SOCK_NONBLOCK);
            sock_set_nodelay (client->con->sock);

            _add_request_queue (node);
            stats_event_inc (NULL, "connections");
        }
        process_request_queue ();
    }

    /* Give all the other threads notification to shut down */
    thread_cond_broadcast(&global.shutdown_cond);

    if (tid)
        thread_join (tid);

    /* wait for all the sources to shutdown */
    thread_rwlock_wlock(&_source_shutdown_rwlock);
    thread_rwlock_unlock(&_source_shutdown_rwlock);
}
Пример #16
0
static void *_stats_thread(void *arg)
{
    stats_event_t *event;
    stats_event_t *copy;
    event_listener_t *listener;

    if (!kitsune_is_updating()) { /**DSU control */
        stats_event (NULL, "server", ICECAST_VERSION_STRING);
        stats_event_time (NULL, "server_start");

        /* global currently active stats */
        stats_event (NULL, "clients", "0");
        stats_event (NULL, "connections", "0");
        stats_event (NULL, "sources", "0");
        stats_event (NULL, "stats", "0");
        
        /* global accumulating stats */
        stats_event (NULL, "client_connections", "0");
        stats_event (NULL, "source_client_connections", "0");
        stats_event (NULL, "source_relay_connections", "0");
        stats_event (NULL, "source_total_connections", "0");
        stats_event (NULL, "stats_connections", "0");
        stats_event (NULL, "listener_connections", "0");
        INFO0 ("stats thread started");
    }

    while (_stats_running) {
      kitsune_update("stats"); /**DSU updatepoint */
        if (_global_event_queue != NULL) {
            /* grab the next event from the queue */
            thread_mutex_lock(&_global_event_mutex);
            event = (stats_event_t *)_global_event_queue;
            _global_event_queue = event->next;
            thread_mutex_unlock(&_global_event_mutex);

            event->next = NULL;

            thread_mutex_lock(&_stats_mutex);

            /* check if we are dealing with a global or source event */
            if (event->source == NULL)
                process_global_event (event);
            else
                process_source_event (event);
            
            /* now we have an event that's been processed into the running stats */
            /* this event should get copied to event listeners' queues */
            listener = (event_listener_t *)_event_listeners;
            while (listener) {
                copy = _copy_event(event);
                thread_mutex_lock(listener->mutex);
                _add_event_to_queue(copy, listener->queue);
                thread_mutex_unlock(listener->mutex);

                listener = listener->next;
            }

            /* now we need to destroy the event */
            _free_event(event);

            thread_mutex_unlock(&_stats_mutex);
            continue;
        }

        thread_sleep(300000);
    }

    return NULL;
}