[vdr] calling MainMenuAction() from an other plugin

Reinhard Nissl rnissl at gmx.de
Mon Apr 17 16:28:15 CEST 2006


Hi,

Klaus Schmidinger wrote:

>> In my case, I don't show an OSD. I just use this functionality as a 
>> trampoline to have the VDR main thread execute my code for switching 
>> the primary device, as it doesn't work reliably when it is done in any 
>> other thread.
>>
>> So you are right, when a plugin opens an OSD (which is the typical 
>> case), one will only see the OSD of the last plugin. On the other 
>> hand, it would be useful to know for the caller, that the 
>> MenuMenuAction of the specified plugin will be called when 
>> CallPlugin() returned true. Otherwise it would need more "intelligent" 
>> code at the caller to achieve the call under race conditions.
>>
>> In the case where the above is of no interest, there is no need to 
>> have an additional mutex lock in CallPlugin(), as Put() has one in 
>> remote.c:79.
> 
> I'm not particularly fond of that FIFO of yours.
> However, I do realize that it is useful to tell the caller of
> cRemote::CallPlugin() whether the call was successful.
> The attached patch vdr-1.3.46-callplugin.diff makes cRemote::CallPlugin()
> return false if there is currently a plugin call pending.

The code looks good to me. Am I right that CallPlugin() shall now only 
be used to open the plugins main menu, i. e. no longer any other 
processing in the context of the main thread?

> The ability to "catch the main thread" will be implemented by the
> second attached patch (vdr-1.3.46-mainthreadhook.diff), so that no
> "dirty tricks" should be necessary. This patch may have its line
> numbers a little off, because I have already made other changes
> to these files, but I wanted to give you a chance to look at this
> and maybe comment on it before I release version 1.3.47 later today.

I assume that this new interface function should be used for the code 
which has nothing to do with the plugins main menu but was put in that 
MainMenuAction() to execute the code in the context of the main thread.

In my case, the following code is to be executed in the new function:

   void cXineDevice::mainMenuTrampoline()
   {
#if VDRVERSNUM >= 10332
     cMutexLock switchPrimaryDeviceLock(&m_switchPrimaryDeviceMutex);
     if (m_switchPrimaryDeviceDeviceNo < 0)
       return;

     cControl::Shutdown();

     if (m_switchPrimaryDeviceDeviceNo == (1 + DeviceNumber()))
     {
       char *msg = 0;
       ::asprintf(&msg, tr("Switching primary DVB to %s..."), 
m_plugin->Name());

       Skins.Message(mtInfo, msg);
       ::free(msg);
     }

     SetPrimaryDevice(m_switchPrimaryDeviceDeviceNo);

     if (m_switchPrimaryDeviceDeviceNo != (1 + DeviceNumber()))
     {
       char *msg = 0;
       ::asprintf(&msg, tr("Switched primary DVB back from %s"), 
m_plugin->Name());

       Skins.Message(mtInfo, msg);
       ::free(msg);
     }

     m_switchPrimaryDeviceCond.Broadcast();
#endif
   }

I see here a new problem, as I need to call cControl::Shutdown(), but 
when VDR's main thread returns to it's main loop, it still may use 
"Menu" which is most likely invalid at that time:

         // Main thread hooks of plugins:
         PluginManager.MainThreadHook();
         // User Input:
         cOsdObject *Interact = Menu ? Menu : cControl::Control();

Maybe PluginManager.MainThreadHook() should be called earlier.

Bye.
-- 
Dipl.-Inform. (FH) Reinhard Nissl
mailto:rnissl at gmx.de



More information about the vdr mailing list