erl_ddll(3)



erl_ddll(3erl)             Erlang Module Definition             erl_ddll(3erl)

NAME
       erl_ddll - Dynamic driver loader and linker.

DESCRIPTION
       This  module  provides  an  interface  for loading and unloading Erlang
       linked-in drivers in runtime.

   Note:
       This is a large reference document. For casual use of this module,  and
       for  most real world applications, the descriptions of functions load/2
       and unload/1 are enough to getting started.

       The driver is to be provided as a dynamically linked library in an  ob-
       ject  code  format specific for the platform in use, that is, .so files
       on most Unix systems and .ddl files on  Windows.  An  Erlang  linked-in
       driver must provide specific interfaces to the emulator, so this module
       is not designed for loading arbitrary dynamic libraries. For  more  in-
       formation about Erlang drivers, see erts:erl_driver .

       When describing a set of functions (that is, a module, a part of a mod-
       ule, 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 (dif-
       ferent 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:

         Load and Unload on a "When Needed Basis":
           This (most common) scenario simply supports that each user  of  the
           driver  loads  it when needed and unloads it when no longer needed.
           The driver is always reference counted and as  long  as  a  process
           keeping  the driver loaded is still alive, the driver is present in
           the system.

           Each user of the driver use literally the  same  pathname  for  the
           driver when demanding load, but the users are not concerned with if
           the driver is already loaded from the file system or if the  object
           code must be loaded from file system.

           The following two pairs of functions support this scenario:

           load/2 and unload/1:
             When using the load/unload interfaces, the driver is not unloaded
             until the last port using the driver is closed. Function unload/1
             can  return  immediately,  as the users have no interrest in when
             the unloading occurs. The driver is unloaded when no one needs it
             any longer.

             If  a  process having the driver loaded dies, it has the same ef-
             fect as if unloading is done.

             When loading, function load/2 returns ok when any instance of the
             driver  is  present. Thus, if a driver is waiting to get unloaded
             (because of open ports), it simply changes  state  to  no  longer
             need unloading.

           load_driver/2 and unload_driver/1:
             These interfaces are intended to be used when it is considered an
             error that ports are open to a driver that no  user  has  loaded.
             The  ports  that  are  still  open  when  the last user calls un-
             load_driver/1 or when the last process having the  driver  loaded
             dies, are killed with reason driver_unloaded.

             The  function  names  load_driver  and unload_driver are kept for
             backward compatibility.

         Loading and Reloading for Code Replacement:
           This scenario can occur if the driver code needs replacement during
           operation of the Erlang emulator. Implementing driver code replace-
           ment is a little more tedious than Beam code  replacement,  as  one
           driver  cannot be loaded as both "old" and "new" code. All users of
           a driver must have it closed (no open ports) before  the  old  code
           can be unloaded and the new code can be loaded.

           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 sin-
           gle 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 user has a driver loaded when code replace-
           ment is demanded, the  replacement  cannot  occur  until  the  last
           "other" user has unloaded the driver.

           Demanding  reload when a reload is already in progress is always an
           error. Using the high-level functions, it is also an error  to  de-
           mand reloading when more than one user has the driver loaded.

           To simplify driver replacement, avoid designing your system so that
           more than one user has the driver loaded.

           The two functions for reloading drivers are  to  be  used  together
           with  corresponding load functions to support the two different be-
           haviors concerning open ports:

           load/2 and reload/2:
             This pair of functions is used when reloading is to be done after
             the last open port to the driver is closed.

             As  reload/2  waits  for  the  reloading  to occur, a misbehaving
             process keeping open ports to the driver (or keeping  the  driver
             loaded)  can cause infinite waiting for reload. Time-outs must be
             provided outside of the process demanding the reload or by  using
             the  low-level  interface  try_load/3  in combination with driver
             monitors.

           load_driver/2 and reload_driver/2:
             This pair of functions are used when open ports to the driver are
             to  be killed with reason driver_unloaded to allow for new driver
             code to get loaded.

             However, if  another  process  has  the  driver  loaded,  calling
             reload_driver  returns error code pending_process. As stated ear-
             lier, the recommended design is to not allow other users than the
             "driver reloader" to demand loading of the driver in question.

DATA TYPES
       driver() = iolist() | atom()

       path() = string() | atom()

EXPORTS
       demonitor(MonitorRef) -> ok

              Types:

                 MonitorRef = reference()

              Removes  a driver monitor in much the same way as erlang:demoni-
              tor/1 in ERTS does with process monitors. For details about  how
              to  create  driver  monitors,  see  monitor/2,  try_load/3,  and
              try_unload/2.

              The function throws a badarg exception if the parameter is not a
              reference().

       format_error(ErrorDesc) -> string()

              Types:

                 ErrorDesc = term()

              Takes an ErrorDesc returned by load, unload, or reload functions
              and returns a string that describes the error or warning.

          Note:
              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 ap-
              peared in (meaning the same operating system process).

       info() -> AllInfoList

              Types:

                 AllInfoList = [DriverInfo]
                 DriverInfo = {DriverName, InfoList}
                 DriverName = string()
                 InfoList = [InfoItem]
                 InfoItem = {Tag :: atom(), Value :: term()}

              Returns a list of tuples {DriverName, InfoList}, where  InfoList
              is the result of calling info/1 for that DriverName. Only dynam-
              ically linked-in drivers are included in the list.

       info(Name) -> InfoList

              Types:

                 Name = driver()
                 InfoList = [InfoItem, ...]
                 InfoItem = {Tag :: atom(), Value :: term()}

              Returns a list of tuples {Tag, Value}, where Tag is the informa-
              tion  item  and  Value is the result of calling info/2 with this
              driver name and this tag. The result is a tuple list  containing
              all information available about a driver.

              The following tags appears in the list:

                * processes

                * driver_options

                * port_count

                * linked_in_driver

                * permanent

                * awaiting_load

                * awaiting_unload

              For a detailed description of each value, see info/2.

              The  function  throws  a  badarg  exception if the driver is not
              present in the system.

       info(Name, Tag) -> Value

              Types:

                 Name = driver()
                 Tag =
                     processes    |    driver_options    |    port_count     |
                 linked_in_driver |
                     permanent | awaiting_load | awaiting_unload
                 Value = term()

              Returns  specific  information about one aspect of a driver. Pa-
              rameter Tag specifies which aspect to get information about. The
              return Value differs between different tags:

                processes:
                  Returns all processes containing users of the specific driv-
                  ers as a list of tuples {pid(),integer() >= 0}, where  inte-
                  ger() denotes the number of users in process pid().

                driver_options:
                  Returns  a list of the driver options provided when loading,
                  and any options set by the driver during initialization. The
                  only valid option is kill_ports.

                port_count:
                  Returns  the  number  of ports (an integer() >= 0) using the
                  driver.

                linked_in_driver:
                  Returns a boolean(), which is true if the driver is a stati-
                  cally linked-in one, otherwise false.

                permanent:
                  Returns  a  boolean(),  which is true if the driver has made
                  itself permanent (and is not a statically linked-in driver),
                  otherwise false.

                awaiting_load:
                  Returns  a list of all processes having monitors for loading
                  active. Each process is returned as {pid(),integer() >=  0},
                  where  integer()  is  the number of monitors held by process
                  pid().

                awaiting_unload:
                  Returns a list of all processes having monitors for  unload-
                  ing  active. Each process is returned as {pid(),integer() >=
                  0}, where integer()  is  the  number  of  monitors  held  by
                  process pid().

              If  option linked_in_driver or permanent returns true, all other
              options return linked_in_driver or permanent, respectively.

              The function throws a badarg exception  if  the  driver  is  not
              present in the system or if the tag is not supported.

       load(Path, Name) -> ok | {error, ErrorDesc}

              Types:

                 Path = path()
                 Name = driver()
                 ErrorDesc = term()

              Loads  and links the dynamic driver Name. Path is a file path to
              the directory containing the driver. Name must be a sharable ob-
              ject/dynamic library. Two drivers with different Path parameters
              cannot be loaded under the same name. Name is a string  or  atom
              containing at least one character.

              The  Name  specified is to correspond to the filename of the dy-
              namically loadable object file residing in the directory  speci-
              fied  as  Path,  but  without  the extension (that is, .so). The
              driver name provided in the driver initialization  routine  must
              correspond  with  the  filename,  in much the same way as Erlang
              module names correspond to the names of the .beam files.

              If the driver was previously unloaded, but is still present  be-
              cause  of open ports to it, a call to load/2 stops the unloading
              and keeps the driver (as long as Path is the same),  and  ok  is
              returned. If you really want the object code to be reloaded, use
              reload/2 or the low-level interface try_load/3 instead. See also
              the  description of different scenarios for loading/unloading in
              the introduction.

              If more than one process tries to load an already loaded  driver
              with the same Path, or if the same process tries to load it many
              times, the function returns ok. The emulator keeps track of  the
              load/2  calls,  so that a corresponding number of unload/2 calls
              must be done from the same process before the  driver  gets  un-
              loaded. It is therefore safe for an application to load a driver
              that is shared between processes or applications when needed. It
              can  safely  be unloaded without causing trouble for other parts
              of the system.

              It is not allowed to load multiple drivers with  the  same  name
              but with different Path parameters.

          Note:
              Path  is  interpreted literally, so that all loaders of the same
              driver must specify the same literal Path string, although  dif-
              ferent paths can point out the same directory in the file system
              (because of use of relative paths and links).

              On success, the function returns  ok.  On  failure,  the  return
              value is {error,ErrorDesc}, where ErrorDesc is an opaque term to
              be translated into human readable form  by  function  format_er-
              ror/1.

              For more control over the error handling, use the try_load/3 in-
              terface instead.

              The function throws a badarg exception if the parameters are not
              specified as described here.

       load_driver(Path, Name) -> ok | {error, ErrorDesc}

              Types:

                 Path = path()
                 Name = driver()
                 ErrorDesc = term()

              Works essentially as load/2, but loads the driver with other op-
              tions. All  ports  using  the  driver  are  killed  with  reason
              driver_unloaded when the driver is to be unloaded.

              The  number  of  loads and unloads by different users influences
              the loading and unloading of a driver  file.  The  port  killing
              therefore  only occurs when the last user unloads the driver, or
              when the last process having loaded the driver exits.

              This interface (or at least the name of the functions)  is  kept
              for  backward  compatibility.  Using try_load/3 with {driver_op-
              tions,[kill_ports]} in the option list gives the same effect re-
              garding the port killing.

              The function throws a badarg exception if the parameters are not
              specified as described here.

       loaded_drivers() -> {ok, Drivers}

              Types:

                 Drivers = [Driver]
                 Driver = string()

              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 info.

       monitor(Tag, Item) -> MonitorRef

              Types:

                 Tag = driver
                 Item = {Name, When}
                 Name = driver()
                 When = loaded | unloaded | unloaded_only
                 MonitorRef = reference()

              Creates a driver monitor and works in many ways as  erlang:moni-
              tor/2  in ERTS, does for processes. When a driver changes state,
              the monitor results in a monitor message that  is  sent  to  the
              calling  process.  MonitorRef  returned  by this function is in-
              cluded in the message sent.

              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 demonitor/1.

              MonitorRef can also be used in subsequent calls  to  demonitor/1
              to remove a monitor.

              The function accepts the following parameters:

                Tag:
                  The  monitor tag is always driver, as this function can only
                  be used to create driver monitors.  In  the  future,  driver
                  monitors  will be integrated with process monitors, why this
                  parameter has to be specified for consistence.

                Item:
                  Parameter Item specifies which driver to monitor (the driver
                  name)  and which state change to monitor. The parameter is a
                  tuple of arity two whose first element is  the  driver  name
                  and second element is one of the following:

                  loaded:
                    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 re-
                    sults  in  a DOWN message sent immediately. Monitoring for
                    loading is therefore most useful when triggered  by  func-
                    tion  try_load/3, where the monitor is created because the
                    driver is in such a pending state.

                    Setting a driver monitor for loading eventually  leads  to
                    one of the following messages being sent:

                    {'UP', reference(), driver, Name, loaded}:
                      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  user  is  expected to know if reloading is demanded
                      before creating a monitor for loading.

                    {'UP', reference(), driver, Name, permanent}:
                      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.

                    {'DOWN', reference(), driver, Name, load_cancelled}:
                      This  message arrives if reloading was underway, but the
                      requesting user cancelled it by dying or calling try_un-
                      load/2 (or unload/1/unload_driver/1) again before it was
                      reloaded.

                    {'DOWN', reference(), driver, Name,  {load_failure,  Fail-
                    ure}}:
                      This  message  arrives if reloading was underway but the
                      loading for some reason failed. The Failure term is  one
                      of  the errors that can be returned from try_load/3. The
                      error term can be passed to format_error/1 for  transla-
                      tion  into human readable form. Notice that the transla-
                      tion must be done in the same running Erlang virtual ma-
                      chine as the error was detected in.

                  unloaded:
                    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:

                    {'DOWN', reference(), driver, Name, unloaded}:
                      The  monitored  driver  instance is now unloaded. As the
                      unload can be a result of a reload/2 request, the driver
                      can  once  again  have been loaded when this message ar-
                      rives.

                    {'UP', reference(), driver, Name, unload_cancelled}:
                      This message is sent  if  unloading  was  expected,  but
                      while  the  driver  was  waiting  for  all  ports to get
                      closed, a new user of the driver appeared, and  the  un-
                      loading was cancelled.

                      This  message  appears  if  {ok, pending_driver} was re-
                      turned from  try_unload/2  for  the  last  user  of  the
                      driver, and then {ok, already_loaded} is returned from a
                      call to try_load/3.

                      If one really wants to monitor when the driver gets  un-
                      loaded,  this  message  distorts the picture, because no
                      unloading was done. Option unloaded_only creates a moni-
                      tor similar to an unloaded monitor, but never results in
                      this message.

                    {'UP', reference(), driver, Name, permanent}:
                      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.

                  unloaded_only:
                    A  monitor created as unloaded_only behaves exactly as one
                    created as unloaded except that  the  {'UP',  reference(),
                    driver, Name, unload_cancelled} message is never sent, but
                    the monitor instead persists until the driver really  gets
                    unloaded.

              The function throws a badarg exception if the parameters are not
              specified as described here.

       reload(Path, Name) -> ok | {error, ErrorDesc}

              Types:

                 Path = path()
                 Name = driver()
                 ErrorDesc = pending_process | OpaqueError
                 OpaqueError = term()

              Reloads the driver named Name from  a  possibly  different  Path
              than  previously  used. This function is used in the code change
              scenario described in the introduction.

              If there are other users of this driver,  the  function  returns
              {error,  pending_process},  but if there are no other users, the
              function call hangs until all open ports are closed.

          Note:
              Avoid mixing multiple users with driver reload requests.

              To avoid hanging on open ports, use function try_load/3 instead.

              The Name and Path parameters have exactly the  same  meaning  as
              when calling the plain function load/2.

              On  success,  the  function returns ok. On failure, the function
              returns an opaque error, except the  pending_process  error  de-
              scribed earlier. The opaque errors are to be translated into hu-
              man readable form by function format_error/1.

              For more control over the error handling, use the try_load/3 in-
              terface instead.

              The function throws a badarg exception if the parameters are not
              specified as described here.

       reload_driver(Path, Name) -> ok | {error, ErrorDesc}

              Types:

                 Path = path()
                 Name = driver()
                 ErrorDesc = pending_process | OpaqueError
                 OpaqueError = term()

              Works exactly as reload/2,  but  for  drivers  loaded  with  the
              load_driver/2 interface.

              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 scenarios in this module description and
              the function description for reload/2.

              The function throws a badarg exception if the parameters are not
              specified as described here.

       try_load(Path, Name, OptionList) ->
                   {ok, Status} |
                   {ok, PendingStatus, Ref} |
                   {error, ErrorDesc}

              Types:

                 Path = path()
                 Name = driver()
                 OptionList = [Option]
                 Option =
                     {driver_options, DriverOptionList} |
                     {monitor, MonitorOption} |
                     {reload, ReloadOption}
                 DriverOptionList = [DriverOption]
                 DriverOption = kill_ports
                 MonitorOption = ReloadOption = pending_driver | pending
                 Status = loaded | already_loaded | PendingStatus
                 PendingStatus = pending_driver | pending_process
                 Ref = reference()
                 ErrorDesc = ErrorAtom | OpaqueError
                 ErrorAtom =
                     linked_in_driver | inconsistent | permanent |
                     not_loaded_by_this_process  | not_loaded | pending_reload
                 |
                     pending_process
                 OpaqueError = term()

              Provides   more   control   than   the    load/2/reload/2    and
              load_driver/2/reload_driver/2  interfaces.  It  never  waits for
              completion of other operations related to the driver, but  imme-
              diately  returns  the status of the driver as one of the follow-
              ing:

                {ok, loaded}:
                  The driver was loaded and is immediately usable.

                {ok, already_loaded}:
                  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 try_unload is expected sometime  in  the
                  future.

                {ok, pending_driver}or {ok, pending_driver, reference()}:
                  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 ex-
                  pected when you are done with the driver. This return  value
                  mostly   occurs   when  options  {reload,pending_driver}  or
                  {reload,pending} are used, but can occur when  another  user
                  is   unloading  a  driver  in  parallel  and  driver  option
                  kill_ports is set. In other words, this return value  always
                  needs to be handled.

                {ok, pending_process}or {ok, pending_process, reference()}:
                  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  user (not only by a port, in
                  which case {ok,pending_driver} would  have  been  returned).
                  Still, unload is expected when you are done with the driver.
                  This return value only occurs when  option  {reload,pending}
                  is used.

              When  the  function  returns  {ok, pending_driver} or {ok, pend-
              ing_process}, one can get information about when the  driver  is
              actually loaded by using option {monitor, MonitorOption}.

              When  monitoring  is  requested,  and a corresponding {ok, pend-
              ing_driver} or {ok,  pending_process}  would  be  returned,  the
              function  instead  returns  a  tuple  {ok, PendingStatus, refer-
              ence()} and the process then gets a monitor message later,  when
              the  driver  gets  loaded.  The monitor message to expect is de-
              scribed in the function description of monitor/2.

          Note:
              In case of loading, monitoring can not only get triggered by us-
              ing  option  {reload,  ReloadOption},  but also in special cases
              where  the  load  error  is  transient.  Thus,  {monitor,  pend-
              ing_driver} is to be used under basically all real world circum-
              stances.

              The function accepts the following parameters:

                Path:
                  The file system path to the directory where the  driver  ob-
                  ject file is located. The filename of the object file (minus
                  extension) must correspond to the driver name (used  in  pa-
                  rameter  Name)  and the driver must identify itself with the
                  same name. Path can be provided as an iolist(),  meaning  it
                  can  be  a  list of other iolist()s, characters (8-bit inte-
                  gers), or binaries, all to be flattened into a  sequence  of
                  characters.

                  The  (possibly  flattened) Path parameter must be consistent
                  throughout the system. A driver is  to,  by  all  users,  be
                  loaded  using  the  same literal Path. The exception is when
                  reloading is requested, in which case Path can be  specified
                  differently. Notice that all users trying to load the driver
                  later need to use the new Path if Path is  changed  using  a
                  reload  option.  This is yet another reason to have only one
                  loader of a driver one wants to upgrade in a running system.

                Name:
                  This parameter is the name of the driver to be used in  sub-
                  sequent calls to function erlang:open_port in ERTS. The name
                  can be specified as an iolist() or an atom(). The name spec-
                  ified when loading is used to find the object file (with the
                  help of Path and the system-implied extension  suffix,  that
                  is,  .so).  The  name  by which the driver identifies itself
                  must also be consistent with this Name  parameter,  much  as
                  the module name of a Beam file much corresponds to its file-
                  name.

                OptionList:
                  Some options can be specified to control the loading  opera-
                  tion. The options are specified as a list of two-tuples. The
                  tuples have the following values and meanings:

                  {driver_options, DriverOptionList}:
                    This is to provide options that changes its general behav-
                    ior 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,  mean-
                    ing  that  they  are  as  much a part of the driver as the
                    name.

                    The only allowed driver option is kill_ports, which  means
                    that  all  ports opened to the driver are killed with exit
                    reason driver_unloaded when no process any longer has  the
                    driver  loaded. This situation arises either when the last
                    user calls try_unload/2, or when the last  process  having
                    loaded the driver exits.

                  {monitor, MonitorOption}:
                    A MonitorOption tells try_load/3 to trigger a driver moni-
                    tor under certain conditions. When the  monitor  is  trig-
                    gered, the function returns a three-tuple {ok, PendingSta-
                    tus, reference()}, where reference() is the monitor refer-
                    ence for the driver monitor.

                    Only  one MonitorOption can be specified. It is one of the
                    following:

                    * The atom pending, which means that a monitor  is  to  be
                      created whenever a load operation is delayed,

                    * The  atom  pending_driver, in which a monitor is created
                      whenever the operation is delayed because of open  ports
                      to an otherwise unused driver.

                    Option pending_driver is of little use, but is present for
                    completeness, as it is well defined which  reload  options
                    that  can  give rise to which delays. However, it can be a
                    good idea to use the same MonitorOption as  the  ReloadOp-
                    tion, if present.

                    If  reloading  is not requested, it can still be useful to
                    specify option monitor, as forced unloads  (driver  option
                    kill_ports or option kill_ports to try_unload/2) trigger a
                    transient state where driver loading cannot  be  performed
                    until  all  closing  ports are closed. Thus, as try_unload
                    can,  in  almost  all  situations,   return   {ok,   pend-
                    ing_driver},  always  specify  at  least  {monitor,  pend-
                    ing_driver} in production code (see the monitor discussion
                    earlier).

                  {reload, ReloadOption}:
                    This option is used to reload a driver from disk, most of-
                    ten in a code upgrade scenario.  Having  a  reload  option
                    also  implies that parameter Path does not need to be con-
                    sistent with earlier loads of the driver.

                    To reload a driver,  the  process  must  have  loaded  the
                    driver  before,  that  is, there must be an active user of
                    the driver in the process.

                    The reload option can be either of the following:

                    pending:
                      With the atom pending, reloading is  requested  for  any
                      driver  and  is effectuated when all ports opened to the
                      driver are closed. The driver replacement in  this  case
                      takes  place regardless if there are still pending users
                      having the driver loaded.

                      The option also triggers port-killing (if driver  option
                      kill_ports  is  used)  although there are pending users,
                      making it usable for forced driver replacement, but lay-
                      ing much responsibility on the driver users. The pending
                      option is seldom used as one does not want  other  users
                      to have loaded the driver when code change is underway.

                    pending_driver:
                      This option is more useful. Here, reloading is queued if
                      the driver is not loaded by any  other  users,  but  the
                      driver  has  opened  ports,  in  which  case  {ok, pend-
                      ing_driver} is returned  (a  monitor  option  is  recom-
                      mended).

                    If the driver is unloaded (not present in the system), er-
                    ror code not_loaded is returned. Option reload is intended
                    for  when  the  user  has already loaded the driver in ad-
                    vance.

              The function can return numerous errors, some can  only  be  re-
              turned given a certain combination of options.

              Some  errors  are  opaque and can only be interpreted by passing
              them to function format_error/1, but some can be interpreted di-
              rectly:

                {error,linked_in_driver}:
                  The  driver  with the specified name is an Erlang statically
                  linked-in driver, which cannot be manipulated with this API.

                {error,inconsistent}:
                  The driver is already loaded with other DriverOptionList  or
                  a different literal Path argument.

                  This  can  occur  even  if  a reload option is specified, if
                  DriverOptionList differs from the current.

                {error, permanent}:
                  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.

                {error, pending_process}:
                  The driver is loaded by other  users  when  option  {reload,
                  pending_driver} was specified.

                {error, pending_reload}:
                  Driver  reload is already requested by another user when op-
                  tion {reload, ReloadOption} was specified.

                {error, not_loaded_by_this_process}:
                  Appears when option reload is specified. The driver Name  is
                  present  in  the  system, but there is no user of it in this
                  process.

                {error, not_loaded}:
                  Appears when option reload is specified. The driver Name  is
                  not  in  the system. Only drivers loaded by this process can
                  be reloaded.

              All other error codes are to  be  translated  by  function  for-
              mat_error/1.  Notice  that  calls to format_error are to be per-
              formed from the same running instance of the Erlang virtual  ma-
              chine  as  the error is detected in, because of system-dependent
              behavior concerning error values.

              If the arguments or options are malformed, the function throws a
              badarg exception.

       try_unload(Name, OptionList) ->
                     {ok, Status} |
                     {ok, PendingStatus, Ref} |
                     {error, ErrorAtom}

              Types:

                 Name = driver()
                 OptionList = [Option]
                 Option = {monitor, MonitorOption} | kill_ports
                 MonitorOption = pending_driver | pending
                 Status = unloaded | PendingStatus
                 PendingStatus = pending_driver | pending_process
                 Ref = reference()
                 ErrorAtom =
                     linked_in_driver          |          not_loaded         |
                 not_loaded_by_this_process |
                     permanent

              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  kill_ports  implicitly
              does.  Also, it can trigger a monitor either because other users
              still have the driver loaded  or  because  open  ports  use  the
              driver.

              Unloading  can be described as the process of telling the emula-
              tor that this particular part of the  code  in  this  particular
              process  (that  is,  this user) no longer needs the driver. That
              can, if there are no  other  users,  trigger  unloading  of  the
              driver, in which case the driver name disappears from the system
              and (if possible) the memory occupied by the  driver  executable
              code is reclaimed.

              If  the  driver  has  option kill_ports set, or if kill_ports is
              specified as an option to this function, all pending ports using
              this  driver are killed when unloading is done by the last user.
              If no port-killing is involved and there are open ports, the un-
              loading  is delayed until no more open ports use the driver. If,
              in this case, another user (or even this user) loads the  driver
              again  before  the driver is unloaded, the unloading never takes
              place.

              To allow the user to request unloading to wait  for  actual  un-
              loading,  monitor triggers can be specified in much the same way
              as when loading. However, as users of this function  seldom  are
              interested in more than decrementing the reference counts, moni-
              toring is seldom needed.

          Note:
              If option kill_ports is used, monitor trigging  is  crucial,  as
              the  ports  are  not guaranteed to be killed until the driver is
              unloaded. Thus, a monitor must be triggered  for  at  least  the
              pending_driver case.

              The possible monitor messages to expect are the same as when us-
              ing option unloaded to function monitor/2.

              The function returns one of the following statuses upon success:

                {ok, unloaded}:
                  The driver was immediately unloaded, meaning that the driver
                  name  is now free to use by other drivers and, if the under-
                  lying OS permits it, the memory occupied by the  driver  ob-
                  ject code is now reclaimed.

                  The driver can only be unloaded when there are no open ports
                  using it and no more users require it to be loaded.

                {ok, pending_driver}or {ok, pending_driver, reference()}:
                  Indicates that this call removed  the  last  user  from  the
                  driver,  but  there  are still open ports using it. When all
                  ports are closed and no new users have arrived,  the  driver
                  is reloaded and the name and memory reclaimed.

                  This  return  value  is  valid even if option kill_ports was
                  used, as killing ports can be a process that does  not  com-
                  plete  immediately.  However,  the condition is in that case
                  transient. Monitors are always useful  to  detect  when  the
                  driver is really unloaded.

                {ok, pending_process}or {ok, pending_process, reference()}:
                  The unload request is registered, but other users still hold
                  the driver. Notice that the term pending_process  can  refer
                  to  the  running process; there can be more than one user in
                  the same process.

                  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 scenario described in the introduction.

              The function accepts the following parameters:

                Name:
                  Name  is the name of the driver to be unloaded. The name can
                  be specified as an iolist() or as an atom().

                OptionList:
                  Argument OptionList can be used to specify certain  behavior
                  regarding ports and triggering monitors under certain condi-
                  tions:

                  kill_ports:
                    Forces killing of all ports opened using this driver, with
                    exit  reason  driver_unloaded, if you are the last user of
                    the driver.

                    If other users have the driver loaded, this option has  no
                    effect.

                    To  get  the consistent behavior of killing ports when the
                    last user unloads, use driver option kill_ports when load-
                    ing the driver instead.

                  {monitor, MonitorOption}:
                    Creates  a  driver  monitor  if the condition specified in
                    MonitorOption is true. The valid options are:

                    pending_driver:
                      Creates a driver monitor if the return value  is  to  be
                      {ok, pending_driver}.

                    pending:
                      Creates  a  monitor  if  the  return value is {ok, pend-
                      ing_driver} or {ok, pending_process}.

                    The pending_driver MonitorOption is by far the  most  use-
                    ful.  It  must be used to ensure that the driver really is
                    unloaded and the ports closed whenever  option  kill_ports
                    is  used,  or  the driver can have been loaded with driver
                    option kill_ports.

                    Using the monitor triggers in the call to  try_unload  en-
                    sures  that  the  monitor is added before the unloading is
                    executed, meaning that  the  monitor  is  always  properly
                    triggered,  which  is  not the case if monitor/2 is called
                    separately.

              The function can return the following error conditions, all well
              specified (no opaque values):

                {error, linked_in_driver}:
                  You  were  trying  to  unload an Erlang statically linked-in
                  driver, which cannot be manipulated with this interface (and
                  cannot be unloaded at all).

                {error, not_loaded}:
                  The driver Name is not present in the system.

                {error, not_loaded_by_this_process}:
                  The  driver  Name  is present in the system, but there is no
                  user of it in this process.

                  As a special case, drivers can be  unloaded  from  processes
                  that  have  done no corresponding call to try_load/3 if, and
                  only if, there are no users of the driver at all, which  can
                  occur if the process containing the last user dies.

                {error, permanent}:
                  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 badarg exception if the parameters are not
              specified as described here.

       unload(Name) -> ok | {error, ErrorDesc}

              Types:

                 Name = driver()
                 ErrorDesc = term()

              Unloads, or at least dereferences the driver named Name. If  the
              caller  is  the  last user of the driver, and no more open ports
              use the driver, the driver gets unloaded.  Otherwise,  unloading
              is delayed until all ports are closed and no users remain.

              If  there are other users of the driver, the reference counts of
              the driver is merely decreased, so that the caller is no  longer
              considered  a user of the driver. For use scenarios, see the de-
              scription in the beginning of this module.

              The ErrorDesc returned is an opaque value to be  passed  further
              on  to function format_error/1. For more control over the opera-
              tion, use the try_unload/2 interface.

              The function throws a badarg exception if the parameters are not
              specified as described here.

       unload_driver(Name) -> ok | {error, ErrorDesc}

              Types:

                 Name = driver()
                 ErrorDesc = term()

              Unloads,  or at least dereferences the driver named Name. If the
              caller is the last user of the driver, all remaining open  ports
              using  the driver are killed with reason driver_unloaded and the
              driver eventually gets unloaded.

              If there are other users of the driver, the reference counts  of
              the  driver is merely decreased, so that the caller is no longer
              considered a user. For use scenarios, see the description in the
              beginning of this module.

              The  ErrorDesc  returned is an opaque value to be passed further
              on to function format_error/1. For more control over the  opera-
              tion, use the try_unload/2 interface.

              The function throws a badarg exception if the parameters are not
              specified as described here.

SEE ALSO
       erts:erl_driver(5), erts:driver_entry(5)

Ericsson AB                       kernel 7.0                    erl_ddll(3erl)

Man(1) output converted with man2html
list of all man pages