This module provides an interface for loading and unloading Erlang linked-in drivers in runtime.
This is a large reference document. For casual use of this
module, and for most real world applications, the
descriptions of functions
The driver is to be provided as a dynamically linked library
in an object code format specific for the platform in use,
that is,
When describing a set of functions (that is, a module, a part of a module, or an application), executing in a process and wanting to use a ddll-driver, we use the term user. A process can have many users (different modules needing the same driver) and many processes running the same code, making up many users of a driver.
In the basic scenario, each user loads the driver before starting to use it and unloads the driver when done. The reference counting keeps track of processes and the number of loads by each process. This way the driver is only unloaded when no one wants it (it has no user). The driver also keeps track of ports that are opened to it. This enables delay of unloading until all ports are closed, or killing of all ports that use the driver when it is unloaded.
The interface supports two basic scenarios of loading and unloading. Each scenario can also have the option of either killing ports when the driver is unloading, or waiting for the ports to close themselves. The scenarios are as follows:
This (most common) scenario simply supports that each
Each
The following two pairs of functions support this scenario:
When using the
If a process having the driver loaded dies, it has the same effect as if unloading is done.
When loading, function
These interfaces are intended to be used when it is considered an
error that ports are open to a driver that no
The function names
This scenario can occur if the driver code needs
replacement during operation of the Erlang
emulator. Implementing driver code replacement is a little
more tedious than Beam code replacement, as one driver
cannot be loaded as both "old" and "new" code. All
The unloading/loading is done as one atomic operation, blocking all processes in the system from using the driver in question while in progress.
The preferred way to do driver code replacement is to let
one single process keep track of the driver. When
the process starts, the driver is loaded. When replacement
is required, the driver is reloaded. Unload is probably never
done, or done when the process exits. If more than one
Demanding reload when a reload is already in progress is
always an error. Using the high-level functions, it is also
an error to demand reloading when more than one
To simplify driver replacement, avoid designing your system so
that more than one
The two functions for reloading drivers are to be used together with corresponding load functions to support the two different behaviors concerning open ports:
This pair of functions is used when reloading is to be done after the last open port to the driver is closed.
As
This pair of functions are used when open ports to
the driver are to be killed with reason
However, if another process has the driver loaded,
calling
Removes a driver monitor in much the same way as
The function throws a
Takes an
Because of peculiarities in the dynamic loading interfaces on different platforms, the returned string is only guaranteed to describe the correct error if format_error/1 is called in the same instance of the Erlang virtual machine as the error appeared in (meaning the same operating system process).
Returns a list of tuples
Returns a list of tuples
The following tags appears in the list:
For a detailed description of each value, see
The function throws a
Returns specific information about one aspect of a driver.
Parameter
Returns all processes containing
Returns a list of the driver options provided when
loading, and any options set by the driver
during initialization. The only valid option
is
Returns the number of ports (an
Returns a
Returns a
Returns a list of all processes having monitors for
Returns a list of all processes having monitors for
If option
The function throws a
Loads and links the dynamic driver
The
If the driver was previously unloaded, but is still
present because of open ports to it, a call to
If more than one process tries to load an already loaded
driver with the same
It is not allowed to load multiple drivers with
the same name but with different
On success, the function returns
For more control over the error handling, use the
The function throws a
Works essentially as
The number of loads and unloads by different
This interface (or at least the name of the functions) is
kept for backward compatibility.
Using
The function throws a
Returns a list of all the available drivers, both (statically) linked-in and dynamically loaded ones.
The driver names are returned as a list of strings rather than a list of atoms for historical reasons.
For more information about drivers, see
Creates a driver monitor and works in many
ways as
As with process monitors, each driver monitor set only
generates one single message. The monitor is
"destroyed" after the message is sent, so it is then not
needed to call
The function accepts the following parameters:
The monitor tag is always
Parameter
Notifies when the driver is reloaded (or loaded if
loading is underway). It only makes sense to monitor
drivers that are in the process of being loaded or
reloaded. A future driver name for loading cannot be
monitored. That only results in a
Setting a driver monitor for
This message is sent either immediately if the driver is already loaded and no reloading is pending, or when reloading is executed if reloading is pending.
The
This message is sent if reloading was expected, but the (old) driver made itself permanent before reloading. It is also sent if the driver was permanent or statically linked-in when trying to create the monitor.
This message arrives if reloading was
underway, but the requesting
This message arrives if reloading was
underway but the loading for some reason
failed. The
Monitors when a driver gets unloaded. If one monitors a driver that is not present in the system, one immediately gets notified that the driver got unloaded. There is no guarantee that the driver was ever loaded.
A driver monitor for unload eventually results in one of the following messages being sent:
The monitored driver instance is now
unloaded. As the unload can be a result of a
This message is sent if unloading was
expected, but while the driver was waiting for
all ports to get closed, a new
This message appears if
If one really wants to monitor when the
driver gets unloaded, this message distorts
the picture, because no unloading was done.
Option
This message is sent if unloading was expected, but the driver made itself permanent before unloading. It is also sent if trying to monitor a permanent or statically linked-in driver.
A monitor created as
The function throws a
Reloads the driver named
If there are other
Avoid mixing multiple
To avoid hanging on open ports, use function
The
On success, the function returns
For more control over the error handling, use the
The function throws a
Works exactly as
As this interface implies that ports are killed when the last user disappears, the function does not hang waiting for ports to get closed.
For more details, see
The function throws a
Provides more control than the
The driver was loaded and is immediately usable.
The driver was already loaded by another process
or is in use by a living port, or both. The load by you is
registered and a corresponding
The load request is registered, but the loading is
delayed because an earlier instance of the
driver is still waiting to get unloaded (open
ports use it). Still, unload is expected when you are
done with the driver. This return value
mostly occurs when options
The load request is registered, but the loading is
delayed because an earlier instance of the
driver is still waiting to get unloaded by another
When the function returns
When monitoring is requested, and a corresponding
In case of loading, monitoring can not only get
triggered by using option
The function accepts the following parameters:
The file system path to the directory where the driver
object file is located. The filename of the object file
(minus extension) must correspond to the driver name
(used in parameter
The (possibly flattened)
This parameter is the name of the driver
to be used in subsequent calls to function
Some options can be specified to control the loading operation. The options are specified as a list of two-tuples. The tuples have the following values and meanings:
This is to provide options that changes its general behavior and "sticks" to the driver throughout its lifespan.
The driver options for a specified driver name need always to be consistent, even when the driver is reloaded, meaning that they are as much a part of the driver as the name.
The only allowed driver option is
A
Only one
The atom
The atom
Option
If reloading is not requested, it can still be
useful to specify option
This option is used to
reload a driver from disk, most often in a
code upgrade scenario. Having a
To reload a driver, the process must have loaded the driver
before, that is, there must be an active
The
With the atom
The option also triggers port-killing (if driver
option
This option is more useful. Here, reloading is queued
if the driver is not loaded by any other
If the driver is unloaded (not present in the system),
error code
The function can return numerous errors, some can only be returned given a certain combination of options.
Some errors are opaque and can only be interpreted by
passing them to function
The driver with the specified name is an Erlang statically linked-in driver, which cannot be manipulated with this API.
The driver is already loaded with other
This can occur even if a
The driver has requested itself to be permanent, making it behave like an Erlang linked-in driver and can no longer be manipulated with this API.
The driver is loaded by other
Driver reload is already requested by another
Appears when option
Appears when option
All other error codes are to be translated by function
If the arguments or options are malformed, the function
throws a
This is the low-level function to unload (or decrement
reference counts of) a driver. It can be used to force port
killing, in much the same way as the driver option
Unloading can be described as the process of telling the
emulator that this particular part of the code in this
particular process (that is, this
If the driver has option
To allow the
If option
The possible monitor messages to expect are the
same as when using option
The function returns one of the following statuses upon success:
The driver was immediately unloaded, meaning that the driver name is now free to use by other drivers and, if the underlying OS permits it, the memory occupied by the driver object code is now reclaimed.
The driver can only be unloaded when there are no open
ports using it and no more
Indicates that this call removed the last
This return value is valid even if option
The unload request is registered, but
other
This is a normal, healthy, return value if the call was
just placed to inform the emulator that you have no
further use of the driver. It is the most
common return value in the most common
The function accepts the following parameters:
Argument
Forces killing of all ports opened using this driver,
with exit reason
If other
To get the consistent behavior of killing ports
when the last
Creates a driver monitor if the condition
specified in
Creates a driver monitor if the return value is to
be
Creates a monitor if the return value is
The
Using the monitor triggers in the call to
The function can return the following error conditions, all well specified (no opaque values):
You were trying to unload an Erlang statically linked-in driver, which cannot be manipulated with this interface (and cannot be unloaded at all).
The driver
The driver
As a special case, drivers can be unloaded from
processes that have done no corresponding call to
The driver has made itself permanent, in which case it can no longer be manipulated by this interface (much like a statically linked-in driver).
The function throws a
Unloads, or at least dereferences the driver named
If there are other
The
The function throws a
Unloads, or at least dereferences the driver named
If there are other
The
The function throws a