[vdr] calling MainMenuAction() from an other plugin

Klaus Schmidinger Klaus.Schmidinger at cadsoft.de
Mon Apr 17 16:47:21 CEST 2006


Reinhard Nissl wrote:
> 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.

Right. That was a dirty trick and I didn't want to manifest that ;-)

> 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.

Originally I was thinking about actually putting it further down.
How about we put it to the very end of the "while (!Interrupted) {"
loop? That way it shouldn't interfere with anything.

I'll make it that way for version 1.3.47, which I will be releasing
shortly.

Klaus



More information about the vdr mailing list