> On 13 September 2017 at 19:39 Dan Williams <d...@redhat.com> wrote: > ... > > The two major patterns for doing all of this are (a) threads and (b) > event-driven programming. GLib is an example of (b), and it really > does remove the error-prone issues of lock management, concurrent data > access, and deadlocks from the equation. In return, you get to make > sure you clean up your event handlers when you're not using them :) > > You can add as many timeout_add_seconds() as you like, or you can put > most of your logic into the one. Globals will work precisely because > you aren't doing multiple threads and thus you are sure that there is > only one thing accessing the global data at a given time. But globals > have their downsides too (mainly from a readability and refactor- > ability perspective). > > There's always the signals option too, if you want to go fully event- > driven. They have nothing to do with the mainloop BTW. But they also > break up the program flow and if you have long chains of them, it can > become a bit more confusing. > > But back to your original question, here's an example of getting NM > state too: > > #!/usr/bin/env python > import gi > gi.require_version('ModemManager', '1.0') > gi.require_version('NM', '1.0') > from gi.repository import GLib, GObject, Gio, ModemManager, NM > import sys, signal > > main_loop = None > > def signal_handler(data): > main_loop.quit() > > def get_modem_state(data): > (obj, nm) = data > modem = obj.get_modem() > print "Modem State: %s" % > ModemManager.ModemState.get_string(modem.get_state()) > > print "NM state: %s" % nm.get_nm_running() > > # Do whatever other work you need to do, as long as it doesn't take many > seconds > > # True = continue running this timeout > return True > > main_loop = GLib.MainLoop() > GLib.unix_signal_add(GLib.PRIORITY_HIGH, signal.SIGHUP, signal_handler, None) > GLib.unix_signal_add(GLib.PRIORITY_HIGH, signal.SIGTERM, signal_handler, None) > > connection = Gio.bus_get_sync(Gio.BusType.SYSTEM, None) > manager = ModemManager.Manager.new_sync(connection, > Gio.DBusObjectManagerClientFlags.DO_NOT_AUTO_START, > None) > modems = manager.get_objects() > if len(modems) == 0: > print "no modems found" > sys.exit(1) > > nm = NM.Client.new(None) > GLib.timeout_add_seconds(5, get_modem_state, (modems[0], nm)) > try: > main_loop.run() > except KeyboardInterrupt: > pass
Thanks Dan. I've persevered with GLib, and made a bit of progress. On top of your suggestion - instead of the start-up "modems = manager.get_objects()" etc, I've hooked in [a derivation of] the ModemWatcher example, and pass an instance in the timeout_add_seconds() instead of 'modems[0]'. Getting somewhere under normal circumstances, but I've found that if MM is restarted whilst the script is running, then get_modem_state() no longer gets called at all. The ModemWatcher instance *is* still spotting the presence of the modem, even if I unload its driver after stopping MM and reload it after MM is restarted. Something, I guess, has got unhooked in the event driving...? _______________________________________________ ModemManager-devel mailing list ModemManager-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/modemmanager-devel