From 57c3246511434f42214e113b8902af10ab9cca49 Mon Sep 17 00:00:00 2001
From: xsipewe Use this functionality with extreme care! Use this functionality with extreme care. A driver callback is executed as a direct extension of the
- native code of the VM. Execution is not made in a safe environment.
- The VM can not provide the same services as provided when
- executing Erlang code, such as preemptive scheduling or memory
- protection. If the driver callback function doesn't behave well,
- the whole VM will misbehave. A driver callback that crash will crash the whole VM. An erroneously implemented driver callback might cause
- a VM internal state inconsistency which may cause a crash of the VM,
- or miscellaneous misbehaviors of the VM at any point after the call
- to the driver callback. A driver callback that do
-
-
A driver callback that crash will crash the whole VM.
+An erroneously implemented driver callback can cause a VM + internal state inconsistency, which can cause a crash of the VM, + or miscellaneous misbehaviors of the VM at any point after the + call to the driver callback.
+A driver callback doing
+
- As of erts version 5.9 (OTP release R15B) the driver interface + + +
As from
Old drivers (compiled with an
The
The
-
The driver call-back functions are called synchronously from the - erlang emulator. If they take too long before completing, they - can cause timeouts in the emulator. Use the queue or - asynchronous calls if necessary, since the emulator must be + +
The driver callback functions are called synchronously from the + Erlang emulator. If they take too long before completing, they + can cause time-outs in the emulator. Use the queue or + asynchronous calls if necessary, as the emulator must be responsive.
-The driver structure contains the name of the driver and some - 15 function pointers. These pointers are called at different + +
The driver structure contains the driver name and some + 15 function pointers, which are called at different times by the emulator.
+The only exported function from the driver is
When writing a driver in C++, the driver entry should be of
-
When writing a driver in C++, the driver entry is to be of
+
+extern "C" DRIVER_INIT(drivername);+
When the driver has passed the
If compiling a driver for static inclusion via --enable-static-drivers you - have to define STATIC_ERLANG_DRIVER before the DRIVER_INIT declaration.
+ +If compiling a driver for static inclusion through
+
Do not declare the
Do not declare the
typedef struct erl_drv_entry {
- int (*init)(void); /* called at system start up for statically
+ int (*init)(void); /* Called at system startup for statically
linked drivers, and after loading for
- dynamically loaded drivers */
-
+ dynamically loaded drivers */
#ifndef ERL_SYS_DRV
ErlDrvData (*start)(ErlDrvPort port, char *command);
- /* called when open_port/2 is invoked.
- return value -1 means failure. */
+ /* Called when open_port/2 is invoked,
+ return value -1 means failure */
#else
ErlDrvData (*start)(ErlDrvPort port, char *command, SysDriverOpts* opts);
- /* special options, only for system driver */
+ /* Special options, only for system driver */
#endif
void (*stop)(ErlDrvData drv_data);
- /* called when port is closed, and when the
- emulator is halted. */
+ /* Called when port is closed, and when the
+ emulator is halted */
void (*output)(ErlDrvData drv_data, char *buf, ErlDrvSizeT len);
- /* called when we have output from erlang to
+ /* Called when we have output from Erlang to
the port */
void (*ready_input)(ErlDrvData drv_data, ErlDrvEvent event);
- /* called when we have input from one of
+ /* Called when we have input from one of
the driver's handles */
void (*ready_output)(ErlDrvData drv_data, ErlDrvEvent event);
- /* called when output is possible to one of
+ /* Called when output is possible to one of
the driver's handles */
- char *driver_name; /* name supplied as command
- in open_port XXX ? */
- void (*finish)(void); /* called before unloading the driver -
- DYNAMIC DRIVERS ONLY */
- void *handle; /* Reserved -- Used by emulator internally */
+ char *driver_name; /* Name supplied as command in
+ erlang:open_port/2 */
+ void (*finish)(void); /* Called before unloading the driver -
+ dynamic drivers only */
+ void *handle; /* Reserved, used by emulator internally */
ErlDrvSSizeT (*control)(ErlDrvData drv_data, unsigned int command,
char *buf, ErlDrvSizeT len,
char **rbuf, ErlDrvSizeT rlen);
- /* "ioctl" for drivers - invoked by
+ /* "ioctl" for drivers - invoked by
port_control/3 */
- void (*timeout)(ErlDrvData drv_data); /* Handling of timeout in driver */
+ void (*timeout)(ErlDrvData drv_data);
+ /* Handling of time-out in driver */
void (*outputv)(ErlDrvData drv_data, ErlIOVec *ev);
- /* called when we have output from erlang
+ /* Called when we have output from Erlang
to the port */
void (*ready_async)(ErlDrvData drv_data, ErlDrvThreadData thread_data);
void (*flush)(ErlDrvData drv_data);
- /* called when the port is about to be
- closed, and there is data in the
- driver queue that needs to be flushed
+ /* Called when the port is about to be
+ closed, and there is data in the
+ driver queue that must be flushed
before 'stop' can be called */
ErlDrvSSizeT (*call)(ErlDrvData drv_data, unsigned int command,
char *buf, ErlDrvSizeT len,
char **rbuf, ErlDrvSizeT rlen, unsigned int *flags);
/* Works mostly like 'control', a synchronous
- call into the driver. */
+ call into the driver */
void (*event)(ErlDrvData drv_data, ErlDrvEvent event,
ErlDrvEventData event_data);
- /* Called when an event selected by
+ /* Called when an event selected by
driver_event() has occurred */
int extended_marker; /* ERL_DRV_EXTENDED_MARKER */
int major_version; /* ERL_DRV_EXTENDED_MAJOR_VERSION */
int minor_version; /* ERL_DRV_EXTENDED_MINOR_VERSION */
int driver_flags; /* ERL_DRV_FLAGs */
- void *handle2; /* Reserved -- Used by emulator internally */
+ void *handle2; /* Reserved, used by emulator internally */
void (*process_exit)(ErlDrvData drv_data, ErlDrvMonitor *monitor);
/* Called when a process monitor fires */
void (*stop_select)(ErlDrvEvent event, void* reserved);
/* Called to close an event object */
- } ErlDrvEntry;
-
-
+ } ErlDrvEntry;
This is called directly after the driver has been loaded by
-
Called directly after the driver has been loaded by
+
This is called when the driver is instantiated, when
-
ERL_DRV_ERROR_GENERAL - general error, no error code
-ERL_DRV_ERROR_ERRNO - error with error code in
ERL_DRV_ERROR_BADARG - error, badarg
-If an error code is returned, the port isn't started.
+Called when the driver is instantiated, when
+
If an error code is returned, the port is not started.
This is called when the port is closed, with
-
Called when the port is closed, with
+
This is called when an erlang process has sent data to the
- port. The data is pointed to by
Called when an Erlang process has sent data to the port. The data is
+ pointed to by
This is called when a driver event (given in the
-
On unix the
Called when a driver event (specified in parameter
+
On Unix the
On Windows the
On Windows the
To use this with threads and asynchronous routines, create a
- pipe on unix and an Event on Windows. When the routine
+ pipe on Unix and an
Spurious events may happen. That is, calls to
False events can occur. That is, calls to
This is the name of the driver, it must correspond to the
- atom used in
The driver name. It must correspond to the atom used in
+
This function is called by the
Called by the
The driver is only unloaded as a result of calling
-
This field is reserved for the emulator's internal use. The
- emulator will modify this field; therefore, it is important
- that the
This is a special routine invoked with the erlang function
-
A special routine invoked with
+
This is the fastest way of calling a driver and get a - response. It won't make any context switch in the erlang - emulator, and requires no message passing. It is suitable - for calling C function to get faster execution, when erlang + response. It makes no context switch in the Erlang + emulator and requires no message passing. It is suitable + for calling C function to get faster execution, when Erlang is too slow.
-If the driver wants to return data, it should return it in +
If the driver wants to return data, it is to return it in
If the flag is set to
If the flag is set to
Using binaries is faster if more than a few bytes are returned.
-The return value is the number of bytes returned in
-
The return value is the number of bytes returned in
This function is called any time after the driver's timer
- reaches 0. The timer is activated with
-
Called any time after the driver's timer reaches
This function is called whenever the port is written to. If +
Called whenever the port is written to. If
it is
The
This function is called after an asynchronous call has
- completed. The asynchronous call is started with
Called after an asynchronous call has completed.
+ The asynchronous call is started with
+
Called when the port is about to be closed, + and there is data in the driver queue that must be flushed + before 'stop' can be called.
This function is called from
Called from
The return value is the number of bytes returned in
Intentionally left undocumented.
- This field should either be equal to
This field is either to be equal to
This field should equal
This field is to equal
- This field should equal
This field is to equal
This field is used to pass driver capability and other
- information to the runtime system. If the
-
The runtime system uses port-level locking on
+ all ports executing this driver instead of driver-level
+ locking when the driver is run in a runtime
+ system with SMP support. For more information, see
+
Marks that driver instances can handle being called
+ in the
Disables busy port message queue functionality. For
+ more information, see
+
When this flag is specified, the linked-in driver must manually
+ acknowledge that the port has been successfully started using
+
- This field is reserved for the emulator's internal use. The
- emulator will modify this field; therefore, it is important
- that the
This field is reserved for the emulator's internal use. The
+ emulator modifies this field, so it is important
+ that the
This callback is called when a monitored process exits. The +
Called when a monitored process exits. The
This function is called on behalf of
-
Called on behalf of
+
A typical implementation on Unix is to do
-
Argument
In contrast to most of the other call-back functions,
-
Argument
In contrast to most of the other callback functions,
+
It is not allowed to call any functions in the
-
As from
As from ERTS 5.9 (Erlang/OTP R15B) the driver interface
has been changed with larger types for the callbacks
Old drivers (compiled with an