1 #include <lib/base/filepush.h>
2 #include <lib/base/eerror.h>
9 eFilePushThread::eFilePushThread(): m_messagepump(eApp, 0)
15 CONNECT(m_messagepump.recv_msg, eFilePushThread::recvEvent);
18 static void signal_handler(int x)
22 void eFilePushThread::thread()
24 off_t dest_pos = 0, source_pos = 0;
25 size_t bytes_read = 0;
27 off_t current_span_offset = 0;
28 size_t current_span_remaining = 0;
30 size_t written_since_last_sync = 0;
32 int already_empty = 0;
33 eDebug("FILEPUSH THREAD START");
34 // this is a race. FIXME.
36 dest_pos = lseek(m_fd_dest, 0, SEEK_CUR);
37 source_pos = m_raw_source.lseek(0, SEEK_CUR);
39 /* m_stop must be evaluated after each syscall. */
42 /* first try flushing the bufptr */
43 if (m_buf_start != m_buf_end)
45 // TODO: take care of boundaries.
46 filterRecordData(m_buffer + m_buf_start, m_buf_end - m_buf_start);
47 int w = write(m_fd_dest, m_buffer + m_buf_start, m_buf_end - m_buf_start);
48 // eDebug("wrote %d bytes", w);
54 // ... we would stop the thread
57 // posix_fadvise(m_fd_dest, dest_pos, w, POSIX_FADV_DONTNEED);
60 written_since_last_sync += w;
62 if (written_since_last_sync >= 2048*1024)
65 written_since_last_sync = 0;
68 // printf("FILEPUSH: wrote %d bytes\n", w);
73 /* now fill our buffer. */
75 if (m_sg && !current_span_remaining)
77 m_sg->getNextSourceSpan(source_pos, bytes_read, current_span_offset, current_span_remaining);
79 if (source_pos != current_span_offset)
80 source_pos = m_raw_source.lseek(current_span_offset, SEEK_SET);
84 size_t maxread = sizeof(m_buffer);
86 /* if we have a source span, don't read past the end */
87 if (m_sg && maxread > current_span_remaining)
88 maxread = current_span_remaining;
94 m_buf_end = m_raw_source.read(m_buffer, maxread);
101 if (errno == EOVERFLOW)
103 eWarning("OVERFLOW while recording");
106 eDebug("eFilePushThread *read error* (%m) - not yet handled");
110 /* on EOF, try COMMITting once. */
111 if (m_send_pvr_commit && !already_empty)
113 eDebug("sending PVR commit");
115 if (::ioctl(m_fd_dest, PVR_COMMIT) < 0 && errno == EINTR)
117 eDebug("commit done");
118 /* well check again */
123 eDebug("FILEPUSH: end-of-file! (currently unhandled)");
124 if (!m_raw_source.lseek(0, SEEK_SET))
133 source_pos += m_buf_end;
134 bytes_read += m_buf_end;
136 current_span_remaining -= m_buf_end;
139 // printf("FILEPUSH: read %d bytes\n", m_buf_end);
142 eDebug("FILEPUSH THREAD STOP");
145 void eFilePushThread::start(int fd_source, int fd_dest)
147 m_raw_source.setfd(fd_source);
152 int eFilePushThread::start(const char *filename, int fd_dest)
154 if (m_raw_source.open(filename) < 0)
161 void eFilePushThread::installSigUSR1Handler()
163 /* we set the signal to not restart syscalls, so we can detect our signal. */
164 struct sigaction act;
165 act.sa_handler = signal_handler; // no, SIG_IGN doesn't do it. we want to receive the -EINTR
167 sigaction(SIGUSR1, &act, 0);
170 // called from thread before alive is set to 1
171 void eFilePushThread::before_set_thread_alive()
173 installSigUSR1Handler();
176 void eFilePushThread::stop()
178 if (!thread_running()) /* FIXME: races */
185 void eFilePushThread::pause()
190 void eFilePushThread::seek(int whence, off_t where)
192 m_raw_source.lseek(where, whence);
195 void eFilePushThread::resume()
201 void eFilePushThread::flush()
203 m_buf_start = m_buf_end = 0;
206 void eFilePushThread::enablePVRCommit(int s)
208 m_send_pvr_commit = s;
211 void eFilePushThread::setScatterGather(iFilePushScatterGather *sg)
216 void eFilePushThread::sendEvent(int evt)
218 m_messagepump.send(evt);
221 void eFilePushThread::recvEvent(const int &evt)
226 void eFilePushThread::filterRecordData(const unsigned char *data, int len)