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