1.3.27 with NPTL: (wapd) always crashes at shutdown

Message ID 1119296496.28867.74.camel@bobcat.mine.nu
State New
Headers

Commit Message

Ville Skyttä June 20, 2005, 7:41 p.m. UTC
  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...
  

Patch

diff -ru wapd-0.7a.orig/server.c wapd-0.7a/server.c
--- wapd-0.7a.orig/server.c	2005-01-25 22:32:24.000000000 +0200
+++ wapd-0.7a/server.c	2005-06-20 21:50:45.000000000 +0300
@@ -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
      }
 }
 
diff -ru wapd-0.7a.orig/server.h wapd-0.7a/server.h
--- wapd-0.7a.orig/server.h	2005-01-24 18:13:35.000000000 +0200
+++ wapd-0.7a/server.h	2005-06-20 21:53:51.000000000 +0300
@@ -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();
diff -ru wapd-0.7a.orig/wapd.c wapd-0.7a/wapd.c
--- wapd-0.7a.orig/wapd.c	2005-01-25 22:26:04.000000000 +0200
+++ wapd-0.7a/wapd.c	2005-06-20 21:53:06.000000000 +0300
@@ -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!