Module libpulse_binding::context
[−]
[src]
Connection contexts for asynchronous communication with a server.
A Context
object wraps a connection to a PulseAudio server using its native protocol.
Overview
The asynchronous API is the native interface to the PulseAudio library. It allows full access to all available functionality. This however means that it is rather complex and can take some time to fully master.
Main Loop Abstraction
The API is based around an asynchronous event loop, or main loop, abstraction. This abstraction contains three basic elements:
- Deferred events: Events that will trigger as soon as possible. Note that some implementations may block all other events when a deferred event is active.
- I/O events: Events that trigger on file descriptor activities.
- Timer events: Events that trigger after a fixed amount of time.
The abstraction is represented as a number of function pointers in the
::mainloop::api::MainloopApi
structure.
To actually be able to use these functions, an implementation needs to be coupled to the abstraction. There are three of these shipped with PulseAudio, but any other can be used with a minimal amount of work, provided it supports the three basic events listed above.
The implementations shipped with PulseAudio are:
- 'Standard': A minimal but fast implementation based on poll().
- 'Threaded': A special version of the previous implementation where all of PulseAudio's internal handling runs in a separate thread.
- 'Glib': A wrapper around GLib's main loop. This is provided in the separate
libpulse_glib_binding
crate.
UNIX signals may be hooked to a main loop using the functions from ::mainloop::signal
. These
rely only on the main loop abstraction and can therefore be used with any of the
implementations.
Reference Counting
Almost all objects in PulseAudio are reference counted. What that means is that you rarely malloc() or free() any objects. Instead you increase and decrease their reference counts. Whenever an object's reference count reaches zero, that object gets destroyed and any resources it uses get freed.
The benefit of this design is that an application need not worry about whether or not it needs to keep an object around in case the library is using it internally. If it is, then it has made sure it has its own reference to it.
Whenever the library creates an object, it will have an initial reference count of one. Most of
the time, this single reference will be sufficient for the application, so all required
reference count interaction will be a single call to the object's unref
function.
Interacting with PulseAudio through this Rust binding, pointers to most reference counted
objects are held in a wrapper object, which has an implementation of the Drop
trait, which is
automatically called upon the owned wrapper object going out of scope, and calls the PulseAudio
unref
function. Should use of this binding require increasing the ref count further, there is
a choice of either possibly using the raw PulseAudio ref
/unref
functions with the underlying
C API object pointer, if available, or, preferably, using Rust Rc
/Arc
wrappers.
Context
A context is the basic object for a connection to a PulseAudio server. It multiplexes commands, data streams and events through a single channel.
There is no need for more than one context per application, unless connections to multiple servers are needed.
Operations
All operations on the context are performed asynchronously. I.e. the client will not wait for
the server to complete the request. To keep track of all these in-flight operations, the
application is given an ::operation::Operation
object for each asynchronous operation.
There are only two actions (besides reference counting) that can be performed on an
::operation::Operation
: querying its state with ::operation::Operation::get_state
and
aborting it with ::operation::Operation::cancel
.
An ::operation::Operation
object is reference counted, so an application must make sure to
unreference it, even if it has no intention of using it. This however is taken care of
automatically in this Rust binding via the implementation of the Drop
trait on the object.
Connecting
A context must be connected to a server before any operation can be issued. Calling
Context::connect
will initiate the connection procedure. Unlike most asynchronous
operations, connecting does not result in an ::operation::Operation
object. Instead, the
application should register a callback using Context::set_state_callback
.
Disconnecting
When the sound support is no longer needed, the connection needs to be closed using
Context::disconnect
. This is an immediate function that works synchronously.
Since the context object has references to other objects it must be disconnected after use or
there is a high risk of memory leaks. If the connection has terminated by itself, then there is
no need to explicitly disconnect the context using Context::disconnect
.
Functions
The sound server's functionality can be divided into a number of subsections:
Modules
ext_device_manager |
Routines for controlling module-device-manager. |
ext_device_restore |
Routines for controlling module-device-restore. |
ext_stream_restore |
Routines for controlling module-stream-restore. |
flags |
Some special flags for contexts. |
introspect |
Routines for daemon introspection. |
scache |
Sample cache mechanism. |
subscribe |
Daemon introspection event subscription subsystem. |
Structs
Context |
An opaque connection context to a daemon This acts as a safe Rust wrapper for the actual C object. |
Enums
ContextInternal |
An opaque connection context to a daemon |
State |
The state of a connection context |
Type Definitions
ContextEventCb |
A callback for asynchronous meta/policy event messages. The set of defined events can be extended at any time. Also, server modules may introduce additional message types so make sure that your callback function ignores messages it doesn't know. |
ContextNotifyCb |
Generic notification callback prototype |
ContextSuccessCb |
A generic callback for operation completion
The |
FlagSet |