Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions erts/doc/references/driver_entry.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,8 @@ typedef struct erl_drv_entry {
int (*init)(void); /* Called at system startup for statically
linked drivers, and after loading for
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 */
#else
ErlDrvData (*start)(ErlDrvPort port, char *command, SysDriverOpts* opts);
/* Special options, only for system driver */
#endif
/* Called when open_port/2 is invoked */
Comment thread
sverker marked this conversation as resolved.
void (*stop)(ErlDrvData drv_data);
/* Called when port is closed, and when the
emulator is halted */
Expand Down
4 changes: 3 additions & 1 deletion erts/emulator/beam/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,9 @@ struct erts_driver_t_ {
DE_Handle *handle;
erts_mtx_t *lock;
ErlDrvEntry *entry;
ErlDrvData (*start)(ErlDrvPort port, char *command, SysDriverOpts* opts);
ErlDrvData (*start)(ErlDrvPort port, char *command);
ErlDrvData (*start_sys_drv)(ErlDrvPort port, char *command,
SysDriverOpts* opts);
void (*stop)(ErlDrvData drv_data);
void (*finish)(void);
void (*flush)(ErlDrvData drv_data);
Expand Down
32 changes: 23 additions & 9 deletions erts/emulator/beam/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ static erts_atomic64_t bytes_in;
static erts_atomic64_t bytes_out;

static void deliver_result(Port *p, Eterm sender, Eterm pid, Eterm res);
static int init_driver(erts_driver_t *, ErlDrvEntry *, DE_Handle *);
static int init_driver(erts_driver_t *, ErlDrvEntry *, DE_Handle *, bool);
static void terminate_port(Port *p);
static void pdl_init(void);
static int driver_failure_term(ErlDrvPort ix, Eterm term, int eof);
Expand Down Expand Up @@ -685,7 +685,7 @@ erts_open_driver(erts_driver_t* driver, /* Pointer to driver. */
&opts->high_msgq_watermark);

error_number = error_type = 0;
if (driver->start) {
if (driver->start || driver->start_sys_drv) {
ERTS_MSACC_PUSH_STATE_M();
if (ERTS_IS_P_TRACED_FL(port, F_TRACE_SCHED_PORTS)) {
trace_sched_ports_where(port, am_in, am_open);
Expand All @@ -710,7 +710,13 @@ erts_open_driver(erts_driver_t* driver, /* Pointer to driver. */
}
#endif

drv_data = (*driver->start)(ERTS_Port2ErlDrvPort(port), name, opts);
if (driver->start_sys_drv) {
drv_data = (*driver->start_sys_drv)(ERTS_Port2ErlDrvPort(port),
name, opts);
}
else {
drv_data = (*driver->start)(ERTS_Port2ErlDrvPort(port), name);
}
if (((SWord) drv_data) == -1)
error_type = -1;
else if (((SWord) drv_data) == -2) {
Expand Down Expand Up @@ -3024,10 +3030,10 @@ void erts_init_io(int port_tab_size,
erts_tsd_set(driver_list_lock_status_key, (void *) 1);
erts_rwmtx_rwlock(&erts_driver_list_lock);

init_driver(&fd_driver, &fd_driver_entry, NULL);
init_driver(&spawn_driver, &spawn_driver_entry, NULL);
init_driver(&fd_driver, &fd_driver_entry, NULL, true);
init_driver(&spawn_driver, &spawn_driver_entry, NULL, true);
#ifndef __WIN32__
init_driver(&forker_driver, &forker_driver_entry, NULL);
init_driver(&forker_driver, &forker_driver_entry, NULL, true);
#endif
erts_init_static_drivers();
for (dp = driver_tab; dp->de != NULL; dp++)
Expand Down Expand Up @@ -7547,7 +7553,8 @@ no_stop_select_callback(ErlDrvEvent event, void* private)
((DE)->major_version == (MAJOR) && (DE)->minor_version >= (MINOR)))

static int
init_driver(erts_driver_t *drv, ErlDrvEntry *de, DE_Handle *handle)
init_driver(erts_driver_t *drv, ErlDrvEntry *de, DE_Handle *handle,
bool is_system_driver)
{
drv->name_atom = erts_atom_put((byte*)de->driver_name,
sys_strlen(de->driver_name),
Expand All @@ -7570,7 +7577,14 @@ init_driver(erts_driver_t *drv, ErlDrvEntry *de, DE_Handle *handle)
}
drv->entry = de;

drv->start = de->start;
if (is_system_driver) {
drv->start = NULL;
drv->start_sys_drv = de->start;
}
else {
drv->start = (ErlDrvData (*)(ErlDrvPort, char *)) de->start;
drv->start_sys_drv = NULL;
}
drv->stop = de->stop;
drv->finish = de->finish;
drv->flush = de->flush;
Expand Down Expand Up @@ -7651,7 +7665,7 @@ int erts_add_driver_entry(ErlDrvEntry *de, DE_Handle *handle,
}

if (!err) {
err = init_driver(dp, de, handle);
err = init_driver(dp, de, handle, false);

if (taint) {
erts_add_taint(dp->name_atom);
Expand Down
Loading