Mercurial > pt1
changeset 16:ecb85bde67b1
added signal handler to perform cleaning up when it receives a signal.
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Wed, 25 Feb 2009 02:35:36 +0900 |
parents | 1b0883b02b4f |
children | 52c7c7c64ba6 |
files | recpt1/recpt1.c |
diffstat | 1 files changed, 115 insertions(+), 29 deletions(-) [+] |
line wrap: on
line diff
--- a/recpt1/recpt1.c Tue Feb 24 23:26:22 2009 +0900 +++ b/recpt1/recpt1.c Wed Feb 25 02:35:36 2009 +0900 @@ -9,6 +9,7 @@ #include <math.h> #include <unistd.h> #include <getopt.h> +#include <signal.h> #include <netdb.h> #include <arpa/inet.h> @@ -41,12 +42,12 @@ { int lp; - for(lp = 0; isdb_t_conv_table[lp].parm_freq != NULL; lp++){ + for(lp = 0; isdb_t_conv_table[lp].parm_freq != NULL; lp++) { /* return entry number in the table when strings match and * lengths are same. */ if((memcmp(isdb_t_conv_table[lp].parm_freq, channel, strlen(channel)) == 0) && - (strlen(channel) == strlen(isdb_t_conv_table[lp].parm_freq))){ + (strlen(channel) == strlen(isdb_t_conv_table[lp].parm_freq))) { return &isdb_t_conv_table[lp]; } } @@ -194,7 +195,8 @@ addr, sizeof(struct sockaddr_in)); } free(buf); - } else { + } + else { if(use_udp && sfd != -1) { sendto(sfd, sbuf.data, sbuf.size, 0, addr, sizeof(struct sockaddr_in)); @@ -248,7 +250,8 @@ addr, sizeof(struct sockaddr_in)); } free(buf); - } else { + } + else { write(wfd, sbuf.data, sbuf.size); if(use_udp && sfd != -1) { @@ -355,13 +358,15 @@ sigbuf[1] = (signal & 0xFF); /* calculate signal level */ - if(sigbuf[0] <= 0x10U){ + if(sigbuf[0] <= 0x10U) { /* clipped maximum */ return 24.07f; - } else if (sigbuf[0] >= 0xB0U) { + } + else if (sigbuf[0] >= 0xB0U) { /* clipped minimum */ return 0.0f; - } else { + } + else { /* linear interpolation */ const float fMixRate = (float)(((unsigned short)(sigbuf[0] & 0x0FU) << 8) | @@ -388,12 +393,77 @@ CNR = (0.000024 * P * P * P * P) - (0.0016 * P * P * P) + (0.0398 * P * P) + (0.5491 * P)+3.0965; printf("Signal=%fdB\n", CNR); - } else { + } + else { CNR = getsignal_isdb_s(rc); printf("Signal=%fdB\n", CNR); } } +void +cleanup(int tfd) +{ + /* stop recording */ + ioctl(tfd, STOP_REC, 0); + + /* restore LNB state */ +#if 0 + if(ptr->type == CHTYPE_SATELLITE) { + if(ioctl(tfd, LNB_DISABLE, 0) < 0) { + return 0 ; + } + } +#endif + /* xxx really need mutex? */ + f_exit = TRUE; +} + +/* will be signal handler thread */ +void * +process_signals(void *data) +{ + sigset_t waitset; + int sig; + int tfd = *(int *)data; + + sigemptyset(&waitset); + sigaddset(&waitset, SIGINT); + sigaddset(&waitset, SIGTERM); + + sigwait(&waitset, &sig); + + switch(sig) { + case SIGINT: + fprintf(stderr, "\nSIGINT received. cleaning up...\n"); + cleanup(tfd); + break; + case SIGTERM: + fprintf(stderr, "\nSIGTERM received. cleaning up...\n"); + cleanup(tfd); + break; + } + + return NULL; /* dummy */ +} + +void +init_signal_handlers(pthread_t *signal_thread, int tfd) +{ + sigset_t blockset; + static int tunerfd; + + tunerfd = tfd; + + sigemptyset(&blockset); + sigaddset(&blockset, SIGINT); + sigaddset(&blockset, SIGTERM); + + if(pthread_sigmask(SIG_BLOCK, &blockset, NULL)) + fprintf(stderr, "pthread_sigmask() failed.\n"); + + pthread_create(signal_thread, NULL, process_signals, &tunerfd); +} + int main(int argc, char **argv) { @@ -404,7 +474,8 @@ time_t start_time, cur_time; FREQUENCY freq; ISDB_T_FREQ_CONV_TABLE *ptr; - pthread_t dequeue_threads; + pthread_t dequeue_thread; + pthread_t signal_thread; QUEUE_T *p_queue = create_queue(MAX_QUEUE); BUFSZ *bufptr; decoder *dec = NULL; @@ -512,10 +583,11 @@ } } if(tfd < 0) { - fprintf(stderr, "Device Open Error\n"); + fprintf(stderr, "Cannot open tuner\n"); return 1; } - } else { + } + else { for(lp = 0; lp < 2; lp++) { tfd = open(isdb_t_dev[lp], O_RDONLY); if(tfd >= 0) { @@ -523,7 +595,7 @@ } } if(tfd < 0) { - fprintf(stderr, "Device Open Error\n"); + fprintf(stderr, "Cannot open tuner\n"); return 1; } } @@ -537,8 +609,8 @@ if(use_b25) { dec = b25_startup(&dopt); if(!dec) { - fprintf(stderr, "cannot start b25 decoder\n"); - fprintf(stderr, "fall back to encrypted recording\n"); + fprintf(stderr, "Could not start b25 decoder\n"); + fprintf(stderr, "Fall back to encrypted recording\n"); use_b25 = 0; } } @@ -569,40 +641,47 @@ if(!fileless) { wfd = open(argv[optind + 2], (O_RDWR | O_CREAT | O_TRUNC), 0666); if(wfd < 0) { - fprintf(stderr, "Output File Open Error(%s)\n", argv[optind + 2]); + fprintf(stderr, "Could not open output file(%s)\n", argv[optind + 2]); return 1; } } - if(ptr->type == CHTYPE_SATELLITE){ - if(ioctl(tfd, LNB_ENABLE, 0) < 0){ + if(ptr->type == CHTYPE_SATELLITE) { + if(ioctl(tfd, LNB_ENABLE, 0) < 0) { return 0 ; } } if(ioctl(tfd, SET_CHANNEL, &freq) < 0) { - fprintf(stderr, "Tuner Select Error\n"); + fprintf(stderr, "Could not tune to the specified channel\n"); calc_cn(tfd, ptr->type); return 1; } calc_cn(tfd, ptr->type); + /* init signal handler thread */ + init_signal_handlers(&signal_thread, tfd); + /* make reader thread */ tdata.queue = p_queue; tdata.decoder = dec; tdata.wfd = wfd; tdata.sock_data = sdata; - pthread_create(&dequeue_threads, NULL, write_func, &tdata); + pthread_create(&dequeue_thread, NULL, write_func, &tdata); /* start recording */ if(ioctl(tfd, START_REC, 0) < 0) { - fprintf(stderr, "Tuner Start Error\n"); + fprintf(stderr, "Tuner could not start recording\n"); return 1; } + fprintf(stderr, "Recording...\n"); + time(&start_time); /* read from tuner */ while(1) { + if(f_exit) + break; time(&cur_time); bufptr = malloc(sizeof(BUFSZ)); bufptr->size = read(tfd, bufptr->buffer, MAX_READ_SIZE); @@ -611,7 +690,8 @@ f_exit = TRUE; enqueue(p_queue, NULL); break; - } else { + } + else { continue; } } @@ -634,28 +714,34 @@ break; } } + /* close tuner */ - if(ptr->type == CHTYPE_SATELLITE){ - if(ioctl(tfd, LNB_DISABLE, 0) < 0){ + if(ptr->type == CHTYPE_SATELLITE) { + if(ioctl(tfd, LNB_DISABLE, 0) < 0) { return 0 ; } } close(tfd); /* wait reader thread */ - pthread_join(dequeue_threads, NULL); + pthread_join(dequeue_thread, NULL); + fprintf(stderr, "dequeue_thread joined\n"); + + pthread_join(signal_thread, NULL); + fprintf(stderr, "signal_thread joined\n"); + + /* relase queue */ destroy_queue(p_queue); - /* close socket */ - if(use_udp) { - close(sdata->sfd); - free(sdata); - } + /* free socket data */ + free(sdata); /* release decoder */ if(use_b25) { b25_shutdown(dec); } + fprintf(stderr, "leaving main\n"); + return 0; }