close screen when session is closed
[enigma2.git] / lib / base / filepush.cpp
1 #include <config.h>
2 #include <lib/base/filepush.h>
3 #include <lib/base/eerror.h>
4 #include <errno.h>
5 #include <fcntl.h>
6
7 eFilePushThread::eFilePushThread()
8 {
9         m_stop = 0;
10         flush();
11 }
12
13 static void signal_handler(int x)
14 {
15 }
16
17 void eFilePushThread::thread()
18 {
19         off_t dest_pos = 0;
20         eDebug("FILEPUSH THREAD START");
21                 // this is a race. FIXME.
22         
23                 /* we set the signal to not restart syscalls, so we can detect our signal. */
24         struct sigaction act;
25         act.sa_handler = signal_handler; // no, SIG_IGN doesn't do it. we want to receive the -EINTR
26         act.sa_flags = 0;
27         sigaction(SIGUSR1, &act, 0);
28         
29         dest_pos = lseek(m_fd_dest, 0, SEEK_CUR);
30                 /* m_stop must be evaluated after each syscall. */
31         while (!m_stop)
32         {
33                         /* first try flushing the bufptr */
34                 if (m_buf_start != m_buf_end)
35                 {
36                                 // TODO: take care of boundaries.
37                         int w = write(m_fd_dest, m_buffer + m_buf_start, m_buf_end - m_buf_start);
38                         eDebug("wrote %d bytes", w);
39                         if (w <= 0)
40                         {
41                                 if (errno == -EINTR)
42                                         continue;
43                                 eDebug("eFilePushThread *write error* - not yet handled");
44                                 // ... we would stop the thread
45                         }
46
47                                 /* this should flush all written pages to disk. */
48                         posix_fadvise(m_fd_dest, dest_pos, w, POSIX_FADV_DONTNEED);
49
50                         dest_pos += w;
51 //                      printf("FILEPUSH: wrote %d bytes\n", w);
52                         m_buf_start += w;
53                         continue;
54                 }
55                         
56                         /* now fill our buffer. */
57                 m_buf_start = 0;
58                 m_buf_end = read(m_fd_source, m_buffer, sizeof(m_buffer));
59                 if (m_buf_end < 0)
60                 {
61                         m_buf_end = 0;
62                         if (errno == EINTR)
63                                 continue;
64                         eDebug("eFilePushThread *read error* - not yet handled");
65                 }
66                 if (m_buf_end == 0)
67                 {
68                         eDebug("FILEPUSH: end-of-file! (currently unhandled)");
69                         if (!lseek(m_fd_source, 0, SEEK_SET))
70                         {
71                                 eDebug("(looping)");
72                                 continue;
73                         }
74                         break;
75                 }
76 //              printf("FILEPUSH: read %d bytes\n", m_buf_end);
77         }
78         
79         eDebug("FILEPUSH THREAD STOP");
80 }
81
82 void eFilePushThread::start(int fd_source, int fd_dest)
83 {
84         m_fd_source = fd_source;
85         m_fd_dest = fd_dest;
86         resume();
87 }
88
89 void eFilePushThread::stop()
90 {
91         m_stop = 1;
92         sendSignal(SIGUSR1);
93         kill();
94 }
95
96 void eFilePushThread::pause()
97 {
98         stop();
99 }
100
101 void eFilePushThread::seek(int whence, off_t where)
102 {
103         ::lseek(m_fd_source, where, whence);
104 }
105
106 void eFilePushThread::resume()
107 {
108         m_stop = 0;
109         run();
110 }
111
112 void eFilePushThread::flush()
113 {
114         m_buf_start = m_buf_end = 0;
115 }
116