]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
timeshift: read from file fixes, added filemgr_dump traces
authorJaroslav Kysela <perex@perex.cz>
Sun, 3 Jan 2016 20:44:09 +0000 (21:44 +0100)
committerJaroslav Kysela <perex@perex.cz>
Sun, 3 Jan 2016 20:44:09 +0000 (21:44 +0100)
src/timeshift/private.h
src/timeshift/timeshift_filemgr.c
src/timeshift/timeshift_reader.c
src/timeshift/timeshift_writer.c

index f668060a128d9d16a3612434792954a8e0414d9b..e24ca74b2fa4b524e454e047a9c091e203064410 100644 (file)
@@ -180,4 +180,12 @@ void timeshift_filemgr_remove
 void timeshift_filemgr_flush ( timeshift_t *ts, timeshift_file_t *end );
 void timeshift_filemgr_close ( timeshift_file_t *tsf );
 
+void timeshift_filemgr_dump0 ( timeshift_t *ts );
+
+static inline void timeshift_filemgr_dump ( timeshift_t *ts )
+{
+  if (tvhtrace_enabled())
+    timeshift_filemgr_dump0(ts);
+}
+
 #endif /* __TVH_TIMESHIFT_PRIVATE_H__ */
index 7214c8646246a03e85200ec44454342ae12d0a4b..0e0e4f0ae7e6ebf3ee969fc36eddbac0b78158c3 100644 (file)
@@ -119,6 +119,21 @@ static void timeshift_reaper_remove ( timeshift_file_t *tsf )
  * File Handling
  * *************************************************************************/
 
+void
+timeshift_filemgr_dump0 ( timeshift_t *ts )
+{
+  timeshift_file_t *tsf;
+
+  if (TAILQ_EMPTY(&ts->files)) {
+    tvhtrace("timeshift", "ts %d file dump - EMPTY", ts->id);
+    return;
+  }
+  TAILQ_FOREACH(tsf, &ts->files, link) {
+    tvhtrace("timeshift", "ts %d file dump tsf %p time %"PRId64" last %"PRId64,
+             ts->id, tsf, tsf->time, tsf->last);
+  }
+}
+
 /*
  * Get root directory
  *
@@ -321,7 +336,7 @@ timeshift_file_t *timeshift_filemgr_get ( timeshift_t *ts, int64_t start_time )
         /* Create File */
         snprintf(path, sizeof(path), "%s/tvh-%"PRId64, ts->path, start_time);
         tvhtrace("timeshift", "ts %d create file %s", ts->id, path);
-        if ((fd = open(path, O_WRONLY | O_CREAT, 0600)) > 0) {
+        if ((fd = tvh_open(path, O_WRONLY | O_CREAT, 0600)) > 0) {
           tsf_tmp = timeshift_filemgr_file_init(ts, start_time);
           tsf_tmp->wfd = fd;
           tsf_tmp->path = strdup(path);
@@ -339,6 +354,7 @@ timeshift_file_t *timeshift_filemgr_get ( timeshift_t *ts, int64_t start_time )
         }
       }
     }
+    timeshift_filemgr_dump(ts);
     tsf_tl = tsf_tmp;
   }
 
