fixes bug #467
[enigma2.git] / lib / base / filepush.cpp
index 7f85eac23a5c574bab24d74f8ee922add17eddc5..91f24ba064026502d3b69316d89c2409bd133bec 100644 (file)
@@ -6,7 +6,7 @@
 
 #define PVR_COMMIT 1
 
-FILE *f = fopen("/log.ts", "wb");
+//FILE *f = fopen("/log.ts", "wb");
 
 eFilePushThread::eFilePushThread(int io_prio_class, int io_prio_level, int blocksize)
        :prio_class(io_prio_class), prio(io_prio_level), m_messagepump(eApp, 0)
@@ -37,7 +37,6 @@ void eFilePushThread::thread()
        
        size_t written_since_last_sync = 0;
 
-       int already_empty = 0;
        eDebug("FILEPUSH THREAD START");
        
                /* we set the signal to not restart syscalls, so we can detect our signal. */
@@ -105,11 +104,11 @@ void eFilePushThread::thread()
                                   absolutely forbidden is to return EINTR and consume a non-aligned number of bytes. 
                                */
                        int w = write(m_fd_dest, m_buffer + m_buf_start, m_buf_end - m_buf_start);
-                       fwrite(m_buffer + m_buf_start, 1, m_buf_end - m_buf_start, f);
+//                     fwrite(m_buffer + m_buf_start, 1, m_buf_end - m_buf_start, f);
 //                     eDebug("wrote %d bytes", w);
                        if (w <= 0)
                        {
-                               if (errno == EINTR)
+                               if (errno == EINTR || errno == EAGAIN || errno == EBUSY)
                                        continue;
                                eDebug("eFilePushThread WRITE ERROR");
                                sendEvent(evtWriteError);
@@ -165,7 +164,7 @@ void eFilePushThread::thread()
                if (m_buf_end < 0)
                {
                        m_buf_end = 0;
-                       if (errno == EINTR)
+                       if (errno == EINTR || errno == EBUSY || errno == EAGAIN)
                                continue;
                        if (errno == EOVERFLOW)
                        {
@@ -174,18 +173,35 @@ void eFilePushThread::thread()
                        }
                        eDebug("eFilePushThread *read error* (%m) - not yet handled");
                }
+
+                       /* a read might be mis-aligned in case of a short read. */
+               int d = m_buf_end % m_blocksize;
+               if (d)
+               {
+                       m_raw_source.lseek(-d, SEEK_CUR);
+                       m_buf_end -= d;
+               }
+
                if (m_buf_end == 0)
                {
                                /* on EOF, try COMMITting once. */
-                       if (m_send_pvr_commit && !already_empty)
+                       if (m_send_pvr_commit)
                        {
-                               eDebug("sending PVR commit");
-                               already_empty = 1;
-                               if (::ioctl(m_fd_dest, PVR_COMMIT) < 0 && errno == EINTR)
-                                       continue;
-                               eDebug("commit done");
-                                               /* well check again */
-                               continue;
+                               struct pollfd pfd;
+                               pfd.fd = m_fd_dest;
+                               pfd.events = POLLIN;
+                               switch (poll(&pfd, 1, 250)) // wait for 250ms
+                               {
+                                       case 0:
+                                               eDebug("wait for driver eof timeout");
+                                               continue;
+                                       case 1:
+                                               eDebug("wait for driver eof ok");
+                                               break;
+                                       default:
+                                               eDebug("wait for driver eof aborted by signal");
+                                               continue;
+                               }
                        }
                        
                                /* in stream_mode, we are sending EOF events 
@@ -215,7 +231,6 @@ void eFilePushThread::thread()
                        bytes_read += m_buf_end;
                        if (m_sg)
                                current_span_remaining -= m_buf_end;
-                       already_empty = 0;
                }
 //             printf("FILEPUSH: read %d bytes\n", m_buf_end);
        }
@@ -248,15 +263,9 @@ void eFilePushThread::stop()
 
        m_stop = 1;
 
-       // fixmee.. here we need a better solution to ensure
-       // that the thread context take notice of the signal
-       // even when no syscall is in progress
-       while(!sendSignal(SIGUSR1))
-       {
-               eDebug("send SIGUSR1 to thread context");
-               usleep(5000); // wait msek
-       }
-       kill();
+       eDebug("stopping thread."); /* just do it ONCE. it won't help to do this more than once. */
+       sendSignal(SIGUSR1);
+       kill(0);
 }
 
 void eFilePushThread::pause()