int main(void) { const char *path = "/home/netstar"; notify_t *notify = notify_new(); notify_path_set(notify, path); notify_event_callback_set(notify, NOTIFY_EVENT_CALLBACK_FILE_ADD, _change_cb, NULL); notify_event_callback_set(notify, NOTIFY_EVENT_CALLBACK_FILE_DEL, _change_cb, NULL); notify_event_callback_set(notify, NOTIFY_EVENT_CALLBACK_FILE_MOD, _change_cb, NULL); notify_event_callback_set(notify, NOTIFY_EVENT_CALLBACK_DIR_ADD, _change_cb, NULL); notify_event_callback_set(notify, NOTIFY_EVENT_CALLBACK_DIR_DEL, _change_cb, NULL); notify_event_callback_set(notify, NOTIFY_EVENT_CALLBACK_DIR_MOD, _change_cb, NULL); int res = notify_background_run(notify); if (res) { fprintf(stderr, "failed to put notify into the background!"); exit(EXIT_FAILURE); } for (int i = 0; i < 20; i++) { sleep(1); printf("other code!\n"); } notify_stop_wait(notify); notify_free(notify); return EXIT_SUCCESS; }
void afiddle_free(afiddle *x){ notify_free((t_object *)x);}
int main(int argc, char **argv) { ssize_t readen; int have_data = 1; int ntimeouts = 0; time_t timeout_start = time(NULL); int rtp_hdr_pos = 0, num_packets = 0; struct rlimit rl; if (getrlimit(RLIMIT_STACK, &rl) == 0) { if (rl.rlim_cur > THREAD_STACK_SIZE) { rl.rlim_cur = THREAD_STACK_SIZE; setrlimit(RLIMIT_STACK, &rl); } } memset(rtp_hdr[0], 0, RTP_HDR_SZ); memset(rtp_hdr[1], 0, RTP_HDR_SZ); data_init(&ts); ts_set_log_func(LOG_func); parse_options(&ts, argc, argv); if (ts.pidfile) daemonize(ts.pidfile); if (ts.syslog_active) { if (ts.syslog_remote) { log_init(ts.ident, 1, 1, ts.syslog_host, ts.syslog_port); remote_syslog = 1; } else { openlog(ts.ident, LOG_NDELAY | LOG_PID, LOG_USER); local_syslog = 1; } } ts.notify = notify_alloc(&ts); ts_LOGf("Start %s\n", program_id); notify(&ts, "START", "Starting %s", program_id); if (ts.input.type == NET_IO && udp_connect_input(&ts.input) < 1) goto EXIT; if (ts.output.type == NET_IO && udp_connect_output(&ts.output) < 1) goto EXIT; signal(SIGCHLD, SIG_IGN); signal(SIGPIPE, SIG_IGN); signal(SIGINT , signal_quit); signal(SIGTERM, signal_quit); if (ts.threaded) { pthread_create(&ts.decode_thread, &ts.thread_attr, &decode_thread, &ts); pthread_create(&ts.write_thread , &ts.thread_attr, &write_thread , &ts); } ts.emm_last_report = time(NULL) + FIRST_REPORT_SEC; ts.ecm_last_report = time(NULL) + FIRST_REPORT_SEC; camd_start(&ts); if (packet_from_file) { uint8_t tmp[2048]; ts_hex_dump_buf((char *)tmp, sizeof(tmp), packet_buf, packet_buflen, 16); ts_LOGf("%s | Processing packet with CAID 0x%04x\n", packet_type == ECM_MSG ? "ECM" : "EMM", ts.forced_caid); ts_LOGf("%s | Packet dump:\n%s\n", packet_type == ECM_MSG ? "ECM" : "EMM", tmp); camd_process_packet(&ts, camd_msg_alloc(packet_type, ts.forced_caid, ts.forced_service_id, packet_buf, packet_buflen)); goto EXIT; } do { if (!ts.camd.constant_codeword) do_reports(&ts); if (ts.input.type == NET_IO) { set_log_io_errors(0); if (!ts.rtp_input) { readen = fdread_ex(ts.input.fd, (char *)ts_packet, FRAME_SIZE, 250, 4, 1); } else { readen = fdread_ex(ts.input.fd, (char *)ts_packet, FRAME_SIZE + RTP_HDR_SZ, 250, 4, 1); if (readen > RTP_HDR_SZ) { memcpy(rtp_hdr[rtp_hdr_pos], ts_packet, RTP_HDR_SZ); memmove(ts_packet, ts_packet + RTP_HDR_SZ, FRAME_SIZE); readen -= RTP_HDR_SZ; uint16_t ssrc = (rtp_hdr[rtp_hdr_pos][2] << 8) | rtp_hdr[rtp_hdr_pos][3]; uint16_t pssrc = (rtp_hdr[!rtp_hdr_pos][2] << 8) | rtp_hdr[!rtp_hdr_pos][3]; rtp_hdr_pos = !rtp_hdr_pos; if (pssrc + 1 != ssrc && (ssrc != 0 && pssrc != 0xffff) && num_packets > 2) if (ts.ts_discont) ts_LOGf("--- | RTP discontinuity last_ssrc %5d, curr_ssrc %5d, lost %d packet\n", pssrc, ssrc, ((ssrc - pssrc)-1) & 0xffff); num_packets++; } } set_log_io_errors(1); if (!keep_running) break; if (readen < 0) { ts_LOGf("--- | Input read timeout.\n"); if (!ntimeouts) { timeout_start = time(NULL); notify(&ts, "INPUT_TIMEOUT", "Read timeout on input %s://%s:%s/", ts.rtp_input ? "rtp" : "udp", ts.input.hostname, ts.input.service); } ts.no_input = 1; ntimeouts++; } else { if (ntimeouts && readen > 0) { time_t now = time(NULL); ts_LOGf("+++ | Input OK after %ld sec timeout.\n", (now - timeout_start) + 2); notify(&ts, "INPUT_OK", "Data is available on input %s://%s:%s/ after %ld seconds timeout.", ts.rtp_input ? "rtp" : "udp", ts.input.hostname, ts.input.service, (now - timeout_start) + 2); // Timeout is detected when ~2 seconds there is no incoming data ts.no_input = 0; ntimeouts = 0; } } } else { readen = read(ts.input.fd, ts_packet, FRAME_SIZE); have_data = !(readen <= 0); } if (readen > 0) { if (ts.input_dump_file) fwrite(ts_packet, readen, 1, ts.input_dump_file); process_packets(&ts, ts_packet, readen); } } while (have_data && keep_running); EXIT: camd_stop(&ts); // If pthread_join failes make sure we exit... signal(SIGINT , SIG_DFL); signal(SIGTERM, SIG_DFL); signal(SIGALRM, signal_alarm); alarm(2); if (ts.threaded) { ts.decode_stop = 1; ts.write_stop = 1; if (ts.decode_thread) pthread_join(ts.decode_thread, NULL); if (ts.write_thread) pthread_join(ts.write_thread, NULL); } show_pid_report(&ts); notify_sync(&ts, "STOP", "Stopping %s", program_id); ts_LOGf("Stop %s\n", program_id); if (ts.syslog_active) { if (ts.syslog_remote) log_close(); else closelog(); } if (ts.input_dump_file) fclose(ts.input_dump_file); if (ts.pidfile) unlink(ts.pidfile); if (log_file) fclose(log_file); notify_free(&ts.notify); data_free(&ts); exit(EXIT_SUCCESS); }