Пример #1
0
void mainloop(const bool &Exit)
{
   unsigned char skipped = 0;
   for (;!Exit;)
   {
      if (skipped < temp.frameskip)
      {
          skipped++;
          temp.vidblock = 1;
      }
      else
          skipped = temp.vidblock = 0;

      if (!temp.vidblock)
          flip();

      for (unsigned f = rsm.needframes[rsm.frame]; f; f--)
      {
         temp.sndblock = !conf.sound.enabled;
         temp.inputblock = temp.vidblock && conf.sound.enabled;
         spectrum_frame();
         VideoSaver();

         // message handling before flip (they paint to rbuf)
         if (!temp.inputblock)
         {
             dispatch(conf.atm.xt_kbd ? ac_main_xt : ac_main);
         }
         if (!temp.sndblock)
         {
             do_sound();
             Vs1001.Play();
         }
         if (rsm.mix_frames > 1)
         {
            memcpy(rbuf_s + rsm.rbuf_dst * rb2_offs, rbuf, temp.scx * temp.scy / 4);
            if (++rsm.rbuf_dst == rsm.mix_frames)
                rsm.rbuf_dst = 0;
         }
         if (!temp.sndblock)
         {
/*
             if(conf.sound.do_sound == do_sound_none)
                 do_idle();
*/
         }
      }

      if (++rsm.frame == rsm.period)
          rsm.frame = 0;

   }
   correct_exit();
}
Пример #2
0
int main(int argc, char *argv[]) {
    pthread_attr_t pthread_attr;
    int   opt,               /* Буфер для распознания опций argv через getopt */
          opt_t = 0;         /* Указан ли ключ '-t' */
    int null_fd;
    int rc;                 /* return code */
    
    #if CATCH_SIGNAL
        struct sigaction sa;
        sigset_t         sa_set;
    #endif
    
    #ifdef NDEBUG
        pid_t pid, sid;
        /* Отделяемся от родительского процесса */
        pid = fork();
    
        /* Если не проходит даже форк - значит дела совсем плохи -
         * завершаем работу тут же. */
        if (pid < 0) {
            perror("fork()");
            exit(EXIT_FAILURE);
        }
    
        /* Если дочерний процесс порождён успешно, то родительский процесс можно завершить. */
        if (pid > 0) { exit(EXIT_SUCCESS); }
    #endif

    /* Открытие журнала на запись */
    openlog(SELF_NAME, LOG_ODELAY|LOG_PERROR|LOG_PID, LOG_DAEMON);

    #ifdef NDEBUG
        /* Создание нового SID для дочернего процесса */
        sid = setsid();
        /* Если получить sid не удалось - пытаемся сделать это ещё SETSID_ATEMPTS_COUNT раз */
        TRY_N_TIMES(SETSID_ATEMPTS_COUNT, (sid = setsid()), (sid < 0), "setsid()", LOG_CRIT);
        /* Если после вышеописанных попыток sid всё равно не получен - завершаем работу. */
        if (sid < 0) {
            syslog(LOG_EMERG, "setsid(): %s.", strerror(errno));
            exit(EXIT_FAILURE);
        }
    #endif

    #if CATCH_SIGNAL
        sigemptyset(&sa_set);
        sigaddset(&sa_set, SIGHUP);
        sigprocmask(SIG_BLOCK, &sa_set, 0);

        sa.sa_mask    = sa_set;
        sa.sa_flags   = SA_NOMASK;
        sa.sa_handler = correct_exit;

        sigaction(SIGTSTP, &sa, 0);
        sigaction(SIGINT,  &sa, 0);
        sigaction(SIGTERM, &sa, 0);
        sigaction(SIGQUIT, &sa, 0);
    #endif
    
    /* Изменяем файловую маску */
    umask(0);
    
    /* Изменяем текущий рабочий каталог */
    if (chdir("/") < 0) {
        syslog(LOG_WARNING, "chdir(): %s.", strerror(errno));
    }
    
    /* Закрываем стандартные файловые дескрипторы - 
     * теперь вместо них будет /dev/null            */
    null_fd = open(DEV_NULL_PATH, O_RDWR | O_NONBLOCK);
    if(null_fd < 0){
        syslog(LOG_EMERG, "open(\""DEV_NULL_PATH"\"): %s.", strerror(errno));
        exit(EXIT_FAILURE);
    }
    close_and_dup_stdfd(STDIN_FILENO,  null_fd);
    #ifdef NDEBUG
        close_and_dup_stdfd(STDOUT_FILENO, null_fd);
        close_and_dup_stdfd(STDERR_FILENO, null_fd);
    #endif
    
    /* Заполним страктуру значениями по-умолчанию */
    /*  server_pool.be_verbose    = 0;  */
        server_pool.threads_count = DEFAULT_THREADS_COUNT;
    
    /* Проверим все переданные аргументы */
    while ((opt = getopt(argc, argv, "vt:")) != -1) {
        switch (opt) {
            case 'v':    /* verbose */
                server_pool.be_verbose = 1;
                break;
            /*case 'c':     cache file path
                break;*/
            case 't':    /* thread count */
                server_pool.threads_count = atoi(optarg);
                opt_t = 1;
                if(server_pool.threads_count < 1){
                    syslog(LOG_WARNING, "Threads count incorrect."
                        "Use default: " DEFAULT_THREADS_COUNT_S);
                }
                break;
            default:    /* '?' */
                break;
        }
    }
    if(opt_t == 0 && server_pool.be_verbose){
        syslog(LOG_NOTICE, "Threads count not specified. "
            "Use default: " DEFAULT_THREADS_COUNT_S);
    }
    /* Получаем адрес сервера. */
    if (optind >= argc) {
        if(server_pool.be_verbose){
            syslog(LOG_NOTICE, "Server addres not specified. "
                "Use default: '" DEFAULT_SERVER_ADDR "'");
        }
        strncpy(server_pool.server_addr, DEFAULT_SERVER_ADDR, MAX_SERVER_ADDR_SIZE);
    }
    else{
        strncpy(server_pool.server_addr, argv[optind], MAX_SERVER_ADDR_SIZE);
    }
    
    /* Инициализируем барьер. */
    if(pthread_barrier_init(&server_pool.proxy_barr, NULL,
                          server_pool.threads_count + 1)
    ){
        syslog(LOG_ERR, "Error in barrier creating.");
        server_pool.no_barr = 1;
    }
    else{
        server_pool.no_barr = 0;
    }
    
    /* Резервируем место под нити */
    server_pool.tids = (pthread_t *) malloc(sizeof(pthread_t) * server_pool.threads_count);
    
    server_pool.context = zmq_ctx_new();
    server_pool.clients = zmq_socket(server_pool.context, ZMQ_ROUTER);
    server_pool.workers = zmq_socket(server_pool.context, ZMQ_DEALER);
    zmq_bind(server_pool.clients, server_pool.server_addr);
    zmq_bind(server_pool.workers, ZMQ_INPROC_ADDR);
    
    pthread_attr_init(&pthread_attr);
    pthread_attr_setdetachstate(&pthread_attr, PTHREAD_CREATE_DETACHED);
        /* sync pthread init */
        if(pthread_create(&server_pool.sync_tid, &pthread_attr, &thread_synchronizer, NULL) != 0){
            syslog(LOG_EMERG, "Error in sync thread creating.");
            correct_exit();
        }
        
        /* cmd pthread init */
        
        /* client pthreads init */
        for(int i = 0; i < server_pool.threads_count; i++){
            if(pthread_create(&server_pool.tids[i], &pthread_attr, &thread_operator, (void *) i) != 0){
                syslog(LOG_EMERG, "Error in thread creating.");
                correct_exit();
            }
        }
    pthread_attr_destroy(&pthread_attr);
    
    if(server_pool.be_verbose){
        syslog(LOG_INFO, "Initialize complete. Start main cycle.");
    }
    
    /* Перед запуском zmq_proxy необходимо открыть все нужные сокеты.
     * Ожидаем, когда все клиентские нити сделают это. */
    if(!server_pool.no_barr){
        rc = pthread_barrier_wait(&server_pool.proxy_barr);
        if(rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD)
            syslog(LOG_ERR, "Cannot wait on barrier.");
        else{
            pthread_barrier_destroy(&server_pool.proxy_barr);
            #ifndef NDEBUG
                syslog(LOG_DEBUG, "Barrier destroy. Start proxy.");
            #endif
        }
    }
    
    zmq_proxy(server_pool.clients, server_pool.workers, NULL);
    
    return EXIT_SUCCESS;
}