/* Captures open data stream to configured output file. */ static bool capture_and_save(FILE *stream) { return IF_(!continuous_capture, TEST_OK(READ_ITEM(stream, sample_count))) && IF_ELSE(matlab_format, capture_matlab_data(stream), capture_raw_data(stream)); }
int start_live(struct radclock_handle *handle) { /* Threads */ void* thread_status; int have_fixed_point_thread = 0; int err; JDEBUG /* * Handle first time run. If no time_server specified while we produce * packets, we would be a nasty CPU hog. Better avoid creating problems and * exit with an error message */ if ((handle->conf->synchro_type == SYNCTYPE_NTP) || (handle->conf->synchro_type == SYNCTYPE_1588)) { if (strlen(handle->conf->time_server) == 0) { verbose(LOG_ERR, "No time server specified on command line " "or configuration file, attempting suicide."); return (1); } } /* * This thread triggers the processing of data. It could be a dummy sleeping * loop, an NTP client, a 1588 slave ... */ if (!VM_SLAVE(handle)) { err = start_thread_TRIGGER(handle); if (err < 0) return (1); } /* * This thread is in charge of processing the raw data collected, magically * transform the data into stamps and give them to the sync algo for * processing. */ if (handle->unix_signal == SIGHUP) { /* * This is not start, but HUP, the algo thread is still running * Simply clear the flag and bypass */ handle->unix_signal = 0; } else { if (VM_SLAVE(handle) || VM_MASTER(handle)) { err = init_vm(handle); if (err < 0){ verbose(LOG_ERR, "Failed to initialise VM communication"); return (1); } } if (!VM_SLAVE(handle)) { err = start_thread_DATA_PROC(handle); if (err < 0) return (1); } } /* Are we running an NTP server for network clients ? */ switch (handle->conf->server_ntp) { case BOOL_ON: err = start_thread_NTP_SERV(handle); if (err < 0) return (1); break; case BOOL_OFF: default: /* do nothing */ break; } /* Are we running a VM UDP server for network guests ? */ switch (handle->conf->server_vm_udp) { case BOOL_ON: err = start_thread_VM_UDP_SERV(handle); if (err < 0) return (1); break; case BOOL_OFF: default: /* do nothing */ break; } /* * To be able to provide the RADCLOCK timestamping mode, we need to refresh * the fixed point data in the kernel. That's this guy's job. * XXX Update: with kernel version 2, the overflow problem is taking care of * by the kernel. The fixedpoint thread is deprecated and should be removed * in the future */ if ((handle->run_mode == RADCLOCK_SYNC_LIVE) && (handle->clock->kernel_version < 2)) { err = start_thread_FIXEDPOINT(handle); if (err < 0) return (1); have_fixed_point_thread = 1; } else have_fixed_point_thread = 0; /* * That's our main capture loop, it does not return until the end of * input or if we explicitely break it * XXX TODO XXX: a unique source is assumed !! */ err = capture_raw_data(handle); if (err == -1) { /* Yes, we abuse this a bit ... */ handle->unix_signal = SIGTERM; verbose(LOG_NOTICE, "Reached end of input"); } if (err == -2) { verbose(LOG_NOTICE, "Breaking current capture loop for rehash"); } /* * pcap_break_loop() has been called or end of input. In both cases kill the * threads. If we rehash, they will be restarted anyway. */ verbose(LOG_NOTICE, "Send killing signal to threads. Wait for stop message."); handle->pthread_flag_stop = PTH_STOP_ALL; /* Do not stop sync algo thread if we HUP */ if (handle->unix_signal == SIGHUP) handle->pthread_flag_stop &= ~PTH_DATA_PROC_STOP; if (handle->conf->server_ntp == BOOL_ON) { pthread_join(handle->threads[PTH_NTP_SERV], &thread_status); verbose(LOG_NOTICE, "NTP server thread is dead."); } pthread_join(handle->threads[PTH_TRIGGER], &thread_status); verbose(LOG_NOTICE, "Trigger thread is dead."); if (have_fixed_point_thread) { pthread_join(handle->threads[PTH_FIXEDPOINT], &thread_status); verbose(LOG_NOTICE, "Kernel fixedpoint thread is dead."); } /* Join on TERM since algo has been told to die */ if (handle->unix_signal != SIGHUP) { pthread_join(handle->threads[PTH_DATA_PROC], &thread_status); verbose(LOG_NOTICE, "Data processing thread is dead."); /* Reinitialise flags */ handle->pthread_flag_stop = 0; verbose(LOG_NOTICE, "Threads are dead."); /* We received a SIGTERM, we exit the loop. */ return (1); } else { handle->pthread_flag_stop = 0; } return (0); }