mirror of
				https://github.com/vdr-projects/vdr.git
				synced 2025-03-01 10:50:46 +00:00 
			
		
		
		
	Implemented message queueing
This commit is contained in:
		
							
								
								
									
										7
									
								
								HISTORY
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								HISTORY
									
									
									
									
									
								
							| @@ -3934,7 +3934,7 @@ Video Disk Recorder Revision History | ||||
|   layers of subdirectories. | ||||
| - Removed EPG bugfix #0, because it removed actually important data. | ||||
|  | ||||
| 2005-11-26: Version 1.3.37 | ||||
| 2005-11-27: Version 1.3.37 | ||||
|  | ||||
| - Added compiler options "-fPIC -g" to all plugins (thanks to Rolf Ahrenberg). | ||||
| - Fixed initializing the day index when editing the weekday parameter of a | ||||
| @@ -3957,3 +3957,8 @@ Video Disk Recorder Revision History | ||||
|   by Stefan Huelswitt). | ||||
| - Added a copy constructor to cString and fixed its assignment operator | ||||
|   (thanks to Holger Brunn). | ||||
| - The new function Skins.QueueMessage() can be called from a background thread | ||||
|   to queue a message for display. See VDR/skins.h for details. | ||||
| - The SVDRP command MESG uses the new message queueing facility, so MESG | ||||
|   commands may now be executed at any time, and the message will be displayed | ||||
|   (no more "pending message"). | ||||
|   | ||||
							
								
								
									
										46
									
								
								PLUGINS.html
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								PLUGINS.html
									
									
									
									
									
								
							| @@ -14,18 +14,18 @@ Copyright © 2005 Klaus Schmidinger<br> | ||||
