VK1ET : Better pthread termination

Close threads, mutex and conditions using pthread functions

Also, correct/update a few comments.
This commit is contained in:
Malcolm Robb 2013-05-21 12:08:35 +01:00
parent 92fd06bcd6
commit f33a7090b0

View file

@ -347,6 +347,7 @@ static uint64_t mstime(void) {
void sigintHandler(int dummy) { void sigintHandler(int dummy) {
MODES_NOTUSED(dummy); MODES_NOTUSED(dummy);
signal(SIGINT, SIG_DFL); // reset signal handler - bit extra safety
Modes.exit = 1; // Signal to threads that we are done Modes.exit = 1; // Signal to threads that we are done
} }
@ -549,6 +550,7 @@ void readDataFromFile(void) {
ssize_t nread, toread; ssize_t nread, toread;
unsigned char *p; unsigned char *p;
if (Modes.exit == 1) break;
if (Modes.data_ready) { if (Modes.data_ready) {
pthread_cond_wait(&Modes.data_cond,&Modes.data_mutex); pthread_cond_wait(&Modes.data_cond,&Modes.data_mutex);
continue; continue;
@ -596,7 +598,11 @@ void *readerThreadEntryPoint(void *arg) {
} else { } else {
readDataFromFile(); readDataFromFile();
} }
return NULL; /* Signal to the other thread that new data is ready - dummy really so threads don't mutually lock */
Modes.data_ready = 1;
pthread_cond_signal(&Modes.data_cond);
pthread_mutex_unlock(&Modes.data_mutex);
pthread_exit(NULL);
} }
/* ============================== Debugging ================================= */ /* ============================== Debugging ================================= */
@ -3188,14 +3194,14 @@ void snipMode(int level) {
} }
/* ============================= Networking ================================= /* ============================= Networking =================================
* Note: here we risregard any kind of good coding practice in favor of * Note: here we disregard any kind of good coding practice in favor of
* extreme simplicity, that is: * extreme simplicity, that is:
* *
* 1) We only rely on the kernel buffers for our I/O without any kind of * 1) We only rely on the kernel buffers for our I/O without any kind of
* user space buffering. * user space buffering.
* 2) We don't register any kind of event handler, from time to time a * 2) We don't register any kind of event handler, from time to time a
* function gets called and we accept new connections. All the rest is * function gets called and we accept new connections. All the rest is
* handled via non-blocking I/O and manually pullign clients to see if * handled via non-blocking I/O and manually polling clients to see if
* they have something new to share with us when reading is needed. * they have something new to share with us when reading is needed.
*/ */
@ -4136,7 +4142,12 @@ int main(int argc, char **argv) {
printf("%d total usable messages\n", Modes.stat_goodcrc + Modes.stat_fixed); printf("%d total usable messages\n", Modes.stat_goodcrc + Modes.stat_fixed);
} }
if (Modes.filename == NULL) {
rtlsdr_cancel_async(Modes.dev); // Cancel rtlsdr_read_async will cause data input thread to terminate cleanly rtlsdr_cancel_async(Modes.dev); // Cancel rtlsdr_read_async will cause data input thread to terminate cleanly
rtlsdr_close(Modes.dev); rtlsdr_close(Modes.dev);
exit (0); }
pthread_cond_destroy(&Modes.data_cond); // Thread cleanup
pthread_mutex_destroy(&Modes.data_mutex);
pthread_join(Modes.reader_thread,NULL); // Wait on reader thread exit
pthread_exit(0);
} }