index 0668e5dd51d2a505125aaee4948bf4015cdb79b9..f4e2260b152ec54334929bbb855cf758929f75db 100644 (file)
@@ -43,6 +43,8 @@
 
 static ssize_t _read_buf ( timeshift_file_t *tsf, int fd, void *buf, size_t size )
 {
+  size_t r, ret;
+
   if (tsf && tsf->ram) {
     if (tsf->roff == tsf->woff) return 0;
     if (tsf->roff + size > tsf->woff) return -1;
@@ -52,10 +54,26 @@ static ssize_t _read_buf ( timeshift_file_t *tsf, int fd, void *buf, size_t size
     pthread_mutex_unlock(&tsf->ram_lock);
     return size;
   } else {
-    size = read(tsf ? tsf->rfd : fd, buf, size);
-    if (size > 0 && tsf)
-      tsf->roff += size;
-    return size;
+    ret = 0;
+    while (size > 0) {
+      r = read(tsf ? tsf->rfd : fd, buf, size);
+      if (r < 0) {
+        if (ERRNO_AGAIN(errno))
+          continue;
+        tvhtrace("timeshift", "read errno %d", errno);
+        return -1;
+      }
+      if (r > 0) {
+        size -= r;
+        ret += r;
+        buf += r;
+      }
+      if (r == 0)
+        return 0;
+    }
+    if (ret > 0 && tsf)
+      tsf->roff += r;
+    return ret;
   }
 }
 
@@ -367,7 +385,7 @@ static int _timeshift_read
 {
   timeshift_file_t *tsf = *cur_file;
   ssize_t r;
-  off_t off;
+  off_t off = 0;
 
   *sm = NULL;
 
@@ -375,7 +393,7 @@ static int _timeshift_read
 
     /* Open file */
     if (tsf->rfd < 0 && !tsf->ram) {
-      tsf->rfd = open(tsf->path, O_RDONLY);
+      tsf->rfd = tvh_open(tsf->path, O_RDONLY, 0);
       tvhtrace("timeshift", "ts %d open file %s (fd %i)", ts->id, tsf->path, tsf->rfd);
       if (tsf->rfd < 0)
         return -1;
@@ -395,19 +413,19 @@ static int _timeshift_read
       return -1;
     }
     tvhtrace("timeshift", "ts %d seek to %jd (fd %i) read msg %p/%"PRId64" (%"PRId64")",
-             ts->id, (intmax_t)tsf->roff, tsf->rfd, *sm, *sm ? (*sm)->sm_time : -1, (int64_t)r);
+             ts->id, (intmax_t)off, tsf->rfd, *sm, *sm ? (*sm)->sm_time : -1, (int64_t)r);
 
     /* Special case - EOF */
     if (r <= sizeof(size_t) || tsf->roff > tsf->size || *sm == NULL) {
       if (tsf->rfd >= 0)
         close(tsf->rfd);
       tsf->rfd  = -1;
-      *cur_file = tsf = timeshift_filemgr_next(tsf, NULL, 0);
-      if (tsf)
-        tsf->roff = 0; // reset
+      *cur_file = timeshift_filemgr_next(tsf, NULL, 0);
+      if (*cur_file)
+        (*cur_file)->roff = 0; // reset
       *wait     = 0;
-      tvhtrace("timeshift", "ts %d eof, cur_file %p", ts->id, *cur_file);
-
+      tvhtrace("timeshift", "ts %d eof, cur_file %p (prev %p)", ts->id, *cur_file, tsf);
+      timeshift_filemgr_dump(ts);
     }
   }
   return 0;
@@ -821,11 +839,9 @@ void *timeshift_reader ( void *p )
 
     /* Terminate */
     if (!cur_file || end != 0) {
-      if (!end)
-        end = (cur_speed > 0) ? 1 : -1;
 
       /* Back to live (unless buffer is full) */
-      if (end == 1 && !ts->full) {
+      if ((end == 1 && !ts->full) || !cur_file) {
         tvhlog(LOG_DEBUG, "timeshift", "ts %d eob revert to live mode", ts->id);
         cur_speed = 100;
         ctrl      = streaming_msg_create_code(SMT_SPEED, cur_speed);
@@ -834,8 +850,10 @@ void *timeshift_reader ( void *p )
         tvhtrace("timeshift", "reader - set TS_LIVE");
 
         /* Flush timeshift buffer to live */
-        if (_timeshift_flush_to_live(ts, &cur_file, &wait) == -1)
+        if (_timeshift_flush_to_live(ts, &cur_file, &wait) == -1) {
+          pthread_mutex_unlock(&ts->state_mutex);
           break;
+        }
 
         ts->state = TS_LIVE;
 
index 89e30d2b0d46fe76dca8eeeb7381acb019710eb9..0d1682c7dff32a1f1e2dac91e2f5733b086180d7 100644 (file)
@@ -59,6 +59,7 @@ static ssize_t _write
 {
   uint8_t *ram;
   size_t alloc;
+  ssize_t ret;
   if (tsf->ram) {
     pthread_mutex_lock(&tsf->ram_lock);
     if (tsf->ram_size < tsf->woff + count) {
@@ -80,7 +81,10 @@ static ssize_t _write
     pthread_mutex_unlock(&tsf->ram_lock);
     return count;
   }
-  return _write_fd(tsf->wfd, buf, count);
+  ret = _write_fd(tsf->wfd, buf, count);
+  if (ret > 0)
+    tsf->woff += ret;
+  return ret;
 }
 
 /*