| <a href="http://www.cadsoft.de/vdr">www.cadsoft.de/vdr</a> | ||||
| </center> | ||||
| <p> | ||||
| <!--X1.3.20--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> | ||||
| Important modifications introduced in version 1.3.20 are marked like this. | ||||
| <!--X1.3.20--></td></tr></table> | ||||
| <!--X1.3.21--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%> | ||||
| <!--X1.3.21--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> | ||||
| Important modifications introduced in version 1.3.21 are marked like this. | ||||
| <!--X1.3.21--></td></tr></table> | ||||
| <!--X1.3.30--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> | ||||
| <!--X1.3.30--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%> | ||||
| Important modifications introduced in version 1.3.30 are marked like this. | ||||
| <!--X1.3.30--></td></tr></table> | ||||
| <!--X1.3.31--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> | ||||
| <!--X1.3.31--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> | ||||
| Important modifications introduced in version 1.3.31 are marked like this. | ||||
| <!--X1.3.31--></td></tr></table> | ||||
| <!--X1.3.37--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> | ||||
| Important modifications introduced in version 1.3.37 are marked like this. | ||||
| <!--X1.3.37--></td></tr></table> | ||||
| <p> | ||||
| VDR provides an easy to use plugin interface that allows additional functionality | ||||
| to be added to the program by implementing a dynamically loadable library file. | ||||
| @@ -58,9 +58,7 @@ structures and allows it to hook itself into specific areas to perform special a | ||||
| <li><a href="#Command line arguments">Command line arguments</a> | ||||
| <li><a href="#Command line help">Command line help</a> | ||||
| <li><a href="#Getting started">Getting started</a> | ||||
| <!--X1.3.20--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> | ||||
| <li><a href="#Shutting down">Shutting down</a> | ||||
| <!--X1.3.20--></td></tr></table> | ||||
| <li><a href="#Main menu entry">Main menu entry</a> | ||||
| <li><a href="#User interaction">User interaction</a> | ||||
| <li><a href="#Housekeeping">Housekeeping</a> | ||||
| @@ -68,10 +66,10 @@ structures and allows it to hook itself into specific areas to perform special a | ||||
| <li><a href="#The Setup menu">The Setup menu</a> | ||||
| <li><a href="#Configuration files">Configuration files</a> | ||||
| <li><a href="#Internationalization">Internationalization</a> | ||||
| <!--X1.3.30--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> | ||||
| <!--X1.3.30--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%> | ||||
| <li><a href="#Custom services">Custom services</a> | ||||
| <!--X1.3.30--></td></tr></table> | ||||
| <!--X1.3.31--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> | ||||
| <!--X1.3.31--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> | ||||
| <li><a href="#SVDRP commands">SVDRP commands</a> | ||||
| <!--X1.3.31--></td></tr></table> | ||||
| <li><a href="#Loading plugins into VDR">Loading plugins into VDR</a> | ||||
| @@ -87,7 +85,7 @@ structures and allows it to hook itself into specific areas to perform special a | ||||
| <li><a href="#Skins">Skins</a> | ||||
| <li><a href="#Themes">Themes</a> | ||||
| <li><a href="#Devices">Devices</a> | ||||
| <!--X1.3.21--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%> | ||||
| <!--X1.3.21--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> | ||||
| <li><a href="#Audio">Audio</a> | ||||
| <!--X1.3.21--></td></tr></table> | ||||
| <li><a href="#Remote Control">Remote Control</a> | ||||
| @@ -314,10 +312,8 @@ since VDR, for instance, has to create the plugin objects in order to get their | ||||
| command line help - and after that immediately destroys them again. | ||||
| <p> | ||||
| The <b>destructor</b> has to clean up any data created by the plugin. | ||||
| <!--X1.3.20--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> | ||||
| Any threads the plugin may have created shall be stopped in the | ||||
| <a href="#Shutting down"><tt>Stop()</tt></a> function. | ||||
| <!--X1.3.20--></td></tr></table> | ||||
| <p> | ||||
| Of course, if your plugin doesn't define any member variables that need to be | ||||
| initialized (and deleted), you don't need to implement either of these functions. | ||||
| @@ -512,7 +508,6 @@ VDR to exit. | ||||
| If the plugin doesn't implement any background functionality or internationalized | ||||
| texts, it doesn't need to implement either of these functions. | ||||
|  | ||||
| <!--X1.3.20--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> | ||||
| <a name="Shutting down"><hr><h2>Shutting down</h2> | ||||
|  | ||||
| <center><i><b>Stop it, right there!</b></i></center><p> | ||||
| @@ -529,7 +524,6 @@ The <tt>Stop()</tt> function will only be called if a previous call to the | ||||
| <a href="#Getting started"><tt>Start()</tt></a> function of that plugin has | ||||
| returned <i>true</i>. The <tt>Stop()</tt> functions are called in the reverse order | ||||
| as the <a href="#Getting started"><tt>Start()</tt></a> functions were called. | ||||
| <!--X1.3.20--></td></tr></table> | ||||
|  | ||||
| <a name="Main menu entry"><hr><h2>Main menu entry</h2> | ||||
|  | ||||
| @@ -872,7 +866,7 @@ Texts are first searched for in the <i>Phrases</i> registered for this plugin (i | ||||
| and then in the global VDR texts. So a plugin can make use of texts defined by the | ||||
| core VDR code. | ||||
|  | ||||
| <!--X1.3.30--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> | ||||
| <!--X1.3.30--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%> | ||||
| <a name="Custom services"><hr><h2>Custom services</h2> | ||||
|  | ||||
| <center><i><b>What can I do for you?</b></i></center><p> | ||||
| @@ -943,7 +937,7 @@ any plugin handled the request, or <tt>false</tt> if no plugin handled the reque | ||||
|  | ||||
| <!--X1.3.30--></td></tr></table> | ||||
|  | ||||
| <!--X1.3.31--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> | ||||
| <!--X1.3.31--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%> | ||||
| <a name="SVDRP commands"><hr><h2>SVDRP commands</h2> | ||||
|  | ||||
| <center><i><b>Infinite Diversity in Infinite Combinations</b></i></center><p> | ||||
| @@ -1521,6 +1515,22 @@ with the full required resolution. Only if this fails shall it use alternate | ||||
| areas. Drawing areas are always rectangular and may not overlap (but do not need | ||||
| to be adjacent). | ||||
|  | ||||
| <!--X1.3.37--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%> | ||||
| <p> | ||||
| Directly accessing the OSD is only allowed from the foreground thread, which | ||||
| restricts this to a <tt>cOsdObject</tt> returned from the plugin's <tt>MainMenuAction()</tt> | ||||
| function, or any of the skin classes a plugin might implement. | ||||
| <p> | ||||
| If a plugin runs a separate thread and wants to issue a message directly from | ||||
| within that tread, it can call | ||||
|  | ||||
| <p><table><tr><td bgcolor=#F0F0F0><pre> | ||||
| int cSkins::QueueMessage(eMessageType Type, const char *s, int Seconds = 0, int Timeout = 0); | ||||
| </pre></td></tr></table><p> | ||||
|  | ||||
| to queue that message for display. See <tt>VDR/skins.h</tt> for details. | ||||
| <!--X1.3.37--></td></tr></table> | ||||
|  | ||||
| <a name="Skins"><hr><h2>Skins</h2> | ||||
|  | ||||
| <center><i><b>The emperor's new clothes</b></i></center><p> | ||||
| @@ -1830,7 +1840,7 @@ private: | ||||
|   virtual void Action(void); | ||||
| public: | ||||
|   cMyAudio(void); | ||||
| <!--X1.3.21--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%> | ||||
| <!--X1.3.21--><table width=100%><tr><td bgcolor=#0000AA> </td><td width=100%> | ||||
|   virtual void Play(const uchar *Data, int Length, uchar Id); | ||||
| <!--X1.3.21--></td></tr></table> | ||||
|   virtual void Mute(bool On); | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: interface.c 1.69 2005/09/03 09:07:23 kls Exp $ | ||||
|  * $Id: interface.c 1.70 2005/11/27 15:31:06 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "interface.h" | ||||
| @@ -36,13 +36,6 @@ eKeys cInterface::GetKey(bool Wait) | ||||
|   if (SVDRP) { | ||||
|      if (SVDRP->Process()) | ||||
|         Wait = false; | ||||
|      if (!Skins.IsOpen()) { | ||||
|         char *message = SVDRP->GetMessage(); | ||||
|         if (message) { | ||||
|            Skins.Message(mtInfo, message); | ||||
|            free(message); | ||||
|            } | ||||
|         } | ||||
|      } | ||||
|   return cRemote::Get(Wait ? 1000 : 10); | ||||
| } | ||||
|   | ||||
							
								
								
									
										129
									
								
								skins.c
									
									
									
									
									
								
							
							
						
						
									
										129
									
								
								skins.c
									
									
									
									
									
								
							| @@ -4,13 +4,49 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: skins.c 1.5 2005/10/02 10:12:10 kls Exp $ | ||||
