From 8901334cc09370653b48af18231d50a553f0260f Mon Sep 17 00:00:00 2001 From: Adam Sutton Date: Fri, 11 Oct 2013 13:41:46 +0100 Subject: [PATCH] misc: Remove memory leaks and other anomalies Many of these are somewhat redundant now, as I've suppressed many of the warnings as they're false positives. However the changes, such as added a detach flag to tvhthread_create(), have been kept anyway. --- src/avahi.c | 2 +- src/descrambler/capmt.c | 6 +----- src/descrambler/cwc.c | 9 ++------- src/dvr/dvr_inotify.c | 2 +- src/dvr/dvr_rec.c | 2 +- src/epggrab.c | 2 +- src/epggrab/module.c | 2 +- src/epggrab/otamux.c | 1 + src/htsp_server.c | 3 ++- src/idnode.c | 6 ++++-- src/imagecache.c | 2 +- src/input/mpegts/dvb_psi.c | 2 +- src/input/mpegts/iptv/iptv.c | 4 ++-- src/input/mpegts/linuxdvb/linuxdvb_adapter.c | 6 ------ src/input/mpegts/linuxdvb/linuxdvb_device.c | 12 +++++++++++- src/input/mpegts/linuxdvb/linuxdvb_frontend.c | 8 ++++++-- src/input/mpegts/linuxdvb/linuxdvb_network.c | 1 + src/input/mpegts/linuxdvb/linuxdvb_private.h | 2 +- src/input/mpegts/linuxdvb/linuxdvb_satconf.c | 1 + src/input/mpegts/tsfile/tsfile_input.c | 4 ++-- src/main.c | 10 ++++++---- src/service.c | 2 +- src/service_mapper.c | 2 +- src/tcp.c | 4 ++-- src/timeshift.c | 4 ++-- src/timeshift/timeshift_filemgr.c | 2 +- src/tvheadend.h | 9 ++++++--- src/tvhlog.c | 12 ++++++++---- src/wrappers.c | 13 +++++++++---- 29 files changed, 77 insertions(+), 58 deletions(-) diff --git a/src/avahi.c b/src/avahi.c index 65fef8a0..c474dd7c 100644 --- a/src/avahi.c +++ b/src/avahi.c @@ -269,5 +269,5 @@ avahi_init(void) { pthread_t tid; - tvhthread_create(&tid, NULL, avahi_thread, NULL); + tvhthread_create(&tid, NULL, avahi_thread, NULL, 1); } diff --git a/src/descrambler/capmt.c b/src/descrambler/capmt.c index 5d86c3df..9f00be80 100644 --- a/src/descrambler/capmt.c +++ b/src/descrambler/capmt.c @@ -965,7 +965,6 @@ capmt_destroy(capmt_t *capmt) static capmt_t * capmt_entry_find(const char *id, int create) { - pthread_attr_t attr; pthread_t ptid; char buf[20]; capmt_t *capmt; @@ -995,10 +994,7 @@ capmt_entry_find(const char *id, int create) TAILQ_INSERT_TAIL(&capmts, capmt, capmt_link); - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - tvhthread_create(&ptid, &attr, capmt_thread, capmt); - pthread_attr_destroy(&attr); + tvhthread_create(&ptid, NULL, capmt_thread, capmt, 1); return capmt; } diff --git a/src/descrambler/cwc.c b/src/descrambler/cwc.c index 2edbe8a7..b070d817 100755 --- a/src/descrambler/cwc.c +++ b/src/descrambler/cwc.c @@ -1107,7 +1107,7 @@ cwc_session(cwc_t *cwc) pthread_cond_init(&cwc->cwc_writer_cond, NULL); pthread_mutex_init(&cwc->cwc_writer_mutex, NULL); TAILQ_INIT(&cwc->cwc_writeq); - tvhthread_create(&writer_thread_id, NULL, cwc_writer_thread, cwc); + tvhthread_create(&writer_thread_id, NULL, cwc_writer_thread, cwc, 0); /** * Mainloop @@ -1285,7 +1285,6 @@ cwc_emm(uint8_t *data, int len, uint16_t caid, void *ca_update_id) cwc_t *cwc; struct cs_card_data *pcard; - pcard = calloc(1, sizeof(struct cs_card_data)); pthread_mutex_lock(&cwc_mutex); TAILQ_FOREACH(cwc, &cwcs, cwc_link) { @@ -2068,7 +2067,6 @@ cwc_destroy(cwc_t *cwc) static cwc_t * cwc_entry_find(const char *id, int create) { - pthread_attr_t attr; pthread_t ptid; char buf[20]; cwc_t *cwc; @@ -2097,10 +2095,7 @@ cwc_entry_find(const char *id, int create) cwc->cwc_running = 1; TAILQ_INSERT_TAIL(&cwcs, cwc, cwc_link); - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - tvhthread_create(&ptid, &attr, cwc_thread, cwc); - pthread_attr_destroy(&attr); + tvhthread_create(&ptid, NULL, cwc_thread, cwc, 1); return cwc; } diff --git a/src/dvr/dvr_inotify.c b/src/dvr/dvr_inotify.c index e19a562c..db2c64f7 100644 --- a/src/dvr/dvr_inotify.c +++ b/src/dvr/dvr_inotify.c @@ -66,7 +66,7 @@ void dvr_inotify_init ( void ) return; } - tvhthread_create(&tid, NULL, _dvr_inotify_thread, NULL); + tvhthread_create(&tid, NULL, _dvr_inotify_thread, NULL, 1); } /** diff --git a/src/dvr/dvr_rec.c b/src/dvr/dvr_rec.c index a9bfd873..7fd65b6e 100644 --- a/src/dvr/dvr_rec.c +++ b/src/dvr/dvr_rec.c @@ -91,7 +91,7 @@ dvr_rec_subscribe(dvr_entry_t *de) buf, st, flags, NULL, NULL, NULL); - tvhthread_create(&de->de_thread, NULL, dvr_thread, de); + tvhthread_create(&de->de_thread, NULL, dvr_thread, de, 0); } /** diff --git a/src/epggrab.c b/src/epggrab.c index 7541b7cf..7a662c8a 100644 --- a/src/epggrab.c +++ b/src/epggrab.c @@ -400,7 +400,7 @@ void epggrab_init ( void ) pthread_attr_t tattr; pthread_attr_init(&tattr); pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); - tvhthread_create(&tid, &tattr, _epggrab_internal_thread, NULL); + tvhthread_create(&tid, &tattr, _epggrab_internal_thread, NULL, 1); pthread_attr_destroy(&tattr); } diff --git a/src/epggrab/module.c b/src/epggrab/module.c index 462b9477..8a7fdc74 100644 --- a/src/epggrab/module.c +++ b/src/epggrab/module.c @@ -414,7 +414,7 @@ int epggrab_module_enable_socket ( void *m, uint8_t e ) tvhlog(LOG_DEBUG, mod->id, "starting socket thread"); pthread_attr_init(&tattr); pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); - tvhthread_create(&tid, &tattr, _epggrab_socket_thread, mod); + tvhthread_create(&tid, &tattr, _epggrab_socket_thread, mod, 1); } mod->enabled = e; return 1; diff --git a/src/epggrab/otamux.c b/src/epggrab/otamux.c index 1d12ec0a..5f40b44d 100644 --- a/src/epggrab/otamux.c +++ b/src/epggrab/otamux.c @@ -434,6 +434,7 @@ epggrab_ota_init ( void ) if (!(m = htsmsg_field_get_map(f))) continue; epggrab_ota_load_one(f->hmf_name, m); } + htsmsg_destroy(c); } /* Init timer (immediate call after full init) */ diff --git a/src/htsp_server.c b/src/htsp_server.c index 3cd38427..c4192fa8 100644 --- a/src/htsp_server.c +++ b/src/htsp_server.c @@ -2085,7 +2085,8 @@ htsp_serve(int fd, void *opaque, struct sockaddr_storage *source, LIST_INSERT_HEAD(&htsp_connections, &htsp, htsp_link); pthread_mutex_unlock(&global_lock); - tvhthread_create(&htsp.htsp_writer_thread, NULL, htsp_write_scheduler, &htsp); + tvhthread_create(&htsp.htsp_writer_thread, NULL, + htsp_write_scheduler, &htsp, 0); /** * Reader loop diff --git a/src/idnode.c b/src/idnode.c index dd090276..f96e4da8 100644 --- a/src/idnode.c +++ b/src/idnode.c @@ -132,7 +132,7 @@ idnode_init(void) idnode_queue = NULL; pthread_mutex_init(&idnode_mutex, NULL); pthread_cond_init(&idnode_cond, NULL); - tvhthread_create(&tid, NULL, idnode_thread, NULL); + tvhthread_create(&tid, NULL, idnode_thread, NULL, 1); } /** @@ -945,7 +945,7 @@ void* idnode_thread ( void *p ) { idnode_t *node; - htsmsg_t *m, *q; + htsmsg_t *m, *q = NULL; htsmsg_field_t *f; pthread_mutex_lock(&idnode_mutex); @@ -977,11 +977,13 @@ idnode_thread ( void *p ) /* Finished */ pthread_mutex_unlock(&global_lock); htsmsg_destroy(q); + q = NULL; /* Wait */ usleep(500000); pthread_mutex_lock(&idnode_mutex); } + if (q) htsmsg_destroy(q); return NULL; } diff --git a/src/imagecache.c b/src/imagecache.c index b302d74f..cc28dc42 100644 --- a/src/imagecache.c +++ b/src/imagecache.c @@ -165,7 +165,7 @@ void imagecache_init ( void ) #if ENABLE_IMAGECACHE { pthread_t tid; - tvhthread_create(&tid, NULL, _imagecache_thread, NULL); + tvhthread_create(&tid, NULL, _imagecache_thread, NULL, 1); } #endif } diff --git a/src/input/mpegts/dvb_psi.c b/src/input/mpegts/dvb_psi.c index 6354aed5..12761447 100644 --- a/src/input/mpegts/dvb_psi.c +++ b/src/input/mpegts/dvb_psi.c @@ -335,7 +335,7 @@ dvb_desc_service str = sname; while (*str && *str <= 32) str++; - strncpy(sname, str, sname_len); // Note: could avoid this copy by passing an output ptr + memmove(sname, str, sname_len); // Note: could avoid this copy by passing an output ptr l = strlen(str); while (l > 1 && str[l-1] <= 32) { str[l-1] = 0; diff --git a/src/input/mpegts/iptv/iptv.c b/src/input/mpegts/iptv/iptv.c index 9259ce4e..af40f4da 100644 --- a/src/input/mpegts/iptv/iptv.c +++ b/src/input/mpegts/iptv/iptv.c @@ -526,13 +526,13 @@ void iptv_init ( void ) mpegts_input_set_network((mpegts_input_t*)&iptv_input, (mpegts_network_t*)&iptv_network); /* Set table thread */ - tvhthread_create(&tid, NULL, mpegts_input_table_thread, &iptv_input); + tvhthread_create(&tid, NULL, mpegts_input_table_thread, &iptv_input, 1); /* Setup TS thread */ // TODO: could set this up only when needed iptv_poll = tvhpoll_create(10); pthread_mutex_init(&iptv_lock, NULL); - tvhthread_create(&iptv_thread, NULL, iptv_input_thread, NULL); + tvhthread_create(&iptv_thread, NULL, iptv_input_thread, NULL, 1); /* Load config */ iptv_mux_load_all(); diff --git a/src/input/mpegts/linuxdvb/linuxdvb_adapter.c b/src/input/mpegts/linuxdvb/linuxdvb_adapter.c index 51336b4a..cd83a284 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_adapter.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_adapter.c @@ -73,8 +73,6 @@ linuxdvb_adapter_save ( linuxdvb_adapter_t *la, htsmsg_t *m ) idnode_save(&la->ti_id, m); htsmsg_add_u32(m, "number", la->la_number); - if (la->la_rootpath) - htsmsg_add_str(m, "rootpath", la->la_rootpath); /* Frontends */ l = htsmsg_create_map(); @@ -130,7 +128,6 @@ linuxdvb_adapter_create0 ( linuxdvb_device_t *ld, const char *uuid, htsmsg_t *conf ) { uint32_t u32; - const char *str; htsmsg_t *e; htsmsg_field_t *f; linuxdvb_adapter_t *la; @@ -145,7 +142,6 @@ linuxdvb_adapter_create0 la->lh_parent = (linuxdvb_hardware_t*)ld; la->mi_is_enabled = linuxdvb_adapter_is_enabled; la->mi_enabled = 1; - la->la_dvb_number = -1; /* No conf */ @@ -155,8 +151,6 @@ linuxdvb_adapter_create0 idnode_load(&la->ti_id, conf); if (!htsmsg_get_u32(conf, "number", &u32)) la->la_number = u32; - if ((str = htsmsg_get_str(conf, "rootpath"))) - la->la_rootpath = strdup(str); /* Frontends */ if ((conf = htsmsg_get_map(conf, "frontends"))) { diff --git a/src/input/mpegts/linuxdvb/linuxdvb_device.c b/src/input/mpegts/linuxdvb/linuxdvb_device.c index 33fb990f..442e8e25 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_device.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_device.c @@ -194,6 +194,7 @@ void linuxdvb_device_save ( linuxdvb_device_t *ld ) /* Save */ hts_settings_save(m, "input/linuxdvb/devices/%s", idnode_uuid_as_str(&ld->ti_id)); + htsmsg_destroy(m); } const idclass_t linuxdvb_device_class = @@ -282,12 +283,19 @@ linuxdvb_device_find_by_adapter ( int a ) /* Find existing */ if ((ld = linuxdvb_device_find_by_hwid(dev.di_id))) { - memcpy(&ld->ld_devid, &dev, sizeof(dev)); + free(dev.di_id); + if (ld->ld_devid.di_bus == BUS_NONE) { + strcpy(ld->ld_devid.di_path, dev.di_path); + ld->ld_devid.di_bus = dev.di_bus; + ld->ld_devid.di_dev = dev.di_dev; + ld->ld_devid.di_min_adapter = dev.di_min_adapter; + } return ld; } /* Create new */ if (!(ld = linuxdvb_device_create0(NULL, NULL))) { + free(dev.di_id); tvhlog(LOG_ERR, "linuxdvb", "failed to create device for adapter%d", a); return NULL; } @@ -295,6 +303,7 @@ linuxdvb_device_find_by_adapter ( int a ) /* Copy device info */ memcpy(&ld->ld_devid, &dev, sizeof(dev)); ld->mi_displayname = strdup(dev.di_id); + ld->ld_devid.di_id = dev.di_id; return ld; } @@ -311,6 +320,7 @@ void linuxdvb_device_init ( int adapter_mask ) if (!(e = htsmsg_get_map_by_field(f))) continue; (void)linuxdvb_device_create0(f->hmf_name, e); } + htsmsg_destroy(s); } /* Scan for hardware */ diff --git a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c index 41d6574e..972b5911 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c @@ -492,7 +492,7 @@ linuxdvb_frontend_monitor ( void *aux ) tvh_pipe(O_NONBLOCK, &lfe->lfe_dvr_pipe); pthread_mutex_lock(&lfe->lfe_dvr_lock); tvhthread_create(&lfe->lfe_dvr_thread, NULL, - linuxdvb_frontend_input_thread, lfe); + linuxdvb_frontend_input_thread, lfe, 0); pthread_cond_wait(&lfe->lfe_dvr_cond, &lfe->lfe_dvr_lock); pthread_mutex_unlock(&lfe->lfe_dvr_lock); @@ -683,6 +683,7 @@ linuxdvb_frontend_tune0 #define S2CMD(c, d)\ cmds[cmdseq.num].cmd = c;\ cmds[cmdseq.num++].u.data = d + memset(&cmds, 0, sizeof(cmds)); S2CMD(DTV_DELIVERY_SYSTEM, lm->lm_tuning.dmc_fe_delsys); S2CMD(DTV_FREQUENCY, freq); S2CMD(DTV_INVERSION, p->inversion); @@ -840,7 +841,7 @@ linuxdvb_frontend_create0 pthread_cond_init(&lfe->lfe_dvr_cond, NULL); /* Start table thread */ - tvhthread_create(&tid, NULL, mpegts_input_table_thread, lfe); + tvhthread_create(&tid, NULL, mpegts_input_table_thread, lfe, 1); /* No conf */ if (!conf) @@ -890,6 +891,9 @@ linuxdvb_frontend_added memcpy(&lfe->lfe_info, fe_info, sizeof(struct dvb_frontend_info)); /* Set paths */ + free(lfe->lfe_fe_path); + free(lfe->lfe_dvr_path); + free(lfe->lfe_dmx_path); lfe->lfe_fe_path = strdup(fe_path); lfe->lfe_dmx_path = strdup(dmx_path); lfe->lfe_dvr_path = strdup(dvr_path); diff --git a/src/input/mpegts/linuxdvb/linuxdvb_network.c b/src/input/mpegts/linuxdvb/linuxdvb_network.c index 2c9d0757..02c24d8e 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_network.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_network.c @@ -332,6 +332,7 @@ linuxdvb_network_create0 if (!(e = htsmsg_get_map(e, "config"))) continue; (void)linuxdvb_mux_create1(ln, f->hmf_name, e); } + htsmsg_destroy(c); } return ln; diff --git a/src/input/mpegts/linuxdvb/linuxdvb_private.h b/src/input/mpegts/linuxdvb/linuxdvb_private.h index 63bc6de5..3fd165bf 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_private.h +++ b/src/input/mpegts/linuxdvb/linuxdvb_private.h @@ -34,7 +34,7 @@ typedef LIST_HEAD(,linuxdvb_hardware) linuxdvb_hardware_list_t; typedef struct device_info { - char *di_id; + char *di_id; char di_path[128]; enum { BUS_NONE = 0, diff --git a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c index 8a4f62a8..e0dd04f7 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c @@ -641,6 +641,7 @@ linuxdvb_satconf_init ( void ) if (!(e = htsmsg_get_map_by_field(f))) continue; (void)linuxdvb_satconf_create0(f->hmf_name, e); } + htsmsg_destroy(s); } } diff --git a/src/input/mpegts/tsfile/tsfile_input.c b/src/input/mpegts/tsfile/tsfile_input.c index a3914383..c0bf1090 100644 --- a/src/input/mpegts/tsfile/tsfile_input.c +++ b/src/input/mpegts/tsfile/tsfile_input.c @@ -206,7 +206,7 @@ tsfile_input_start_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *t ) return SM_CODE_TUNING_FAILED; } tvhtrace("tsfile", "adapter %d starting thread", mi->mi_instance); - tvhthread_create(&mi->mi_thread_id, NULL, tsfile_input_thread, mi); + tvhthread_create(&mi->mi_thread_id, NULL, tsfile_input_thread, mi, 0); } /* Current */ @@ -244,7 +244,7 @@ tsfile_input_create ( int idx ) mi->mi_displayname = strdup("TSFile"); /* Start table thread */ - tvhthread_create(&tid, NULL, mpegts_input_table_thread, mi); + tvhthread_create(&tid, NULL, mpegts_input_table_thread, mi, 1); return mi; } diff --git a/src/main.c b/src/main.c index 3767ecc2..01278878 100644 --- a/src/main.c +++ b/src/main.c @@ -114,6 +114,7 @@ static cmdline_opt_t* cmdline_opt_find /* * Globals */ +int tvheadend_running; int tvheadend_webui_port; int tvheadend_webui_debug; int tvheadend_htsp_port; @@ -154,7 +155,6 @@ pthread_mutex_t atomic_lock; /* * Locals */ -static int running; static LIST_HEAD(, gtimer) gtimers; static pthread_cond_t gtimer_cond; @@ -167,7 +167,7 @@ handle_sigpipe(int x) static void doexit(int x) { - running = 0; + tvheadend_running = 0; } static int @@ -343,7 +343,7 @@ mainloop(void) gti_callback_t *cb; struct timespec ts; - while(running) { + while(tvheadend_running) { clock_gettime(CLOCK_REALTIME, &ts); /* 1sec stuff */ @@ -760,7 +760,7 @@ main(int argc, char **argv) * Wait for SIGTERM / SIGINT, but only in this thread */ - running = 1; + tvheadend_running = 1; sigemptyset(&set); sigaddset(&set, SIGTERM); sigaddset(&set, SIGINT); @@ -796,6 +796,8 @@ main(int argc, char **argv) if(opt_fork) unlink(opt_pidpath); + // TODO: could join all threads for clean shutdown + return 0; } diff --git a/src/service.c b/src/service.c index a239d2c4..e2ceb4b6 100644 --- a/src/service.c +++ b/src/service.c @@ -986,7 +986,7 @@ service_init(void) TAILQ_INIT(&service_all); pthread_mutex_init(&pending_save_mutex, NULL); pthread_cond_init(&pending_save_cond, NULL); - tvhthread_create(&tid, NULL, service_saver, NULL); + tvhthread_create(&tid, NULL, service_saver, NULL, 1); } diff --git a/src/service_mapper.c b/src/service_mapper.c index af9c5c14..089e9588 100644 --- a/src/service_mapper.c +++ b/src/service_mapper.c @@ -48,7 +48,7 @@ service_mapper_init ( void ) pthread_t tid; TAILQ_INIT(&service_mapper_queue); pthread_cond_init(&service_mapper_cond, NULL); - tvhthread_create(&tid, NULL, service_mapper_thread, NULL); + tvhthread_create(&tid, NULL, service_mapper_thread, NULL, 1); } /* diff --git a/src/tcp.c b/src/tcp.c index 980a0dba..8be7f367 100644 --- a/src/tcp.c +++ b/src/tcp.c @@ -490,7 +490,7 @@ tcp_server_loop(void *aux) continue; } - tvhthread_create(&tid, &attr, tcp_server_start, tsl); + tvhthread_create(&tid, &attr, tcp_server_start, tsl, 1); } } return NULL; @@ -590,7 +590,7 @@ tcp_server_init(int opt_ipv6) tcp_preferred_address_family = AF_INET6; tcp_server_poll = tvhpoll_create(10); - tvhthread_create(&tid, NULL, tcp_server_loop, NULL); + tvhthread_create(&tid, NULL, tcp_server_loop, NULL, 1); } diff --git a/src/timeshift.c b/src/timeshift.c index 0f5e49b4..9ca7201d 100644 --- a/src/timeshift.c +++ b/src/timeshift.c @@ -253,8 +253,8 @@ streaming_target_t *timeshift_create /* Initialise input */ streaming_queue_init(&ts->wr_queue, 0); streaming_target_init(&ts->input, timeshift_input, ts, 0); - tvhthread_create(&ts->wr_thread, NULL, timeshift_writer, ts); - tvhthread_create(&ts->rd_thread, NULL, timeshift_reader, ts); + tvhthread_create(&ts->wr_thread, NULL, timeshift_writer, ts, 0); + tvhthread_create(&ts->rd_thread, NULL, timeshift_reader, ts, 0); /* Update index */ timeshift_index++; diff --git a/src/timeshift/timeshift_filemgr.c b/src/timeshift/timeshift_filemgr.c index a98a4280..bf7cf937 100644 --- a/src/timeshift/timeshift_filemgr.c +++ b/src/timeshift/timeshift_filemgr.c @@ -345,7 +345,7 @@ void timeshift_filemgr_init ( void ) pthread_cond_init(×hift_reaper_cond, NULL); TAILQ_INIT(×hift_reaper_list); tvhthread_create(×hift_reaper_thread, NULL, - timeshift_reaper_callback, NULL); + timeshift_reaper_callback, NULL, 1); } /* diff --git a/src/tvheadend.h b/src/tvheadend.h index e7d0a226..e369df09 100644 --- a/src/tvheadend.h +++ b/src/tvheadend.h @@ -47,6 +47,7 @@ typedef struct { const char *name; const uint32_t *enabled; } tvh_caps_t; +extern int tvheadend_running; extern const char *tvheadend_version; extern const char *tvheadend_cwd; extern const char *tvheadend_webroot; @@ -524,10 +525,12 @@ static inline void mystrset(char **p, const char *s) *p = s ? strdup(s) : NULL; } -int tvhthread_create0(pthread_t *thread, const pthread_attr_t *attr, - void *(*start_routine) (void *), void *arg, const char *name); +int tvhthread_create0 + (pthread_t *thread, const pthread_attr_t *attr, + void *(*start_routine) (void *), void *arg, + const char *name, int detach); -#define tvhthread_create(a, b, c, d) tvhthread_create0(a, b, c, d, #c) +#define tvhthread_create(a, b, c, d, e) tvhthread_create0(a, b, c, d, #c, e) int tvh_open(const char *pathname, int flags, mode_t mode); diff --git a/src/tvhlog.c b/src/tvhlog.c index 7550bf7f..10f25a47 100644 --- a/src/tvhlog.c +++ b/src/tvhlog.c @@ -215,7 +215,7 @@ static void * tvhlog_thread ( void *p ) { int options; - char *path = NULL; + char *path, buf[512]; FILE *fp = NULL; tvhlog_msg_t *msg; @@ -240,8 +240,12 @@ tvhlog_thread ( void *p ) /* Copy options and path */ if (!fp) { - free(path); - path = tvhlog_path ? strdup(tvhlog_path) : NULL; + if (tvhlog_path) { + strncpy(buf, tvhlog_path, sizeof(buf)); + path = buf; + } else { + path = NULL; + } } options = tvhlog_options; pthread_mutex_unlock(&tvhlog_mutex); @@ -406,7 +410,7 @@ tvhlog_init ( int level, int options, const char *path ) pthread_mutex_init(&tvhlog_mutex, NULL); pthread_cond_init(&tvhlog_cond, NULL); TAILQ_INIT(&tvhlog_queue); - tvhthread_create(&tvhlog_tid, NULL, tvhlog_thread, NULL); + tvhthread_create(&tvhlog_tid, NULL, tvhlog_thread, NULL, 1); } void diff --git a/src/wrappers.c b/src/wrappers.c index a2de2df7..900e2357 100644 --- a/src/wrappers.c +++ b/src/wrappers.c @@ -109,11 +109,16 @@ thread_wrapper ( void *p ) int tvhthread_create0 (pthread_t *thread, const pthread_attr_t *attr, - void *(*start_routine) (void *), void *arg, const char *name) + void *(*start_routine) (void *), void *arg, const char *name, + int detach) { + int r; struct thread_state *ts = calloc(1, sizeof(struct thread_state)); strncpy(ts->name, name, sizeof(ts->name)); - ts->run = start_routine; - ts->arg = arg; - return pthread_create(thread, attr, thread_wrapper, ts); + ts->run = start_routine; + ts->arg = arg; + r = pthread_create(thread, attr, thread_wrapper, ts); + if (detach) + pthread_detach(*thread); + return r; }