[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