D-Bus
D-Bus
is a message-oriented middleware mechanism that allows communication between multiple processes running concurrently on the same machine. D-Bus was developed as part of the freedesktop.org project, initiated by GNOME developer Havoc Pennington to standardize services provided by Linux desktop environments such as GNOME and KDE Plasma.
The freedesktop.org project also developed a free and open-source software library called libdbus, as a reference implementation of the specification. This library is not D-Bus itself, as other implementations of the D-Bus specification also exist, such as GDBus, QtDBus, dbus-java and sd-bus.
Overview
D-Bus is an inter-process communication mechanism initially designed to replace the software component communications systems CORBA and DCOP, used by the GNOME and KDE Linux desktop environments respectively. The components of these desktop environments are normally distributed in many processes, each providing only one or a few services. These services may be used by regular client applications or by other components of the desktop environment to perform their tasks.D-Bus provides a software-bus abstraction that gathers all the communications among a group of processes over a single shared virtual channel. Processes connected to a bus do not know how it is internally implemented, but the D-Bus specification guarantees that all processes connected to the bus can communicate with each other through it. D-Bus incurs at least a 2.5x performance loss over one-to-one IPC.
Linux desktop environments take advantage of the D-Bus facilities by instantiating multiple buses, notably:
- a single system bus, available to all users and processes of the system, that provides access to system services ; and
- a session bus for each user login session, that provides desktop services to user applications in the same desktop session, and allows the integration of the desktop session as a whole.
D-Bus provides additional or simplifies existing functionality to the applications, including information-sharing, modularity and privilege separation. For example, information on an incoming voice call received through Bluetooth or Skype can be propagated and interpreted by any currently running music player, which can react by muting the volume or by pausing playback until the call is finished.
D-Bus can also be used as a framework to integrate different components of a user application. For instance, an office suite can communicate through the session bus to share data between a word processor and a spreadsheet.
D-Bus specification
Bus model
Every connection to a bus is identified in the context of D-Bus by what is called a bus name. A bus name consists of two or more dot-separated strings of letters, digits, dashes, and underscores—a reverse domain name. An example of a valid bus name is.When a process sets up a connection to a bus, the bus assigns to the connection a special bus name called unique connection name. Bus names of this type are immutable—it is guaranteed they will not change as long as the connection exists—and, more importantly, they cannot be reused during the bus lifetime. This means that no other connection to that bus will ever have assigned such unique connection name, even if the same process closes down the connection to the bus and creates a new one. Unique connection names are easily recognizable because they start with the otherwise forbidden colon character. An example of a unique connection name is .
A process can ask for additional bus names for its connection, provided that any requested name is not already being used by another connection to the bus. In D-Bus parlance, when a bus name is assigned to a connection, it is said the connection owns the bus name. In that sense, a bus name cannot be owned by two connections at the same time, but, unlike unique connection names, these names can be reused if they are available: a process may reclaim a bus name released—purposely or not—by another process.
The idea behind these additional bus names, commonly called well-known names, is to provide a way to refer to a service using a prearranged bus name. For instance, the service that reports the current time and date in the system bus lies in the process whose connection owns the bus name, regardless of which process it is.
Bus names can be used as a simple way to implement single-instance applications. It can also be used to track a service process lifecycle, since the bus sends a notification when a bus name is released due to a process termination.
Object model
Because of its original conception as a replacement for several component oriented communications systems, D-Bus shares with its predecessors an object model in which to express the semantics of the communications between clients and services. The terms used in the D-Bus object model mimic those used by some object oriented programming languages. That does not mean that D-Bus is somehow limited to OOP languages—in fact, the most used implementation is written in C, a procedural programming language.In D-Bus, a process offers its services by exposing objects. These objects have methods that can be invoked, and signals that the object can emit. Methods and signals are collectively referred to as the members of the object. Any client connected to the bus can interact with an object by using its methods, making requests or commanding the object to perform actions. For instance, an object representing a time service can be queried by a client using a method that returns the current date and time. A client can also listen to signals that an object emits when its state changes due to certain events, usually related to the underlying service. An example would be when a service that manages hardware devices—such as USB or network drivers—signals a "new hardware device added" event. Clients should instruct the bus that they are interested in receiving certain signals from a particular object, since a D-Bus bus only passes signals to those processes with a registered interest in them.
A process connected to a D-Bus bus can request it to export as many D-Bus objects as it wants. Each object is identified by an object path, a string of numbers, letters and underscores separated and prefixed by the slash character, called that because of their resemblance to Unix filesystem paths. The object path is selected by the requesting process, and must be unique in the context of that bus connection. An example of a valid object path is. However, it is not enforced—but also not discouraged—to form hierarchies within object paths. The particular naming convention for the objects of a service is entirely up to the developers of such service, but many developers choose to namespace them using the reserved domain name of the project as a prefix.
Every object is inextricably associated to the particular bus connection where it was exported, and, from the D-Bus point of view, only lives in the context of such connection. Therefore, in order to be able to use a certain service, a client must indicate not only the object path providing the desired service, but also the bus name under which the service process is connected to the bus. This in turn allows that several processes connected to the bus can export different objects with identical object paths unambiguously.
An interface specifies members—methods and signals—that can be used with an object. It is a set of declarations of methods and signals identified by a dot-separated name resembling the Java language interfaces notation. An example of a valid interface name is. Despite their similarity, interface names and bus names should not be mistaken. A D-Bus object can implement several interfaces, but at least must implement one, providing support for every method and signal defined by it. The combination of all interfaces implemented by an object is called the object type.
When using an object, it is a good practice for the client process to provide the member's interface name besides the member's name, but is only mandatory when there is an ambiguity caused by duplicated member names available from different interfaces implemented by the object—otherwise, the selected member is undefined or erroneous. An emitted signal, on the other hand, must always indicate to which interface it belongs.
The D-Bus specification also defines several standard interfaces that objects may want to implement in addition to its own interfaces. Although technically optional, most D-Bus service developers choose to support them in their exported objects since they offer important additional features to D-Bus clients, such as introspection. These standard interfaces are:
- : provides a way to test if a D-Bus connection is alive.
- : provides an introspection mechanism by which a client process can, at run-time, get a description of the interfaces, methods and signals that the object implements.
- : allows a D-Bus object to expose the underlying native object properties or attributes, or simulate them if it does not exist.
- : when a D-Bus service arranges its objects hierarchically, this interface provides a way to query an object about all sub-objects under its path, as well as their interfaces and properties, using a single method call.