How to share state with applications for Free Unix-based desktops
So you're writing an application. At some point, you have a problem where you want to be able to talk to an instance of your program while it's running. It turns out, this is fiendishly difficult for Free Unix-based desktops, and many programs get it wrong. On my Fedora 9 system, looking in /tmp, I see listings like gconfd-walters (GConf), hsperfdata_walters (OpenJDK), pulse-walters (Pulseaudio), emacs500 (GNU Emacs). All of these programs are broken. The root cause of this is the failure of Unix to provide a standard per-user, per-machine temporary directory. If we had that, things would be dramatically simpler, but we don't.
You can't use /tmp because it's not per-user. Any time you rely on a well-known name in /tmp (like the above list), your application is subject to denial-of-service attacks if another user creates that file before you log in. Security aside, it's also just harder to deal with because you have to check for whether or not the data in your temporary directory is stale or not (is something listening on that socket, or is it left over from a session crash?), and that's yet more painful code.
You can't use $HOME because it's not per-machine (think of all the sites that subject users to the pain of NFS), and won't always support Unix domain socket files.
Now, there are other solutions; you can use the X server, which is what Firefox does I believe. If your application is single-instance this isn't too bad, but there is an easier way:
Enter solution: DBus
The best solution is to use DBus. The key feature here is that the DBus session bus provides exactly what we want: a per-user, per-machine namespace, as well as a fairly sane IPC system we can use to pass messages. Here's how you use it.
- Decide on a service name for your application. For the purposes of this discussion, we'll call it org.openssh.Ssh, for no particular reason.
- In your application startup, try to acquire this name on the session bus, using DBus. If you're successful, your application can now provide a service. To pick a completely random example, this service might be multiplexing SSH connections. If something else already owns the service, then you can act as a client; you might send the message org.openssh.GetControlMasterSocketPath to return the path to another Unix-domain socket, because your application has a non-DBus protocol for communication.
In this example, we just used DBus to retrieve the path to another local, randomly-named Unix domain socket. That's perfectly fine - DBus is not the one true IPC system. Programs like Pulseaudio and OpenSSH already have defined protocols, and there is nothing wrong with that, we don't need to replace them with DBus. However, DBus is the best candidate for a one true atomic session namespace.
Again, all examples used in this blog post are completely hypothetical, and have no relation to the silliness of requiring users to try to hack around this issue on their own computers with variables like ControlMaster and ControlPath to enable a useful feature of your application.

(Anonymous)
Standard
(Anonymous)
This is actually long known
per-session
You're right of course that it should be scoped by dbus, which will make it be correctly per-session.
Re: per-session
In ssh/VT logins you won't interact with things that use the desktop components generally, so they don't really count as a "session".
Re: per-session
That's why dbus is per-session; DCOP was in KDE, and multiple sessions Just Worked for them due to that.
One of the important points of dbus was to fix this bug. Unfortunately, it got a little stalled on someone actually replacing gconf and nuking all bonobo usage ;-)
Re: per-session
Firefox for example doesn't allow multiple instances (ok, you can use separate profiles, but that's basically equivalent to logging in with a different Unix uid).
Look in ~/.evolution - lots of files in there; key stores, caches, calendars, memo files...I haven't looked, but I'd place money on there being little to no locking around that data.
Eclipse is another - "this workspace is in use".
Even the GNU Bash shell gets it wrong! It doesn't by default save history from multiple instances. Hotwire uses SQLite so it's at least safe to run multiple processes, but it's not guaranteed that they'll see each other's data.
Re: per-session
Think about all those random places where application developers want to write files; maybe it's KDE's Pidgin equivalent that wants to write a conversation log. Or a game wants to write a high score file. Etc.
Re: per-session
But UNIX users more or less understood and expected that. Remember the multiple-session scenario has to do with people already using NFS or AFS shared homedirs with multiple workstations.
In practice the race between two sessions does not really matter in that case, because you're only sitting at one computer at a time, so one of the sessions would generally not be writing anything. "locking by physical presence of user" ;-)
Of course as your data gets to be a complex multi-file cache with a sqlite database indexing it, or something, things are a lot more likely to break. But old-school KDE was just writing .ini files and such.
Re: per-session
Re: per-session
One difference is that firefox and bash and eclipse all fail somewhat gracefully... while logging in to session #2 with the gconf/bonobo problems just kind of blows up.
(Anonymous)