4
* Copyright Ericsson AB 2006-2010. All Rights Reserved.
4
* Copyright Ericsson AB 2006-2011. All Rights Reserved.
6
6
* The contents of this file are subject to the Erlang Public License,
7
7
* Version 1.1, (the "License"); you may not use this file except in
142
142
* really load and add as LOADED {ok,loaded} {ok,pending_driver}
143
143
* {error, permanent} {error,load_error()}
145
BIF_RETTYPE erl_ddll_try_load_3(Process *p, Eterm path_term,
146
Eterm name_term, Eterm options)
145
BIF_RETTYPE erl_ddll_try_load_3(BIF_ALIST_3)
147
Eterm path_term = BIF_ARG_1;
148
Eterm name_term = BIF_ARG_2;
149
Eterm options = BIF_ARG_3;
148
150
char *path = NULL;
150
152
char *name = NULL;
152
154
erts_driver_t *drv;
238
238
sys_strcpy(path+path_len,name);
241
erts_smp_proc_unlock(p, ERTS_PROC_LOCK_MAIN);
241
erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
244
244
if ((drv = lookup_driver(name)) != NULL) {
250
250
dh = drv->handle;
251
251
if (dh->status == ERL_DE_OK) {
252
int is_last = is_last_user(dh,p);
252
int is_last = is_last_user(dh, BIF_P);
253
253
if (reload == 1 && !is_last) {
254
254
/*Want reload if no other users,
255
255
but there are others...*/
263
263
soft_error_term = am_inconsistent;
266
if ((old = find_proc_entry(dh, p, ERL_DE_PROC_LOADED)) ==
266
if ((old = find_proc_entry(dh, BIF_P,
267
ERL_DE_PROC_LOADED)) ==
268
269
soft_error_term = am_not_loaded_by_this_process;
275
276
/* Reload requested and granted */
276
277
dereference_all_processes(dh);
277
set_driver_reloading(dh, p, path, name, flags);
278
set_driver_reloading(dh, BIF_P, path, name, flags);
278
279
if (dh->flags & ERL_DE_FL_KILL_PORTS) {
310
311
notify_all(dh, drv->name,
311
312
ERL_DE_PROC_AWAIT_UNLOAD, am_UP,
312
313
am_unload_cancelled);
313
add_proc_loaded(dh,p);
314
add_proc_loaded(dh, BIF_P);
314
315
erts_ddll_reference_driver(dh);
316
317
ok_term = mkatom("already_loaded");
329
330
/* Load of granted unload... */
330
add_proc_loaded_deref(dh,p); /* Dont reference, will happen after reload */
331
/* Don't reference, will happen after reload */
332
add_proc_loaded_deref(dh, BIF_P);
332
334
ok_term = am_pending_driver;
333
335
} else { /* ERL_DE_PERMANENT */
371
373
if (!(prt->status & FREE_PORT_FLAGS) &&
372
374
prt->drv_ptr->handle == dh) {
374
erts_smp_atomic_inc(&prt->refc);
376
erts_smp_atomic_inc_nob(&prt->refc);
375
377
/* Extremely rare spinlock */
376
378
while(prt->status & ERTS_PORT_SFLG_INITIALIZING) {
377
379
erts_smp_port_state_unlock(prt);
400
402
erts_ddll_reference_driver(dh);
401
403
unlock_drv_list();
402
erts_smp_proc_lock(p, ERTS_PROC_LOCK_MAIN);
404
erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
404
406
erts_ddll_dereference_driver(dh);
407
p->flags |= F_USING_DDLL;
409
BIF_P->flags |= F_USING_DDLL;
409
Eterm mref = add_monitor(p, dh, ERL_DE_PROC_AWAIT_LOAD);
411
Eterm mref = add_monitor(BIF_P, dh, ERL_DE_PROC_AWAIT_LOAD);
412
hp = HAlloc(BIF_P, 4);
411
413
t = TUPLE3(hp, am_ok, ok_term, mref);
415
hp = HAlloc(BIF_P, 3);
414
416
t = TUPLE2(hp, am_ok, ok_term);
419
421
erts_free(ERTS_ALC_T_DDLL_TMP_BUF, (void *) path);
420
422
erts_free(ERTS_ALC_T_DDLL_TMP_BUF, (void *) name);
421
ERTS_SMP_LC_ASSERT(ERTS_PROC_LOCK_MAIN & erts_proc_lc_my_proc_locks(p));
423
ERTS_SMP_LC_ASSERT(ERTS_PROC_LOCK_MAIN & erts_proc_lc_my_proc_locks(BIF_P));
425
427
unlock_drv_list();
426
erts_smp_proc_lock(p, ERTS_PROC_LOCK_MAIN);
428
erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
428
430
if (do_build_load_error) {
429
soft_error_term = build_load_error(p, build_this_load_error);
431
soft_error_term = build_load_error(BIF_P, build_this_load_error);
434
hp = HAlloc(BIF_P, 3);
433
435
t = TUPLE2(hp, am_error, soft_error_term);
434
436
erts_free(ERTS_ALC_T_DDLL_TMP_BUF, (void *) path);
435
437
erts_free(ERTS_ALC_T_DDLL_TMP_BUF, (void *) name);
436
ERTS_SMP_LC_ASSERT(ERTS_PROC_LOCK_MAIN & erts_proc_lc_my_proc_locks(p));
438
ERTS_SMP_LC_ASSERT(ERTS_PROC_LOCK_MAIN & erts_proc_lc_my_proc_locks(BIF_P));
439
441
assert_drv_list_not_locked();
440
ERTS_SMP_LC_ASSERT(ERTS_PROC_LOCK_MAIN & erts_proc_lc_my_proc_locks(p));
442
ERTS_SMP_LC_ASSERT(ERTS_PROC_LOCK_MAIN & erts_proc_lc_my_proc_locks(BIF_P));
441
443
if (path != NULL) {
442
444
erts_free(ERTS_ALC_T_DDLL_TMP_BUF, (void *) path);
444
446
if (name != NULL) {
445
447
erts_free(ERTS_ALC_T_DDLL_TMP_BUF, (void *) name);
449
BIF_ERROR(BIF_P, BADARG);
483
485
any AWAIT_LOAD-waiters with {'DOWN', ref(), driver, name(), load_cancelled}
484
486
If the driver made itself permanent, {'UP', ref(), driver, name(), permanent}
486
Eterm erl_ddll_try_unload_2(Process *p, Eterm name_term, Eterm options)
488
Eterm erl_ddll_try_unload_2(BIF_ALIST_2)
490
Eterm name_term = BIF_ARG_1;
491
Eterm options = BIF_ARG_2;
488
492
char *name = NULL;
489
493
Eterm ok_term = NIL;
490
494
Eterm soft_error_term = NIL;
498
502
int kill_ports = 0;
500
erts_smp_proc_unlock(p, ERTS_PROC_LOCK_MAIN);
504
erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
502
506
for(l = options; is_list(l); l = CDR(list_val(l))) {
503
507
Eterm opt = CAR(list_val(l));
550
554
if (dh->flags & ERL_DE_FL_KILL_PORTS) {
553
if ((pe = find_proc_entry(dh, p, ERL_DE_PROC_LOADED)) == NULL) {
557
if ((pe = find_proc_entry(dh, BIF_P, ERL_DE_PROC_LOADED)) == NULL) {
554
558
if (num_procs(dh, ERL_DE_PROC_LOADED) > 0) {
555
559
soft_error_term = am_not_loaded_by_this_process;
599
603
if (!(prt->status & FREE_PORT_FLAGS)
600
604
&& prt->drv_ptr->handle == dh) {
602
erts_smp_atomic_inc(&prt->refc);
606
erts_smp_atomic_inc_nob(&prt->refc);
603
607
/* Extremely rare spinlock */
604
608
while(prt->status & ERTS_PORT_SFLG_INITIALIZING) {
605
609
erts_smp_port_state_unlock(prt);
627
631
erts_ddll_reference_driver(dh);
628
632
unlock_drv_list();
629
erts_smp_proc_lock(p, ERTS_PROC_LOCK_MAIN);
633
erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
631
635
erts_ddll_dereference_driver(dh);
633
637
erts_free(ERTS_ALC_T_DDLL_TMP_BUF, (void *) name);
634
p->flags |= F_USING_DDLL;
638
BIF_P->flags |= F_USING_DDLL;
635
639
if (monitor > 0) {
636
Eterm mref = add_monitor(p, dh, ERL_DE_PROC_AWAIT_UNLOAD);
640
Eterm mref = add_monitor(BIF_P, dh, ERL_DE_PROC_AWAIT_UNLOAD);
641
hp = HAlloc(BIF_P, 4);
638
642
t = TUPLE3(hp, am_ok, ok_term, mref);
644
hp = HAlloc(BIF_P, 3);
641
645
t = TUPLE2(hp, am_ok, ok_term);
643
647
if (kill_ports > 1) {
644
ERTS_BIF_CHK_EXITED(p); /* May be exited by port killing */
648
ERTS_BIF_CHK_EXITED(BIF_P); /* May be exited by port killing */
647
651
unlock_drv_list();
653
657
unlock_drv_list();
655
659
erts_free(ERTS_ALC_T_DDLL_TMP_BUF, (void *) name);
656
erts_smp_proc_lock(p, ERTS_PROC_LOCK_MAIN);
660
erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
661
hp = HAlloc(BIF_P, 3);
658
662
t = TUPLE2(hp, am_error, soft_error_term);
663
667
if (name != NULL) {
664
668
erts_free(ERTS_ALC_T_DDLL_TMP_BUF, (void *) name);
666
erts_smp_proc_lock(p, ERTS_PROC_LOCK_MAIN);
670
erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
671
BIF_ERROR(BIF_P, BADARG);
672
676
* A shadow of the "real" demonitor BIF
674
BIF_RETTYPE erl_ddll_demonitor_1(Process *p, Eterm ref)
678
BIF_RETTYPE erl_ddll_demonitor_1(BIF_ALIST_1)
676
if (is_not_internal_ref(ref)) {
677
BIF_ERROR(p, BADARG);
680
if (is_not_internal_ref(BIF_ARG_1)) {
681
BIF_ERROR(BIF_P, BADARG);
679
if (p->flags & F_USING_DDLL) {
680
erts_ddll_remove_monitor(p, ref, ERTS_PROC_LOCK_MAIN);
683
if (BIF_P->flags & F_USING_DDLL) {
684
erts_ddll_remove_monitor(BIF_P, BIF_ARG_1, ERTS_PROC_LOCK_MAIN);
682
686
BIF_RET(am_true);
686
690
* A shadow of the "real" monitor BIF
688
BIF_RETTYPE erl_ddll_monitor_2(Process *p, Eterm dr, Eterm what)
692
BIF_RETTYPE erl_ddll_monitor_2(BIF_ALIST_2)
690
if (dr != am_driver) {
694
if (BIF_ARG_1 != am_driver) {
695
BIF_ERROR(BIF_P, BADARG);
693
return erts_ddll_monitor_driver(p, what, ERTS_PROC_LOCK_MAIN);
697
return erts_ddll_monitor_driver(BIF_P, BIF_ARG_2, ERTS_PROC_LOCK_MAIN);
697
701
* Return list of loaded drivers {ok,[string()]}
699
Eterm erl_ddll_loaded_drivers_0(Process *p)
703
BIF_RETTYPE erl_ddll_loaded_drivers_0(BIF_ALIST_0)
708
712
for (drv = driver_list; drv; drv = drv->next) {
709
713
need += sys_strlen(drv->name)*2+2;
715
hp = HAlloc(BIF_P, need);
712
716
for (drv = driver_list; drv; drv = drv->next) {
714
718
l = buf_to_intlist(&hp, drv->name, sys_strlen(drv->name), NIL);
728
732
* item is processes, driver_options, port_count, linked_in_driver,
729
733
* permanent, awaiting_load, awaiting_unload
731
Eterm erl_ddll_info_2(Process *p, Eterm name_term, Eterm item)
735
BIF_RETTYPE erl_ddll_info_2(BIF_ALIST_2)
738
Eterm name_term = BIF_ARG_1;
739
Eterm item = BIF_ARG_2;
733
740
char *name = NULL;
735
742
erts_driver_t *drv;
852
859
* Backend for erl_ddll:format_error, handles all "soft" errors returned by builtins,
853
860
* possibly by calling the system specific error handler
855
Eterm erl_ddll_format_error_int_1(Process *p, Eterm code_term)
862
BIF_RETTYPE erl_ddll_format_error_int_1(BIF_ALIST_1)
865
Eterm code_term = BIF_ARG_1;
857
866
char *errstring = NULL;
1056
1065
if (!(prt->status & FREE_PORT_FLAGS) &&
1057
1066
prt->drv_ptr->handle == dh) {
1059
erts_smp_atomic_inc(&prt->refc);
1068
erts_smp_atomic_inc_nob(&prt->refc);
1060
1069
while(prt->status & ERTS_PORT_SFLG_INITIALIZING) {
1061
1070
erts_smp_port_state_unlock(prt);
1062
1071
erts_smp_port_state_lock(prt);
1561
1570
if ((res = erts_sys_ddll_load_driver_init(dh->handle,
1562
1571
&init_handle)) != ERL_DE_NO_ERROR) {
1563
erts_sys_ddll_close(dh->handle);
1564
return ERL_DE_LOAD_ERROR_NO_INIT;
1572
res = ERL_DE_LOAD_ERROR_NO_INIT;
1567
1576
dp = erts_sys_ddll_call_init(init_handle);
1568
1577
if (dp == NULL) {
1569
erts_sys_ddll_close(dh->handle);
1570
return ERL_DE_LOAD_ERROR_FAILED_INIT;
1578
res = ERL_DE_LOAD_ERROR_FAILED_INIT;
1573
1582
switch (dp->extended_marker) {
1576
* This may be an old driver that has been recompiled. If so,
1577
* at least the fields that existed in extended driver version
1578
* 1.0 should be zero. If not, a it is a bad driver. We cannot
1579
* be completely certain that this is a valid driver but this is
1580
* the best we can do with old drivers...
1582
if (dp->major_version != 0
1583
|| dp->minor_version != 0
1584
|| dp->driver_flags != 0
1585
|| dp->handle2 != NULL
1586
|| dp->process_exit != NULL) {
1587
/* Old driver; needs to be recompiled... */
1588
return ERL_DE_LOAD_ERROR_INCORRECT_VERSION;
1591
1583
case ERL_DRV_EXTENDED_MARKER:
1592
1584
if (ERL_DRV_EXTENDED_MAJOR_VERSION != dp->major_version
1593
1585
|| ERL_DRV_EXTENDED_MINOR_VERSION < dp->minor_version) {
1594
1586
/* Incompatible driver version */
1595
return ERL_DE_LOAD_ERROR_INCORRECT_VERSION;
1587
res = ERL_DE_LOAD_ERROR_INCORRECT_VERSION;
1599
1592
/* Old driver; needs to be recompiled... */
1600
return ERL_DE_LOAD_ERROR_INCORRECT_VERSION;
1593
res = ERL_DE_LOAD_ERROR_INCORRECT_VERSION;
1603
1597
if (strcmp(name, dp->driver_name) != 0) {
1604
erts_sys_ddll_close(dh->handle);
1605
return ERL_DE_LOAD_ERROR_BAD_NAME;
1598
res = ERL_DE_LOAD_ERROR_BAD_NAME;
1607
erts_smp_atomic_init(&(dh->refc), (long) 0);
1601
erts_smp_atomic_init_nob(&(dh->refc), (erts_aint_t) 0);
1608
1602
dh->port_count = 0;
1609
1603
dh->full_path = erts_alloc(ERTS_ALC_T_DDLL_HANDLE, sys_strlen(path) + 1);
1610
1604
sys_strcpy(dh->full_path, path);
1618
1612
erts_free(ERTS_ALC_T_DDLL_HANDLE, dh->full_path);
1619
1613
dh->full_path = NULL;
1620
erts_sys_ddll_close(dh->handle);
1621
return ERL_DE_LOAD_ERROR_FAILED_INIT;
1614
res = ERL_DE_LOAD_ERROR_FAILED_INIT;
1624
1617
return ERL_DE_NO_ERROR;
1620
erts_sys_ddll_close(dh->handle);
1627
1624
static int do_unload_driver_entry(DE_Handle *dh, Eterm *save_name)
1890
1887
memcpy(name,ap->name,ap->len);
1891
1888
name[ap->len] = '\0';
1893
name_len = io_list_len(name_term);
1894
if (name_len <= 0) {
1890
if (erts_iolist_size(name_term, &name_len)) {
1897
1893
name = erts_alloc(ERTS_ALC_T_DDLL_TMP_BUF, name_len + 1);