1.3.27 with NPTL: (wapd) always crashes at shutdown
Commit Message
On Mon, 2005-06-20 at 15:47 +0200, Udo Richter wrote:
> Ville Skyttä wrote:
> > The culprit seems to be cWapServer::Action() in server.c, which I tried
> > to convert to use cCondWait::SleepMs() instead of usleep(), and added an
> > "active" boolean into the class that would control the while loop in
> > Action() and that would be set to false in the destructor, but those
> > changes did not help.
>
> (without taking any close look at the source code)
> I assume this is a main while loop in a cThread. Stopping a thread from
> within the destructor is quite risky, as the object is already partially
> destructed, and if you dont explicitly wait for the thread to finish,
> the object may be gone before the thread ends.
>
> The best way is to stop the thread before the object gets destroyed,
> using some thread.Stop(). The right place for stopping threads is in
> cPlugin::Stop().
Okay, I think I may have got it, thanks. The attached patch seems to
fix the crash here. Dunno if the usleep changes were actually necessary
but since I already had them available...
@@ -86,7 +86,7 @@
cWapServer::~cWapServer()
{
- Cancel(0);
+ Cancel(3);
free(buffer);
}
@@ -1169,11 +1169,21 @@
return false;
}
+void cWapServer::Shutdown(void)
+{
+ active = false;
+}
+
void cWapServer::Action(void)
{
- usleep(5000000); //initial delay
+ active = true;
+#if VDRVERSNUM >= 10313
+ cCondWait::SleepMs(5000);
+#else
+ usleep(5000000);
+#endif
dsyslog("WAPD: finished initial delay");
- while (1) {
+ while (active) {
if (file.Open(socket.Accept())) {
if (ProcessHeader()) {
if (*authorization == 0 || !WapAccess.Acceptable(authorization))
@@ -1217,7 +1227,11 @@
}
file.Close();
}
+#if VDRVERSNUM >= 10313
+ cCondWait::SleepMs(10);
+#else
usleep(10000);
+#endif
}
}
@@ -20,9 +20,12 @@
#define WMLBUFFER 3*MAXPARSEBUFFER
class cWapServer : cThread {
+ friend class cPluginWapd;
+
private:
enum eMethod { mUnknown, mGet, mPost };
+ bool active;
cWapSocket socket;
cFile file;
cRecordings Recordings;
@@ -68,6 +71,9 @@
void PageLanguage(void);
void PageMain(void);
+protected:
+ void Shutdown(void);
+
public:
cWapServer(int Port);
~cWapServer();
@@ -22,6 +22,8 @@
// Add any member variables or functions you may need here.
cWapServer *server;
int tcpport;
+protected:
+ virtual void Stop(void);
public:
cPluginWapd(void);
virtual ~cPluginWapd();
@@ -97,4 +99,10 @@
return false;
}
+void cPluginWapd::Stop(void)
+{
+ if (server)
+ server->Shutdown();
+}
+
VDRPLUGINCREATOR(cPluginWapd); // Don't touch this!