Beispiel #1
0
int check(thread_info_t *thread, entity_info_t *ent, entity_info_t *other, int *running) {
    
    int res;
    
    if (ent->pollfd->revents & POLLERR) {
        
        res = write_log_entry(thread, ent->name, "err");
        if (res < 0) return -1;
        
        fprintf(stderr, "Connection %d %s error.\n", thread->id, ent->name);
        return -1;
    }
    
    if ((ent->pollfd->revents & POLLHUP) || (ent->pollfd->revents & POLLRDHUP)) {
        
        res = write_log_entry(thread, ent->name, "hup");
        if (res < 0) return -1;
        
        res = shutdown(other->fd, SHUT_RDWR);
        if (res < 0) return -1;
        
        fprintf(stderr, "Connection %d %s hangup.\n", thread->id, ent->name);
        
        *running = 0;
    }
    
    /* TODO: Can we detect and properly handle the case where one half of a duplex connection is
    shut down but the other half remains open? */
    
    return 0;
}
Beispiel #2
0
int pump(thread_info_t *thread, pipe_info_t *pipe) {
    
    int res;
    
    if (pipe->out->pollfd->revents & POLLOUT) {
        
        res = try_write(thread, pipe);
        if (res < 0) return -1;
    }

    if (pipe->in->pollfd->revents & POLLIN && pipe->backup < BUFFER_SIZE) {
        
        ssize_t bytes_read = read(pipe->in->fd, pipe->buffer + pipe->backup, BUFFER_SIZE - pipe->backup);
        if (bytes_read < 0) {
            if (errno == EAGAIN || errno == EWOULDBLOCK) {
                return 0;
            }
            fprintf(stderr, "Connection %d could not receive from %s: %s\n",
                thread->id, pipe->in->name, strerror(errno));
            return -1;
        }
        
        /* Put an entry into the log. When we write the log, we use blocking IO calls. We presume
        that the disk is faster than the network.
        
        Maybe it would be better to do this in try_write() so that the entry's timestamp is closer
        to the actual time that the data is sent to the server or client. */
        
        char count_buffer[20];
        sprintf(count_buffer, "%d", (int)bytes_read);
        res = write_log_entry(thread, pipe->in->name, count_buffer);
        if (res < 0) return -1;
        
        res = fwrite(pipe->buffer + pipe->backup, 1, bytes_read, thread->log);
        if (res != bytes_read) {
            fprintf(stderr, "Connection %d could not write to log: %s\n", thread->id, strerror(errno));
            return -1;
        }
        
        pipe->backup += bytes_read;
    }
    
    if (pipe->backup) {
        
        res = try_write(thread, pipe);
        if (res < 0) return -1;
    }
    
    if (pipe->backup)
        pipe->out->pollfd->events |= POLLOUT;
    else
        pipe->out->pollfd->events &= ~POLLOUT;
    
    return 0;
}
void log_service(int fd, void *cookie)
{
    /* get the name of the log filepath to read */
    char * log_filepath = cookie;

    /* open the log file. */
    int logfd = unix_open(log_filepath, O_RDONLY);
    if (logfd < 0) {
        goto done;
    }

    // temp buffer to read the entries
    unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1] __attribute__((aligned(4)));
    struct logger_entry *entry = (struct logger_entry *) buf;

    while (1) {
        int ret;

        ret = unix_read(logfd, entry, LOGGER_ENTRY_MAX_LEN);
        if (ret < 0) {
            if (errno == EINTR || errno == EAGAIN)
                continue;
            // perror("logcat read");
            goto done;
        }
        else if (!ret) {
            // fprintf(stderr, "read: Unexpected EOF!\n");
            goto done;
        }

        /* NOTE: driver guarantees we read exactly one full entry */

        entry->msg[entry->len] = '\0';

        write_log_entry(fd, entry);
    }

