Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[vdr] Re: Fast forward stops in timeshift mode



Oliver Endriss wrote:
> 
> On Monday 08 September 2003 16:37, Christoph Rauch wrote:
> > Am Sam, 2003-09-06 um 10.44 schrieb Klaus Schmidinger:
> > > > Configuration:
> > > > - vdr 1.2.5pre1
> > > > - driver CVS 2003-08-23
> > > > - single DVB-S Nexus 2.1
> > > > - Kernel 2.4.21
> > > > - /video on ext3
> > > Strange...
> > > The fstat() call in line 864 claimed that the file has an inceased
> > > size (as calculated in line 871), so one would assume that the
> > > safe_read() in line 883 should be able to actually read the new
> > > file content. I would think that the data is _first_ written to the
> > > end of the file and _then_ the directory entry is updated.
> > > Could it be that this is not the case? Can the directory entry
> > > be updated _before_ the data is appended to the file? That wouldn't
> > > make sense to me...
> 
> IMHO the code looks ok. I did some more tests:
> Recompiled vdr with an old gcc 2.96. With 2.96 the problem is harder
> to reproduce than with gcc 3.3, but finally the same problem happens.
> The difference might be due to a slightly different timing.
> 
> Then I modified my debug messages and got a very surprising result.
> My CatchUp() modification looks like this:
>     ...
>     index = (tIndex *)realloc(index, size * sizeof(tIndex));
>     if (index) {
>         int offset = (last + 1) * sizeof(tIndex);
>         int delta = (newLast - last) * sizeof(tIndex);
>         int l = last;
>         int nl = newLast;
>         if (lseek(f, offset, SEEK_SET) == offset) {
>             int n;
>             if ((n = safe_read(f, &index[last + 1], delta)) != delta) {
> (1)             printf("ERROR:  last %d  newlast %d\n", l, nl);
> (2)             printf("ERROR:  last %d  newlast %d\n", last, newLast);
> (3)             esyslog("ERROR: can't read from index - file %d  read %d  delta %d  last %d  newLast %d  size %d  offs %d\n", f, n, delta, last, newLast, buf.st_size, offset);
>                 free(index);
>                 index = NULL;
>                 close(f);
>                 f = -1;
>                 break;
>                 }
>             last = newLast;
>             }
>    ...
> 
> I get the following output (reproducable!):
>     ERROR:  last 28752  newlast 28753
> (1): l, nl (copied last, newLast), values look ok
>     ERROR:  last 28753  newlast 28753
> (2): 'last' has changed! See below.
>     Sep  8 18:03:11 orion vdr[17179]: ERROR: can't read from index - file 30  read 0  delta 8
>                                       last 28753  newLast 28753  size 230032  offs 230024
>                                       ^^^^^^^^^^  ^^^^^^^^^^^^^
> Strange: (1), (2) and (3) should report the same value for 'last', last < newLast.
> 
> In another test session I got delta == -8 and last == newlast+1.
> Even more strange.
> 
> This looks like a reentrancy problem. Maybe 'last' is modified by
> different threads, e.g.
> - CatchUp() is called from two different threads at the same time or
> - last is modified by one thread, while another thread calls CatchUp().
> 
> I can't believe that this is caused by a weird compiler bug.

Thanks for these detailed tests.
With this in mind I looked over dvbplayer.c and recording.c and
I think there actually is a chance that CatchUp() gets called from
the player thread _and_ the foreground program, which might result
in 'last' being changed unexpectedly.

During your tests, do you use the progress display, or any fast forward/rewind
function? AFAICS 'last' should only be messed with when those are used.

Could you please add a counter to CatchUp(), which you increment at the
entry point and decrement when leaving the function, and make a debug
printout should the counter ever become larger than 1? If you can cause
such a situation, we'll need a mutex for CatchUp().

Klaus


-- 
Info:
To unsubscribe send a mail to ecartis@linuxtv.org with "unsubscribe vdr" as subject.



Home | Main Index | Thread Index