|  * $Id: skins.c 1.6 2005/11/27 15:52:25 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "skins.h" | ||||
| #include "interface.h" | ||||
| #include "status.h" | ||||
| #include "tools.h" | ||||
|  | ||||
| // --- cSkinQueuedMessage ---------------------------------------------------- | ||||
|  | ||||
| class cSkinQueuedMessage : public cListObject { | ||||
|   friend class cSkins; | ||||
| private: | ||||
|   eMessageType type; | ||||
|   char *message; | ||||
|   int seconds; | ||||
|   int timeout; | ||||
|   tThreadId threadId; | ||||
|   eKeys key; | ||||
|   int state; | ||||
|   cMutex mutex; | ||||
|   cCondVar condVar; | ||||
| public: | ||||
|   cSkinQueuedMessage(eMessageType Type, const char *s, int Seconds, int Timeout); | ||||
|   virtual ~cSkinQueuedMessage(); | ||||
|   }; | ||||
|  | ||||
| cSkinQueuedMessage::cSkinQueuedMessage(eMessageType Type, const char *s, int Seconds, int Timeout) | ||||
| { | ||||
|   type = Type; | ||||
|   message = s ? strdup(s) : NULL; | ||||
|   seconds = Seconds; | ||||
|   timeout = Timeout; | ||||
|   threadId = cThread::ThreadId(); | ||||
|   key = kNone; | ||||
|   state = 0; // waiting | ||||
| } | ||||
|  | ||||
| cSkinQueuedMessage::~cSkinQueuedMessage() | ||||
| { | ||||
|   free(message); | ||||
| } | ||||
|  | ||||
| cList<cSkinQueuedMessage> SkinQueuedMessages; | ||||
|  | ||||
| // --- cSkinDisplay ---------------------------------------------------------- | ||||
|  | ||||
| @@ -202,6 +238,95 @@ eKeys cSkins::Message(eMessageType Type, const char *s, int Seconds) | ||||
|   return k; | ||||
| } | ||||
|  | ||||
| int cSkins::QueueMessage(eMessageType Type, const char *s, int Seconds, int Timeout) | ||||
| { | ||||
|   if (Type == mtStatus) { | ||||
|      dsyslog("cSkins::QueueMessage() called with mtStatus - ignored!"); | ||||
|      return kNone; | ||||
|      } | ||||
|   if (isempty(s)) { | ||||
|      dsyslog("cSkins::QueueMessage() called with empty message - ignored!"); | ||||
|      return kNone; | ||||
|      } | ||||
|   int k = kNone; | ||||
|   if (Timeout > 0) { | ||||
|      if (cThread::IsMainThread()) { | ||||
|         dsyslog("cSkins::QueueMessage() called from main thread with Timeout = %d - ignored!", Timeout); | ||||
|         return k; | ||||
|         } | ||||
|      cSkinQueuedMessage *m = new cSkinQueuedMessage(Type, s, Seconds, Timeout); | ||||
|      queueMessageMutex.Lock(); | ||||
|      SkinQueuedMessages.Add(m); | ||||
|      m->mutex.Lock(); | ||||
|      queueMessageMutex.Unlock(); | ||||
|      if (m->condVar.TimedWait(m->mutex, Timeout * 1000)) | ||||
|         k = m->key; | ||||
|      else | ||||
|         k = -1; // timeout, nothing has been displayed | ||||
|      m->state = 2; // done | ||||
|      m->mutex.Unlock(); | ||||
|      } | ||||
|   else { | ||||
|      queueMessageMutex.Lock(); | ||||
|      // Check if there is a waiting message w/o timeout for this thread: | ||||
|      if (Timeout == -1) { | ||||
|         for (cSkinQueuedMessage *m = SkinQueuedMessages.Last(); m; m = SkinQueuedMessages.Prev(m)) { | ||||
|             if (m->threadId == cThread::ThreadId()) { | ||||
|                if (m->state == 0 && m->timeout == -1) | ||||
|                   m->state = 2; // done | ||||
|                break; | ||||
|                } | ||||
|             } | ||||
|          } | ||||
|      // Add the new message: | ||||
|      SkinQueuedMessages.Add(new cSkinQueuedMessage(Type, s, Seconds, Timeout)); | ||||
|      queueMessageMutex.Unlock(); | ||||
|      } | ||||
|   return k; | ||||
| } | ||||
|  | ||||
| void cSkins::ProcessQueuedMessages(void) | ||||
| { | ||||
|   if (!cThread::IsMainThread()) { | ||||
|      dsyslog("cSkins::ProcessQueuedMessages() called from background thread - ignored!"); | ||||
|      return; | ||||
|      } | ||||
|   cSkinQueuedMessage *msg = NULL; | ||||
|   // Get the first waiting message: | ||||
|   queueMessageMutex.Lock(); | ||||
|   for (cSkinQueuedMessage *m = SkinQueuedMessages.First(); m; m = SkinQueuedMessages.Next(m)) { | ||||
|       if (m->state == 0) { // waiting | ||||
|          m->state = 1; // active | ||||
|          msg = m; | ||||
|          break; | ||||
|          } | ||||
|       } | ||||
|   queueMessageMutex.Unlock(); | ||||
|   // Display the message: | ||||
|   if (msg) { | ||||
|      msg->mutex.Lock(); | ||||
|      if (msg->state == 1) { // might have changed since we got it | ||||
|         msg->key = Skins.Message(msg->type, msg->message, msg->seconds); | ||||
|         if (msg->timeout == 0) | ||||
|            msg->state = 2; // done | ||||
|         else | ||||
|            msg->condVar.Broadcast(); | ||||
|         } | ||||
|      msg->mutex.Unlock(); | ||||
|      } | ||||
|   // Remove done messages from the queue: | ||||
|   queueMessageMutex.Lock(); | ||||
|   for (;;) { | ||||
|       cSkinQueuedMessage *m = SkinQueuedMessages.First(); | ||||
|       if (m && m->state == 2) { // done | ||||
|          SkinQueuedMessages.Del(m); | ||||
|          } | ||||
|       else | ||||
|          break; | ||||
|       }  | ||||
|   queueMessageMutex.Unlock(); | ||||
| } | ||||
|  | ||||
| void cSkins::Flush(void) | ||||
| { | ||||
|   if (cSkinDisplay::Current()) | ||||
|   | ||||
							
								
								
									
										33
									
								
								skins.h
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								skins.h
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: skins.h 1.8 2005/05/15 14:41:41 kls Exp $ | ||||
|  * $Id: skins.h 1.9 2005/11/27 15:41:44 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #ifndef __SKINS_H | ||||
| @@ -16,6 +16,7 @@ | ||||
| #include "osd.h" | ||||
| #include "recording.h" | ||||
| #include "themes.h" | ||||
| #include "thread.h" | ||||
| #include "tools.h" | ||||
|  | ||||
| enum eMessageType { mtStatus = 0, mtInfo, mtWarning, mtError }; // will be used to calculate color offsets! | ||||
| @@ -298,6 +299,7 @@ class cSkins : public cList<cSkin> { | ||||
| private: | ||||
|   cSkin *current; | ||||
|   cSkinDisplayMessage *displayMessage; | ||||
|   cMutex queueMessageMutex; | ||||
| public: | ||||
|   cSkins(void); | ||||
|   ~cSkins(); | ||||
| @@ -312,6 +314,35 @@ public: | ||||
|        ///< Displays the given message, either through a currently visible | ||||
|        ///< display object that is capable of doing so, or by creating a | ||||
|        ///< temporary cSkinDisplayMessage object. | ||||
|        ///< The return value is the key pressed by the user. If no user input | ||||
|        ///< has been received within Seconds (the default value of 0 results | ||||
|        ///< in the ///< value defined for "Message time" in the setup), kNone | ||||
|        ///< will be returned. | ||||
|   int QueueMessage(eMessageType Type, const char *s, int Seconds = 0, int Timeout = 0); | ||||
|        ///< Like Message(), but this function may be called from a background | ||||
|        ///< thread. The given message is put into a queue and the main program | ||||
|        ///< loop will display it as soon as this is suitable. If Timeout is 0, | ||||
|        ///< QueueMessage() returns immediately and the return value will be kNone. | ||||
|        ///< If a positive Timeout is given, the thread will wait at most the given | ||||
|        ///< number of seconds for the message to be actually displayed (note that | ||||
|        ///< the user may currently be doing something that doesn't allow for | ||||
|        ///< queued messages to be displayed immediately). If the timeout expires | ||||
|        ///< and the message hasn't been displayed yet, the return value is -1 | ||||
|        ///< and the message will be removed from the queue without being displayed. | ||||
|        ///< Positive values of Timeout are only allowed for background threads. | ||||
|        ///< If QueueMessage() is called from the foreground thread with a Timeout | ||||
|        ///< greater than 0, the call is ignored and nothing is displayed. | ||||
|        ///< Queued messages will be displayed in the sequence they have been | ||||
|        ///< put into the queue, so messages from different threads may appear | ||||
|        ///< mingled. If a particular thread queues a message with a Timeout of | ||||
|        ///< -1, and the previous message from the same thread also had a Timeout | ||||
|        ///< of -1, only the last message will be displayed. This can be used for | ||||
|        ///< progress displays, where only the most recent message is actually | ||||
|        ///< important. | ||||
|        ///< Type may only be mtInfo, mtWarning or mtError. A call with mtStatus | ||||
|        ///< will be ignored, as will be one with an empty message. | ||||
|   void ProcessQueuedMessages(void); | ||||
|        ///< Processes the first queued message, if any. | ||||
|   void Flush(void); | ||||
|        ///< Flushes the currently active cSkinDisplay, if any. | ||||
|   }; | ||||
|   | ||||
							
								
								
									
										32
									
								
								svdrp.c
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								svdrp.c
									
									
									
									
									
								
							| @@ -10,7 +10,7 @@ | ||||
|  * and interact with the Video Disk Recorder - or write a full featured | ||||
|  * graphical interface that sits on top of an SVDRP connection. | ||||
|  * | ||||
|  * $Id: svdrp.c 1.83 2005/11/05 11:21:38 kls Exp $ | ||||
|  * $Id: svdrp.c 1.84 2005/11/27 15:29:28 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "svdrp.h" | ||||
| @@ -35,6 +35,7 @@ | ||||
| #include "menu.h" | ||||
| #include "plugin.h" | ||||
| #include "remote.h" | ||||
| #include "skins.h" | ||||
| #include "timers.h" | ||||
| #include "tools.h" | ||||
| #include "videodir.h" | ||||
| @@ -225,12 +226,9 @@ const char *HelpPages[] = { | ||||
|   "LSTT [ <number> ]\n" | ||||
|   "    List timers. Without option, all timers are listed. Otherwise\n" | ||||
|   "    only the given timer is listed.", | ||||
|   "MESG [ <message> ]\n" | ||||
|   "    Displays the given message on the OSD. If message is omitted, the\n" | ||||
|   "    currently pending message (if any) will be returned. The message\n" | ||||
|   "    will be displayed for a few seconds as soon as the OSD has become\n" | ||||
|   "    idle. If a new MESG command is entered while the previous message\n" | ||||
|   "    has not yet been displayed, the old message will be overwritten.", | ||||
|   "MESG <message>\n" | ||||
|   "    Displays the given message on the OSD. The message will be queued\n" | ||||
|   "    and displayed whenever this is suitable.\n", | ||||
|   "MODC <number> <settings>\n" | ||||
|   "    Modify a channel. Settings must be in the same format as returned\n" | ||||
|   "    by the LSTC command.", | ||||
| @@ -363,7 +361,6 @@ cSVDRP::cSVDRP(int Port) | ||||
|   numChars = 0; | ||||
|   length = BUFSIZ; | ||||
|   cmdLine = MALLOC(char, length); | ||||
|   message = NULL; | ||||
|   lastActivity = 0; | ||||
|   isyslog("SVDRP listening on port %d", Port); | ||||
| } | ||||
| @@ -371,7 +368,6 @@ cSVDRP::cSVDRP(int Port) | ||||
| cSVDRP::~cSVDRP() | ||||
| { | ||||
|   Close(); | ||||
|   free(message); | ||||
|   free(cmdLine); | ||||
| } | ||||
|  | ||||
| @@ -954,15 +950,12 @@ void cSVDRP::CmdLSTT(const char *Option) | ||||
| void cSVDRP::CmdMESG(const char *Option) | ||||
| { | ||||
|   if (*Option) { | ||||
|      free(message); | ||||
|      message = strdup(Option); | ||||
|      isyslog("SVDRP message: '%s'", message); | ||||
|      Reply(250, "Message stored"); | ||||
|      isyslog("SVDRP message: '%s'", Option); | ||||
|      Skins.QueueMessage(mtInfo, Option); | ||||
|      Reply(250, "Message queued"); | ||||
|      } | ||||
|   else if (message) | ||||
|      Reply(250, "%s", message); | ||||
|   else | ||||
|      Reply(550, "No pending message"); | ||||
|      Reply(501, "Missing message"); | ||||
| } | ||||
|  | ||||
| void cSVDRP::CmdMODC(const char *Option) | ||||
| @@ -1489,11 +1482,4 @@ bool cSVDRP::Process(void) | ||||
|   return false; | ||||
| } | ||||
|  | ||||
| char *cSVDRP::GetMessage(void) | ||||
| { | ||||
|   char *s = message; | ||||
|   message = NULL; | ||||
|   return s; | ||||
| } | ||||
|  | ||||
| //TODO more than one connection??? | ||||
|   | ||||
							
								
								
									
										4
									
								
								svdrp.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								svdrp.h
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: svdrp.h 1.25 2005/11/05 10:54:22 kls Exp $ | ||||
|  * $Id: svdrp.h 1.26 2005/11/27 15:26:42 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #ifndef __SVDRP_H | ||||
| @@ -48,7 +48,6 @@ private: | ||||
|   int numChars; | ||||
|   int length; | ||||
|   char *cmdLine; | ||||
|   char *message; | ||||
|   time_t lastActivity; | ||||
|   void Close(bool Timeout = false); | ||||
|   bool Send(const char *s, int length = -1); | ||||
| @@ -88,7 +87,6 @@ public: | ||||
|   ~cSVDRP(); | ||||
|   bool HasConnection(void) { return file.IsOpen(); } | ||||
|   bool Process(void); | ||||
|   char *GetMessage(void); | ||||
|   }; | ||||
|  | ||||
| #endif //__SVDRP_H | ||||
|   | ||||
							
								
								
									
										3
									
								
								thread.c
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								thread.c
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: thread.c 1.45 2005/08/14 11:15:42 kls Exp $ | ||||
|  * $Id: thread.c 1.46 2005/11/27 15:15:53 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include "thread.h" | ||||
| @@ -193,6 +193,7 @@ void cMutex::Unlock(void) | ||||
|  | ||||
| // --- cThread --------------------------------------------------------------- | ||||
|  | ||||
| tThreadId cThread::mainThreadId = cThread::ThreadId(); | ||||
| bool cThread::emergencyExitRequested = false; | ||||
|  | ||||
| cThread::cThread(const char *Description) | ||||
|   | ||||
							
								
								
									
										7
									
								
								thread.h
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								thread.h
									
									
									
									
									
								
							| @@ -4,7 +4,7 @@ | ||||