done:
    unix_close(fd);
    free(log_filepath);
}
Beispiel #4
0
struct log_entry_t *append_log_entry(struct p_log *log, 
        uint64_t term, uint64_t index, uint64_t req_id,
        unsigned char *buffer, size_t bufsize) {
    if(!log->tail && index != 1) {
        DBG_LOG(LOG_FATAL, "raft invariant failure\n");
        return NULL; //XXX: raft invariant failure, may be add asserts
    }

    struct log_entry_t *le = 0;
    struct p_log_entry_t *ple = 0;

    if(log->tail) {
        if(log->tail->e->index + 1 != index) {
            struct p_log_entry_t *i = log->tail;
            while(i->e->index != index) {
                struct p_log_entry_t *tmp = i->prev;
                if(!delete_file(log->logdir, i->e->index)) {
                    //XXX: LOG: delete file failed
                }
                free(i->e->buffer);
                free(i->e);
                free(i);
                i = tmp;
            }
            i->next = NULL;
            free(i->e->buffer);

            i->e->term = term;
            i->e->index = index;
            i->e->req_id = req_id;
            i->e->buffer = buffer;
            i->e->bufsize = bufsize;

            log->tail = i->prev;

            ple = i;
            le = ple->e;
        }
    } 

    if(!ple) {
        le = (struct log_entry_t *)
            malloc(sizeof(struct log_entry_t));
        ple = (struct p_log_entry_t *)
            malloc(sizeof(struct p_log_entry_t));
        if(!le || !ple) {
            if(le) {
                free(le);
            }
            return NULL;
        }
        le->term = term;
        le->index = index;
        le->req_id = req_id;
        le->bufsize = bufsize;
        le->buffer = buffer;

        ple->next = ple->prev = NULL;
        ple->e = le;

    }

    //XXX: move directory creation code in "write_log_entry" function
    char tmpbuf[20];
    char *storedir = NULL;
    char *logfile = NULL;
    if(index >= RAFT_MAX_FILES_PER_DIR) {
        snprintf(tmpbuf, 20, "%lld", (index / RAFT_MAX_FILES_PER_DIR));
    } else {
        snprintf(tmpbuf, 20, "0");
    }
    storedir = path_join(log->logdir, tmpbuf);
    if(storedir) {
        int exists;
        if(file_exists(storedir, &exists)) {
            if(!exists) {
#if defined(__unix__) || defined(__APPLE__)
                int r = mkdir(storedir, DIR_PERM);
#else
                int r = mkdir(storedir);
#endif
                if(r) {
                    perror("mkdir failed:");
                    goto err;
                }
            }

            snprintf(tmpbuf, 20, "%lld", index);
            logfile = path_join(storedir, tmpbuf);
            if(logfile) {
                if(!write_log_entry(logfile, le)) {
                    DBG_LOG(LOG_ERROR, "error in file operation\n");
                    goto err;
                }
                
                ple->e = le;
                ple->next = ple->prev = NULL;
                if(!log->tail) {
                    log->head = log->tail = ple;
                } else {
                    log->tail->next = ple;
                    ple->prev = log->tail;
                    log->tail = ple;
                }
                free(storedir);
                free(logfile);
                return le;
            }
        }
    }
err:
    free(le);
    free(ple);
    if(storedir)
        free(storedir);
    if(logfile)
        free(logfile);
    free(le);
    return NULL;
}
Beispiel #5
0
void *handle_connection(void *data) {
    
    int res;
    
    /* Initialize thread */
    
    start_info_t *start_info = data;
    
    thread_info_t thread;
    thread.id = start_info->id;
    thread.start_time = start_info->start_time;
    
    struct pollfd pollfds[2];
    
    fprintf(stderr, "Opened connection %d.\n", thread.id);
    
    /* Create log file */
    
    char log_filename[PATH_MAX];
    snprintf(log_filename, PATH_MAX, "%s_%d", start_info->log_filename, thread.id);
    
    thread.log = fopen(log_filename, "w");
    if (!thread.log) {
        fprintf(stderr, "Connection %d could not open log file '%s': %s\n",
            thread.id, log_filename, strerror(errno));
        goto free_start_info;
    }
    
    /* Write first log entry to show when connection was established */
    
    res = write_log_entry(&thread, "client", "con");
    if (res < 0) goto close_log;
    
    /* Prepare client */
    
    entity_info_t client;
    client.name = "client";
    
    client.fd = start_info->socket;
    
    res = setnonblocking(&thread, &client);
    if (res == -1) goto close_log;
    
    pollfds[0].fd = client.fd;
    pollfds[0].events = POLLIN | POLLHUP | POLLRDHUP | POLLERR;
    client.pollfd = &pollfds[0];
    
    /* Connect to the server */
    
    entity_info_t server;
    server.name = "server";
    
    server.fd = socket(PF_INET, SOCK_STREAM, 0);
    if (server.fd < 0) {
        fprintf(stderr, "Connection %d socket() failed: %s\n", thread.id, strerror(errno));
        goto close_log;
    }
    
    res = connect(server.fd, (struct sockaddr *)start_info->server_addr, sizeof(struct sockaddr_in));
    if (res < 0) {
        fprintf(stderr, "Connection %d could not connect to server: %s\n", thread.id, strerror(errno));
        goto close_server;
    }
    
    res = setnonblocking(&thread, &server);
    if (res < 0) goto close_server;
    
    pollfds[1].fd = server.fd;
    pollfds[1].events = POLLIN | POLLHUP | POLLRDHUP | POLLERR;
    server.pollfd = &pollfds[1];
    
    /* Create pipes */
    
    pipe_info_t client_to_server;
    client_to_server.backup = 0;
    client_to_server.in = &client;
    client_to_server.out = &server;
    
    pipe_info_t server_to_client;
    server_to_client.backup = 0;
    server_to_client.in = &server;
    server_to_client.out = &client;
    
    /* Main loop */
    
    for (;;) {
    
        res = poll(pollfds, 2, -1);
        if (res <= 0) fprintf(stderr, "poll() failed with rc %d: %s\n", res, strerror(errno));
        
        /* Check for error conditions and hangups */
        
        int running = 1;
        
        res = check(&thread, &client, &server, &running);
        if (res < 0) goto close_server;
        if (!running) break;
        
        res = check(&thread, &server, &client, &running);
        if (res < 0) goto close_server;
        if (!running) break;
        
        /* Transfer data from client to server */
        
        res = pump(&thread, &client_to_server);
        if (res < 0) goto close_server;
        
        /* Transfer data from server to client */
        
        res = pump(&thread, &server_to_client);
        if (res < 0) goto close_server;
    }
    
    /* Clean up */

close_server:
    close(server.fd);

close_log:
    fclose(thread.log);
    
free_start_info:
    close(start_info->socket);
    free(start_info);
    
    return NULL;
}
Beispiel #6
0
void process_data(struct wav_file_headers* wav_headers, int in_fd) {
  
  int sample_size;
  int sample_c,i;
  short *sample;
  int size, wsize;
  int silence_counter = 0;
  int silence_flag = 0;
  int min_length_flag = 1; /* Default is always split */
  int override_flag = 0;	/* tblough 5/23/04 */
  unsigned int bytecounter = 0;
  unsigned int file_bytecounter = 0;
  unsigned int start_time;
  unsigned int file_sample_c = 0;

  start_time = time(NULL);

  // Array of samples (NumChannels of them)
  sample = calloc(wav_headers->fmt.NumChannels * opts.buffer_amt, sizeof(short));

  sample_size = wav_headers->fmt.BitsPerSample / 8;

  if(debug_level >= VERYVERBOSE)
    printf("sample size: %i\n", sample_size);

  sample_c = 0;
  do {

    size = read(in_fd, sample, sample_size * wav_headers->fmt.NumChannels * opts.buffer_amt);
    for(i=0; i<wav_headers->fmt.NumChannels * opts.buffer_amt; i++) {

      if((size == 0) && (debug_level >= VERYVERBOSE))
	printf("End of Data\n");

      if(debug_level >= INSANELYVERBOSE)
	printf("[%i,%i] 0x%hx (%hi)  %i\n", sample_c, i, sample[i], sample[i], size);

      if(is_silence(sample[i]))
	silence_counter++;
      else {
	silence_counter = 0;
      }
    }

    if(silence_counter == 0)
      silence_flag=0;

    if(debug_level >= VERYVERBOSE) {
      printf("min_track_length: %f cur_track_length: %f\n", opts.min_track_length, 
	     file_sample_c / (float)wav_headers->fmt.SampleRate);
    }

    if(opts.min_track_length > 0) {
      /* Check to make sure we've seen enough samples before splitting */
      if( opts.min_track_length <= (file_sample_c / wav_headers->fmt.SampleRate) )
	min_length_flag = 1;
      else
	min_length_flag = 0;
    }

    // tblough 5/23/04 - modified to provide minimum track length override
	if((opts.override > opts.gap) && (silence_counter > OVERRIDE)) {
	   if(debug_level >= VERYVERBOSE) {
          printf("Override GAP: %i  Counter: %i\n", OVERRIDE, silence_counter);
          printf("Silence Detected @ %.2fs\n", calc_real_time(sample_c, wav_headers));
       }
       override_flag = 1;
	}
	else
	   override_flag = 0;

	if((silence_counter > GAP) && (! silence_flag) && (min_length_flag || override_flag)) {

      if(debug_level >= VERYVERBOSE) {
	printf("Silence GAP: %i  Counter: %i\n", GAP, silence_counter);
	printf("Silence Detected @ %.2fs\n", calc_real_time(sample_c, wav_headers));
      }

      silence_flag=1;
      if(opts.log_enabled)
	write_log_entry(file_bytecounter, file_sample_c, wav_headers);
      start_new_file(wav_headers, file_bytecounter, sample_c);
      file_bytecounter = 0;
      file_sample_c = 0;
    }

	// Only write if we should not skip the silence and there is silence
	// loescher 06/06/04
	if (! (opts.skip_silence && silence_flag) ) {
	  wsize = fwrite(sample, sample_size * wav_headers->fmt.NumChannels * opts.buffer_amt, 1, fd);

	  file_bytecounter += wsize * sample_size * wav_headers->fmt.NumChannels * opts.buffer_amt;
	  bytecounter += wsize * sample_size * wav_headers->fmt.NumChannels * opts.buffer_amt;
	}

    sample_c += opts.buffer_amt;
    file_sample_c += opts.buffer_amt;

    // Display stats
    if((opts.show_progress) && ((sample_c % 1000) == 0))
      display_stats(sample_c, bytecounter, start_time, wav_headers);

  } while(size > 0);