Permalink
Browse files

Allow reopening a writeable ringbuffer with a new filename.

This functionality flushes the original file, closes it, and
reopens the file or opens a new file if an optional new filename
is supplied.

Adds ReOpen(QString newFilename) methods to RemoteFile,
ThreadedFileWriter, RingBuffer, and FileRingBuffer.  A 'REOPEN'
command is also added to the remote file transfer protocol.

This functionality will be used in a soon-to-be-committed feature.

NOTE: The binary API version changes with this commit, so
      make clean, etc..

NOTE2: This also bumps the protocol version to 70 because of
       the new file transfer command, so all components need to
       be upgraded at the same time.
  • Loading branch information...
cpinkham committed Nov 30, 2011
1 parent 77e3c7c commit 1da9d23d2838bc2d2e0bc06e2e9e1d382897d21d
@@ -106,8 +106,8 @@ package MythTV;
# Note: as of July 21, 2010, this is actually a string, to account for proto
# versions of the form "58a". This will get used if protocol versions are
# changed on a fixes branch ongoing.
- our $PROTO_VERSION = "69";
- our $PROTO_TOKEN = "63835135";
+ our $PROTO_VERSION = "70";
+ our $PROTO_TOKEN = "53153836";
# currentDatabaseVersion is defined in libmythtv in
# mythtv/libs/libmythtv/dbcheck.cpp and should be the current MythTV core
@@ -11,8 +11,8 @@ class MythBackend {
// MYTH_PROTO_VERSION is defined in libmyth in mythtv/libs/libmyth/mythcontext.h
// and should be the current MythTV protocol version.
- static $protocol_version = '69';
- static $protocol_token = '63835135';
+ static $protocol_version = '70';
+ static $protocol_token = '53153836';
// The character string used by the backend to separate records
static $backend_separator = '[]:[]';
@@ -8,8 +8,8 @@
SCHEMA_VERSION = 1285
NVSCHEMA_VERSION = 1007
MUSICSCHEMA_VERSION = 1018
-PROTO_VERSION = '69'
-PROTO_TOKEN = '63835135'
+PROTO_VERSION = '70'
+PROTO_TOKEN = '53153836'
BACKEND_SEP = '[]:[]'
INSTALL_PREFIX = '/usr/local'
@@ -12,7 +12,7 @@
/// Update this whenever the plug-in API changes.
/// Including changes in the libmythbase, libmyth, libmythtv, libmythav* and
/// libmythui class methods used by plug-ins.
-#define MYTH_BINARY_VERSION "0.25.20111116-1"
+#define MYTH_BINARY_VERSION "0.25.20111129-1"
/** \brief Increment this whenever the MythTV network protocol changes.
*
@@ -35,8 +35,8 @@
* mythtv/bindings/python/MythTV/static.py (version number)
* mythtv/bindings/python/MythTV/mythproto.py (layout)
*/
-#define MYTH_PROTO_VERSION "69"
-#define MYTH_PROTO_TOKEN "63835135"
+#define MYTH_PROTO_VERSION "70"
+#define MYTH_PROTO_TOKEN "53153836"
/** \brief Increment this whenever the MythTV core database schema changes.
*
@@ -185,6 +185,37 @@ bool RemoteFile::Open(void)
return true;
}
+bool RemoteFile::ReOpen(QString newFilename)
+{
+ lock.lock();
+ if (!sock)
+ {
+ LOG(VB_NETWORK, LOG_ERR, "RemoteFile::ReOpen(): Called with no socket");
+ return false;
+ }
+
+ if (!sock->isOpen() || sock->error())
+ return false;
+
+ if (!controlSock->isOpen() || controlSock->error())
+ return false;
+
+ QStringList strlist( QString(query).arg(recordernum) );
+ strlist << "REOPEN";
+ strlist << newFilename;
+
+ controlSock->writeStringList(strlist);
+ controlSock->readStringList(strlist);
+
+ lock.unlock();
+
+ bool retval = false;
+ if (!strlist.empty())
+ retval = strlist[0].toInt();
+
+ return retval;
+}
+
void RemoteFile::Close(void)
{
if (!controlSock)
@@ -22,6 +22,7 @@ class MBASE_PUBLIC RemoteFile
~RemoteFile();
bool Open();
+ bool ReOpen(QString newFilename);
void Close(void);
long long Seek(long long pos, int whence, long long curpos = -1);
@@ -71,6 +71,32 @@ ThreadedFileWriter::ThreadedFileWriter(const QString &fname,
filename.detach();
}
+/** \fn ThreadedFileWriter::ReOpen(QString)
+ * \brief Reopens the file we are writing to or opens a new file
+ * \return true if we successfully open the file.
+ *
+ * \param newFilename optional name of new file to open
+ */
+bool ThreadedFileWriter::ReOpen(QString newFilename)
+{
+ Flush();
+
+ buflock.lock();
+
+ if (fd >= 0)
+ {
+ close(fd);
+ fd = -1;
+ }
+
+ if (!newFilename.isEmpty())
+ filename = newFilename;
+
+ buflock.unlock();
+
+ return Open();
+}
+
/** \fn ThreadedFileWriter::Open(void)
* \brief Opens the file we will be writing to.
* \return true if we successfully open the file.
@@ -100,10 +126,17 @@ bool ThreadedFileWriter::Open(void)
#ifdef USING_MINGW
_setmode(fd, _O_BINARY);
#endif
- writeThread = new TFWWriteThread(this);
- writeThread->start();
- syncThread = new TFWSyncThread(this);
- syncThread->start();
+ if (!writeThread)
+ {
+ writeThread = new TFWWriteThread(this);
+ writeThread->start();
+ }
+
+ if (!syncThread)
+ {
+ syncThread = new TFWSyncThread(this);
+ syncThread->start();
+ }
return true;
}
@@ -388,6 +421,13 @@ void ThreadedFileWriter::DiskLoop(void)
continue;
}
+ if (fd == -1)
+ {
+ bufferHasData.wait(locker.mutex(), 200);
+ TrimEmptyBuffers();
+ continue;
+ }
+
TFWBuffer *buf = writeBuffers.front();
writeBuffers.pop_front();
totalBufferUse -= buf->data.size();
@@ -46,6 +46,7 @@ class ThreadedFileWriter
~ThreadedFileWriter();
bool Open(void);
+ bool ReOpen(QString newFilename = "");
long long Seek(long long pos, int whence);
uint Write(const void *data, uint count);
@@ -366,6 +366,35 @@ bool FileRingBuffer::OpenFile(const QString &lfilename, uint retry_ms)
return ok;
}
+bool FileRingBuffer::ReOpen(QString newFilename)
+{
+ if (!writemode)
+ {
+ LOG(VB_GENERAL, LOG_ERR, LOC + "Tried to ReOpen a read only file.");
+ return false;
+ }
+
+ bool result = false;
+
+ rwlock.lockForWrite();
+
+ if (tfw && tfw->ReOpen(newFilename))
+ result = true;
+ else if (remotefile && remotefile->ReOpen(newFilename))
+ result = true;
+
+ if (result)
+ {
+ filename = newFilename;
+ poslock.lockForWrite();
+ writepos = 0;
+ poslock.unlock();
+ }
+
+ rwlock.unlock();
+ return result;
+}
+
bool FileRingBuffer::IsOpen(void) const
{
rwlock.lockForRead();
@@ -14,6 +14,7 @@ class MTV_PUBLIC FileRingBuffer : public RingBuffer
// General Commands
virtual bool OpenFile(const QString &lfilename,
uint retry_ms = kDefaultOpenTimeout);
+ virtual bool ReOpen(QString newFilename = "");
virtual long long Seek(long long pos, int whence, bool has_lock);
protected:
@@ -108,6 +108,7 @@ class MTV_PUBLIC RingBuffer : protected MThread
*/
virtual bool OpenFile(const QString &lfilename,
uint retry_ms = kDefaultOpenTimeout) = 0;
+ virtual bool ReOpen(QString newFilename = "") { return false; }
int Read(void *buf, int count);
int Peek(void *buf, int count); // only works with readahead
@@ -78,6 +78,17 @@ bool FileTransfer::isOpen(void)
return false;
}
+bool FileTransfer::ReOpen(QString newFilename)
+{
+ if (!writemode)
+ return false;
+
+ if (rbuffer)
+ return rbuffer->ReOpen(newFilename);
+
+ return false;
+}
+
void FileTransfer::Stop(void)
{
if (readthreadlive)
@@ -29,6 +29,7 @@ class FileTransfer
MythSocket *getSocket() { return sock; }
bool isOpen(void);
+ bool ReOpen(QString newFilename = "");
void Stop(void);
@@ -5022,6 +5022,10 @@ void MainServer::HandleFileTransferQuery(QStringList &slist,
retlist << QString::number(isopen);
}
+ else if (command == "REOPEN")
+ {
+ retlist << QString::number(ft->ReOpen(slist[2]));
+ }
else if (command == "DONE")
{
ft->Stop();

0 comments on commit 1da9d23

Please sign in to comment.