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())) >> { >> >> 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. Should be ok too. It's similar to call it earlier in the next loop run ;-) Bye. -- Dipl.-Inform. (FH) Reinhard Nissl mailto:rnissl@xxxxxx