[mythtv] [PATCH] deadlock when opening video input
Kevin Hjelden
mythtv at burntpopcorn.net
Fri Jan 16 02:37:11 EST 2004
This patch is to fix a deadlock when the video source is attempted to
open and fails. tv_rec.cpp opens a thread to open the video source for
recording, and then goes into an infinite loop waiting until the thread
signals that the source is open. However, if the source fails to open,
it simply returns (and doesn't retry) out of the thread causing the loop
never to fail. This patch fixes that by having an error status in
NuppelVideoRecoder that allows the function in tv_rec.cpp to abort if an
error is thrown.
I'm not the best linux coder, so hopefully this doesn't cause too many
problems. I've had it successfully running on my myth box for a month or
so with no noticable problems.
Kevin
-------------- next part --------------
? mythtv/programs/mythfrontend/moc_rankchannels.cpp
? mythtv/programs/mythfrontend/moc_rankprograms.cpp
Index: mythtv/libs/libmythtv/NuppelVideoRecorder.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/NuppelVideoRecorder.cpp,v
retrieving revision 1.152
diff -u -r1.152 NuppelVideoRecorder.cpp
--- mythtv/libs/libmythtv/NuppelVideoRecorder.cpp 7 Jan 2004 06:14:04 -0000 1.152
+++ mythtv/libs/libmythtv/NuppelVideoRecorder.cpp 16 Jan 2004 07:13:03 -0000
@@ -91,6 +91,7 @@
childrenLive = false;
recording = false;
+ errored = false;
paused = false;
pausewritethread = false;
@@ -392,6 +393,11 @@
return recording;
}
+bool NuppelVideoRecorder::IsErrored(void)
+{
+ return errored;
+}
+
long long NuppelVideoRecorder::GetFramesWritten(void)
{
return framesWritten;
@@ -791,6 +797,7 @@
if (lzo_init() != LZO_E_OK)
{
cerr << "lzo_init() failed, exiting\n";
+ errored = true;
return;
}
@@ -815,18 +822,21 @@
{
cerr << "Cannot open '" << ringBuffer->GetFilename() << "' for "
<< "writing, exiting\n";
+ errored = true;
return;
}
if (childrenLive)
{
cerr << "Error: children are already alive\n";
+ errored = true;
return;
}
if (SpawnChildren() < 0)
{
cerr << "Couldn't spawn children\n";
+ errored = true;
return;
}
@@ -848,13 +858,20 @@
if (getuid() == 0)
nice(-10);
+ int retries = 0;
fd = open(videodevice.ascii(), O_RDWR);
- if (fd <= 0)
+ while (fd <= 0)
{
- cerr << "Can't open video device: " << videodevice << endl;
- perror("open video:");
- KillChildren();
- return;
+ usleep(30000);
+ fd = open(videodevice.ascii(), O_RDWR);
+ if (retries++ > 5)
+ {
+ cerr << "Can't open video device: " << videodevice << endl;
+ perror("open video:");
+ KillChildren();
+ errored = true;
+ return;
+ }
}
usingv4l2 = true;
Index: mythtv/libs/libmythtv/NuppelVideoRecorder.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/NuppelVideoRecorder.h,v
retrieving revision 1.66
diff -u -r1.66 NuppelVideoRecorder.h
--- mythtv/libs/libmythtv/NuppelVideoRecorder.h 7 Jan 2004 06:14:04 -0000 1.66
+++ mythtv/libs/libmythtv/NuppelVideoRecorder.h 16 Jan 2004 07:13:03 -0000
@@ -64,6 +64,7 @@
void WaitForPause(void);
bool IsRecording(void);
+ bool IsErrored(void);
long long GetFramesWritten(void);
@@ -193,6 +194,7 @@
pthread_t vbi_tid;
bool recording;
+ bool errored;
int keyframedist;
vector<struct seektable_entry> *seektable;
Index: mythtv/libs/libmythtv/hdtvrecorder.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/hdtvrecorder.h,v
retrieving revision 1.15
diff -u -r1.15 hdtvrecorder.h
--- mythtv/libs/libmythtv/hdtvrecorder.h 7 Jan 2004 06:14:04 -0000 1.15
+++ mythtv/libs/libmythtv/hdtvrecorder.h 16 Jan 2004 07:13:03 -0000
@@ -32,6 +32,7 @@
bool GetPause(void);
void WaitForPause(void);
bool IsRecording(void);
+ bool IsErrored(void) { return false; }
long long GetFramesWritten(void);
Index: mythtv/libs/libmythtv/mpegrecorder.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/mpegrecorder.h,v
retrieving revision 1.10
diff -u -r1.10 mpegrecorder.h
--- mythtv/libs/libmythtv/mpegrecorder.h 7 Jan 2004 06:14:04 -0000 1.10
+++ mythtv/libs/libmythtv/mpegrecorder.h 16 Jan 2004 07:13:03 -0000
@@ -31,6 +31,7 @@
bool GetPause(void);
void WaitForPause(void);
bool IsRecording(void);
+ bool IsErrored(void) { return false; }
long long GetFramesWritten(void);
Index: mythtv/libs/libmythtv/recorderbase.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/recorderbase.h,v
retrieving revision 1.9
diff -u -r1.9 recorderbase.h
--- mythtv/libs/libmythtv/recorderbase.h 7 Jan 2004 06:14:04 -0000 1.9
+++ mythtv/libs/libmythtv/recorderbase.h 16 Jan 2004 07:13:03 -0000
@@ -45,6 +45,7 @@
virtual void WaitForPause(void) = 0;
virtual bool IsRecording(void) = 0;
+ virtual bool IsErrored(void) = 0;
virtual long long GetFramesWritten(void) = 0;
Index: mythtv/libs/libmythtv/tv_rec.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/tv_rec.cpp,v
retrieving revision 1.126
diff -u -r1.126 tv_rec.cpp
--- mythtv/libs/libmythtv/tv_rec.cpp 9 Jan 2004 21:02:13 -0000 1.126
+++ mythtv/libs/libmythtv/tv_rec.cpp 16 Jan 2004 07:13:04 -0000
@@ -485,13 +487,25 @@
SetVideoFiltersForChannel(channel, channel->GetCurrentName());
pthread_create(&encode, NULL, SpawnEncode, nvr);
- while (!nvr->IsRecording())
+ while (!nvr->IsRecording() && !nvr->IsErrored()) // (20 seconds @ usleep(50))
usleep(50);
// evil.
- channel->SetFd(nvr->GetVideoFd());
+ if (nvr->IsRecording())
+ {
+ channel->SetFd(nvr->GetVideoFd());
+ SetVideoFiltersForChannel(channel, channel->GetCurrentName());
- frameRate = nvr->GetFrameRate();
+ frameRate = nvr->GetFrameRate();
+ }
+ else
+ {
+ FinishedRecording();
+ killRecordingFile = true;
+ closeRecorder = true;
+ tmpInternalState = kState_None;
+ }
}
if (closeRecorder)
More information about the mythtv-dev
mailing list