From: Jaroslav Kysela Date: Fri, 24 Apr 2015 11:44:01 +0000 (+0200) Subject: implemented deferred_unlink() for DVR X-Git-Tag: v4.1~117 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2b00b887849aec61c4aa36aee61a22dad389fde5;p=thirdparty%2Ftvheadend.git implemented deferred_unlink() for DVR --- diff --git a/src/dvr/dvr_db.c b/src/dvr/dvr_db.c index 533bcc1a1..20ab11006 100644 --- a/src/dvr/dvr_db.c +++ b/src/dvr/dvr_db.c @@ -2210,6 +2210,7 @@ dvr_entry_delete(dvr_entry_t *de) time_t t; struct tm tm; char tbuf[64]; + int r; t = dvr_entry_get_start_time(de); localtime_r(&t, &tm); @@ -2227,9 +2228,10 @@ dvr_entry_delete(dvr_entry_t *de) #if ENABLE_INOTIFY dvr_inotify_del(de); #endif - if(unlink(de->de_filename) && errno != ENOENT) + r = deferred_unlink(de->de_filename); + if(r && r != -ENOENT) tvhlog(LOG_WARNING, "dvr", "Unable to remove file '%s' from disk -- %s", - de->de_filename, strerror(errno)); + de->de_filename, strerror(-errno)); /* Also delete directories, if they were created for the recording and if they are empty */ diff --git a/src/main.c b/src/main.c index 6a82df71b..2fabff7d5 100644 --- a/src/main.c +++ b/src/main.c @@ -305,6 +305,20 @@ gtimer_disarm(gtimer_t *gti) } } +/** + * + */ +tasklet_t * +tasklet_arm_alloc(tsk_callback_t *callback, void *opaque) +{ + tasklet_t *tsk = calloc(1, sizeof(*tsk)); + if (tsk) { + tsk->tsk_allocated = 1; + tasklet_arm(tsk, callback, opaque); + } + return tsk; +} + /** * */ @@ -339,6 +353,8 @@ tasklet_disarm(tasklet_t *tsk) TAILQ_REMOVE(&tasklets, tsk, tsk_link); tsk->tsk_callback(tsk->tsk_opaque, 1); tsk->tsk_callback = NULL; + if (tsk->tsk_allocated) + free(tsk); } pthread_mutex_unlock(&tasklet_lock); @@ -355,6 +371,8 @@ tasklet_flush() TAILQ_REMOVE(&tasklets, tsk, tsk_link); tsk->tsk_callback(tsk->tsk_opaque, 1); tsk->tsk_callback = NULL; + if (tsk->tsk_allocated) + free(tsk); } pthread_mutex_unlock(&tasklet_lock); @@ -538,6 +556,7 @@ main(int argc, char **argv) pthread_mutex_init(&atomic_lock, NULL); pthread_cond_init(>imer_cond, NULL); pthread_cond_init(&tasklet_cond, NULL); + TAILQ_INIT(&tasklets); /* Defaults */ tvheadend_webui_port = 9981; @@ -1058,6 +1077,7 @@ main(int argc, char **argv) tvhftrace("main", spawn_done); tvhtrace("main", "tasklet enter"); + pthread_cond_signal(&tasklet_cond); pthread_join(tasklet_tid, NULL); tvhtrace("main", "tasklet thread end"); tasklet_flush(); diff --git a/src/tvheadend.h b/src/tvheadend.h index 67dead208..6db892d68 100644 --- a/src/tvheadend.h +++ b/src/tvheadend.h @@ -184,8 +184,10 @@ typedef struct tasklet { TAILQ_ENTRY(tasklet) tsk_link; tsk_callback_t *tsk_callback; void *tsk_opaque; + int tsk_allocated; } tasklet_t; +tasklet_t *tasklet_arm_alloc(tsk_callback_t *callback, void *opaque); void tasklet_arm(tasklet_t *tsk, tsk_callback_t *callback, void *opaque); void tasklet_disarm(tasklet_t *gti); @@ -736,6 +738,8 @@ char *url_encode(char *str); int mpegts_word_count(const uint8_t *tsb, int len, uint32_t mask); +int deferred_unlink(const char *filename); + static inline int32_t deltaI32(int32_t a, int32_t b) { return (a > b) ? (a - b) : (b - a); } static inline uint32_t deltaU32(uint32_t a, uint32_t b) { return (a > b) ? (a - b) : (b - a); } diff --git a/src/utils.c b/src/utils.c index ba7ec46cf..3bfe245e0 100644 --- a/src/utils.c +++ b/src/utils.c @@ -638,3 +638,34 @@ mpegts_word_count ( const uint8_t *tsb, int len, uint32_t mask ) return r; } + +static void +deferred_unlink_cb(void *s, int dearmed) +{ + if (unlink((const char *)s)) + tvherror("main", "unable to remove file '%s'", (const char *)s); + free(s); +} + +int +deferred_unlink(const char *filename) +{ + char *s; + size_t l; + int r; + + l = strlen(filename); + s = malloc(l + 9); + if (s == NULL) + return -ENOMEM; + strcpy(s, filename); + strcpy(s + l, ".removing"); + r = rename(filename, s); + if (r) { + r = -errno; + free(s); + return r; + } + tasklet_arm_alloc(deferred_unlink_cb, s); + return 0; +}