A single instance application is one in which only one instance is allowed to
be running at the same time. Checking for an
existing instance is quite regularly done simply with some sort of lock file or
socket. If a lock is found, then just quit the
app. But suppose you want to pass the current command line arguments along to
the existing instance.
DBus is handy for that. We can check to see if our DBus.Name,
"org.gambas.[Application.Name]" by default, is already registered
on the bus and behave accordingly. The pseudo-logic is:
If DBusName.IsRegistered.With.DbusSessionDaemon ' There is already an instance
running
Send the command line args, via message, to the existing (primary) instance
and quit out of the transient instance
Else
Go ahead and start a 'primary' instance and register our DBus.Name on the bus
End
In Gambas, we would send the message to the existing instance using the general
format
"DBus[DBus.Name][/Path/To/MyDBusObject].inMethod()". But, apparently, this
particular format invisibly tries to register a
connection on the bus using DBus.Name. This causes a problem, because you
cannot register the same name on the bus more than once.
In other words, even if you don't explicitly connect and register a name on the
bus, simply trying to send a message on the bus
causes an intrinsic registration; and, an exception. And you cannot use a
random, guaranteed-unique name for DBus.Name or else
you wouldn't know what it is and would have no way of knowing 'who' to send the
message to.
The solution is to change Dbus.Name in the transient instance just prior to
passing along the command line data. Here is my
original, error-producing code:
--
' DBusInterface class file
Inherits DBusObject
Create Static
Public Sub Receiver(myString As String)
Print "Received: " & myString
End
---
' Gambas module file
Public Sub Main()
If DBus["org.freedesktop.DBus"]["/"].NameHasOwner(DBus.Name)
Print DBus.Name & " already has an owner." ' Only one instance allowed
' ' Send command line args to existing instance
DBus[DBus.Name]["/DBusInterface"].Receiver("command line arguments") '
*[1] *[2]
Quit
Else
DBus.Session.Register(DBusInterface, "/DBusInterface")
Print "Press Ctrl+C to quit."
While True
Wait 0.1
Wend
DBus.Session.Unregister(DBusInterface)
Endif
End
--
*[1]: That line caused "org.freedesktop.DBus.Error.Failed: No return value",
and a Segmentation Fault; even though no return value should have been
expected.
The fix was to do some name swapping:
' ' Send command line args to existing instance
ReceiverDbusName = DBus.Name 'Preserve receiver name
DBus.Name = "org.gambas.Transient" & Application.Name ' Set different
name for transient relay of args.
DBus[ReceiverDbusName]["/DBusInterface"].Receiver("command line arguments")
Problem solved! :-)
--
Lee
__
"Artificial Intelligence is no match for natural stupidity."
--
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151=/4140
___
Gambas-user mailing list
Gambas-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/gambas-user