|  * See the main source file 'vdr.c' for copyright information and | ||||
|  * how to reach the author. | ||||
|  * | ||||
|  * $Id: thread.h 1.31 2005/10/09 11:12:32 kls Exp $ | ||||
|  * $Id: thread.h 1.32 2005/11/27 15:16:50 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #ifndef __THREAD_H | ||||
| @@ -72,6 +72,8 @@ public: | ||||
|   void Unlock(void); | ||||
|   }; | ||||
|  | ||||
| typedef pthread_t tThreadId; | ||||
|  | ||||
| class cThread { | ||||
|   friend class cThreadLock; | ||||
| private: | ||||
| @@ -80,6 +82,7 @@ private: | ||||
|   pthread_t childTid; | ||||
|   cMutex mutex; | ||||
|   char *description; | ||||
|   static tThreadId mainThreadId; | ||||
|   static bool emergencyExitRequested; | ||||
|   static void *StartThread(cThread *Thread); | ||||
| protected: | ||||
| @@ -112,6 +115,8 @@ public: | ||||
|   bool Active(void); | ||||
|        ///< Checks whether the thread is still alive. | ||||
|   static bool EmergencyExit(bool Request = false); | ||||
|   static tThreadId ThreadId(void) { return pthread_self(); } | ||||
|   static tThreadId IsMainThread(void) { return ThreadId() == mainThreadId; } | ||||
|   }; | ||||
|  | ||||
| // cMutexLock can be used to easily set a lock on mutex and make absolutely | ||||
|   | ||||
							
								
								
									
										5
									
								
								vdr.c
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								vdr.c
									
									
									
									
									
								
							| @@ -22,7 +22,7 @@ | ||||
|  * | ||||
|  * The project's page is at http://www.cadsoft.de/vdr | ||||
|  * | ||||
|  * $Id: vdr.c 1.219 2005/11/04 13:48:39 kls Exp $ | ||||
|  * $Id: vdr.c 1.220 2005/11/27 15:56:18 kls Exp $ | ||||
|  */ | ||||
|  | ||||
| #include <getopt.h> | ||||
| @@ -677,6 +677,9 @@ int main(int argc, char *argv[]) | ||||
|            else if (!LastCamMenu) | ||||
|               LastCamMenu = time(NULL); | ||||
|            } | ||||
|         // Queued messages: | ||||
|         if (!Skins.IsOpen()) | ||||
|            Skins.ProcessQueuedMessages(); | ||||
|         // User Input: | ||||
|         cOsdObject *Interact = Menu ? Menu : cControl::Control(); | ||||
|         eKeys key = Interface->GetKey((!Interact || !Interact->NeedsFastResponse()) && time(NULL) - LastCamMenu > LASTCAMMENUTIMEOUT); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user