154
178
if(is_not_atom(a))
157
ASSERT((i > 0) && (i < atom_table_size) && (atom_tab(i) != NULL));
158
return is_node_name(atom_tab(i)->name, atom_tab(i)->len);
181
ASSERT((i > 0) && (i < atom_table_size()) && (atom_tab(i) != NULL));
182
return is_node_name((char*)atom_tab(i)->name, atom_tab(i)->len);
162
190
** This function is called when a distribution
163
191
** port or process terminates
166
int do_net_exits(DistEntry *dep)
193
static void doit_monitor_net_exits(ErtsMonitor *mon, void *vnecp)
197
DistEntry *dep = ((NetExitsContext *) vnecp)->dep;
198
Uint32 rp_locks = ERTS_PROC_LOCK_LINK;
200
rp = erts_pid2proc(NULL, 0, mon->pid, rp_locks);
206
if (mon->type == MON_ORIGIN) {
207
/* local pid is beeing monitored */
208
rmon = erts_remove_monitor(&(rp->monitors),mon->ref);
209
/* ASSERT(rmon != NULL); nope, can happen during process exit */
211
erts_destroy_monitor(rmon);
216
ASSERT(mon->type == MON_TARGET);
217
rmon = erts_remove_monitor(&(rp->monitors),mon->ref);
218
/* ASSERT(rmon != NULL); can happen during process exit */
220
ASSERT(is_atom(rmon->name) || is_nil(rmon->name));
221
watched = (is_atom(rmon->name)
222
? TUPLE2(lhp, rmon->name, dep->sysname)
225
rp_locks |= ERTS_PROC_LOCKS_MSG_SEND;
226
erts_smp_proc_lock(rp, ERTS_PROC_LOCKS_MSG_SEND);
228
erts_queue_monitor_message(rp, &rp_locks, mon->ref, am_process,
229
watched, am_noconnection);
230
erts_destroy_monitor(rmon);
233
erts_smp_proc_unlock(rp, rp_locks);
235
erts_destroy_monitor(mon);
239
NetExitsContext *necp;
241
} LinkNetExitsContext;
244
** This is the function actually doing the job of sending exit messages
245
** for links in a dist entry upon net_exit (the node goes down), NB,
246
** only process links, not node monitors are handled here,
247
** they reside in a separate tree....
249
static void doit_link_net_exits_sub(ErtsLink *sublnk, void *vlnecp)
251
ErtsLink *lnk = ((LinkNetExitsContext *) vlnecp)->lnk; /* the local pid */
255
ASSERT(lnk->type == LINK_PID);
256
if (is_internal_pid(lnk->pid)) {
258
Uint32 rp_locks = ERTS_PROC_LOCK_LINK|ERTS_PROC_LOCKS_XSIG_SEND;
260
rp = erts_pid2proc(NULL, 0, lnk->pid, rp_locks);
265
rlnk = erts_remove_link(&(rp->nlinks), sublnk->pid);
266
xres = erts_send_exit_signal(NULL,
276
erts_destroy_link(rlnk);
277
if (xres >= 0 && IS_TRACED_FL(rp, F_TRACE_PROCS)) {
278
/* We didn't exit the process and it is traced */
279
trace_proc(NULL, rp, am_getting_unlinked, sublnk->pid);
282
erts_smp_proc_unlock(rp, rp_locks);
285
erts_destroy_link(sublnk);
294
** This function is called when a distribution
295
** port or process terminates, once for each link on the high level,
296
** it in turn traverses the link subtree for the specific link node...
298
static void doit_link_net_exits(ErtsLink *lnk, void *vnecp)
300
LinkNetExitsContext lnec = {(NetExitsContext *) vnecp, lnk};
301
ASSERT(lnk->type == LINK_PID)
302
erts_sweep_links(lnk->root, &doit_link_net_exits_sub, (void *) &lnec);
306
erts_destroy_link(lnk);
310
static void doit_node_link_net_exits(ErtsLink *lnk, void *vnecp)
312
DistEntry *dep = ((NetExitsContext *) vnecp)->dep;
313
Eterm name = dep->sysname;
317
ASSERT(lnk->type == LINK_NODE)
318
if (is_internal_pid(lnk->pid)) {
319
Uint32 rp_locks = ERTS_PROC_LOCK_LINK|ERTS_PROC_LOCKS_MSG_SEND;
320
rp = erts_pid2proc(NULL, 0, lnk->pid, rp_locks);
324
rlnk = erts_remove_link(&(rp->nlinks), name);
326
ASSERT(is_atom(rlnk->pid) && (rlnk->type == LINK_NODE));
327
erts_destroy_link(rlnk);
329
n = ERTS_LINK_ROOT_AS_UINT(lnk);
331
/* Drop messages if receiver has a pending exit ... */
332
if (!ERTS_PROC_PENDING_EXIT(rp))
335
for (i = 0; i < n; ++i) {
339
Eterm *hp = erts_alloc_message_heap(3,&bp,&ohp,rp,&rp_locks);
340
tup = TUPLE2(hp, am_nodedown, name);
341
erts_queue_message(rp, rp_locks, bp, tup, NIL);
344
erts_smp_proc_unlock(rp, rp_locks);
347
erts_destroy_link(lnk);
352
* proc is currently running or exiting process.
354
int erts_do_net_exits(DistEntry *dep)
173
356
if (dep == erts_this_dist_entry) { /* Net kernel has died (clean up!!) */
358
(void) erts_smp_io_lock();
359
erts_smp_mtx_lock(&erts_dist_table_mtx);
176
361
/* KILL all port controllers */
177
362
while(erts_visible_dist_entries || erts_hidden_dist_entries) {
183
368
&& (erts_port[internal_port_index(tdep->cid)].status
185
370
&& erts_port[internal_port_index(tdep->cid)].dist_entry);
371
erts_smp_mtx_unlock(&erts_dist_table_mtx);
186
372
/* will call do_net_exists !!! */
187
do_exit_port(tdep->cid, tdep->cid, am_killed);
373
erts_do_exit_port(tdep->cid, tdep->cid, am_killed);
374
erts_smp_mtx_lock(&erts_dist_table_mtx);
377
erts_smp_mtx_unlock(&erts_dist_table_mtx);
379
erts_smp_io_unlock();
380
erts_smp_block_system(ERTS_BS_FLG_ALLOW_GC);
191
381
erts_set_this_node(am_Noname, 0);
383
erts_smp_release_system();
197
while (lnk != NULL) {
201
if (is_internal_pid(item)) {
202
if ((rp = pid2proc(item)) == NULL)
204
if (rp->flags & F_TRAPEXIT) {
206
find_link(&rp->links, LNK_LINK, lnk->data, NIL);
208
deliver_exit_message(lnk->data, rp, am_noconnection);
209
if (IS_TRACED_FL(rp, F_TRACE_PROCS)
210
&& rlinkpp != NULL) {
212
am_getting_unlinked, lnk->data);
216
schedule_exit(rp, am_noconnection);
221
if (is_external_pid(item)
222
&& external_pid_dist_entry(item) != erts_this_dist_entry) {
223
/* We are being monitored */
224
if ((rp = pid2proc(lnk->data)) == NULL)
226
del_link(find_link_by_ref(&rp->links, lnk->ref));
230
/* We are monitoring */
231
if ((rp = pid2proc(item)) == NULL)
233
ASSERT(is_pid(lnk->data) || is_atom(lnk->data));
234
watched = (is_atom(lnk->data)
235
? TUPLE2(&lhp[0], lnk->data, dep->sysname)
237
queue_monitor_message(rp, lnk->ref, am_process,
238
watched, am_noconnection);
239
del_link(find_link_by_ref(&rp->links, lnk->ref));
245
if (is_internal_pid(item)) {
248
if ((rp = pid2proc(item)) == NULL)
250
del_link(find_link(&rp->links,LNK_NODE,name,NIL));
251
bp = new_message_buffer(3);
253
tup = TUPLE2(hp, am_nodedown, name);
254
queue_message_tt(rp, bp, tup, NIL);
255
if (SAVED_HEAP_TOP(rp) == NULL) {
256
SAVED_HEAP_TOP(rp) = HEAP_TOP(rp);
257
HEAP_TOP(rp) = HEAP_LIMIT(rp);
259
MSO(rp).overhead = HEAP_SIZE(rp);
267
erl_exit(1, "bad link type in dist links\n");
386
else { /* recursive call via erts_do_exit_port() will end up here */
387
NetExitsContext nec = {dep};
389
ErtsLink *node_links;
390
ErtsMonitor *monitors;
392
ERTS_SMP_LC_ASSERT(erts_smp_lc_io_is_locked());
394
erts_smp_dist_entry_lock(dep);
395
monitors = dep->monitors;
396
nlinks = dep->nlinks;
397
node_links = dep->node_links;
398
dep->monitors = NULL;
400
dep->node_links = NULL;
401
erts_smp_dist_entry_unlock(dep);
403
erts_sweep_monitors(monitors, &doit_monitor_net_exits, (void *) &nec);
404
erts_sweep_links(nlinks, &doit_link_net_exits, (void *) &nec);
405
erts_sweep_links(node_links, &doit_node_link_net_exits, (void *) &nec);
271
407
clear_dist_entry(dep);
308
438
clear_cache(dep);
309
439
erts_set_dist_entry_not_connected(dep);
440
erts_smp_dist_entry_lock(dep);
442
dep->node_links = NULL;
443
dep->monitors = NULL;
445
erts_smp_dist_entry_unlock(dep);
450
* SMP NOTE on dist_*() functions:
452
* Requirements for usage of dist_*() functions:
453
* I/O lock, lock on dep has to be held, and if c_p != NULL, at least
454
* main lock has to be held on c_p.
456
* Also note that lock on dep will be released and reacquired,
457
* and that lock(s) on c_p may be released and reacquired.
316
462
** Send a DOP_LINK link message
318
int dist_link(DistEntry *dep, Eterm local, Eterm remote)
320
Eterm ctl = TUPLE3(dmem, make_small(DOP_LINK), local, remote);
322
return pack_and_send(dep, ctl, THE_NON_VALUE, 0);
326
int dist_unlink(DistEntry *dep, Eterm local, Eterm remote)
328
Eterm ctl = TUPLE3(dmem, make_small(DOP_UNLINK), local, remote);
330
return pack_and_send(dep, ctl, THE_NON_VALUE, 0);
333
int dist_m_exit(DistEntry *dep, Eterm watcher, Eterm watched,
464
/* SMP NOTE: See "SMP NOTE on dist_*() functions" above */
465
int dist_link(Process *c_p, Uint32 c_p_locks,
466
DistEntry *dep, Eterm local, Eterm remote)
469
Eterm ctl = TUPLE3(&ctl_heap[0], make_small(DOP_LINK), local, remote);
471
return pack_and_send(c_p, c_p_locks, dep, ctl, THE_NON_VALUE, 0);
475
/* SMP NOTE: See "SMP NOTE on dist_*() functions" above */
476
int dist_unlink(Process *c_p, Uint32 c_p_locks,
477
DistEntry *dep, Eterm local, Eterm remote)
480
Eterm ctl = TUPLE3(&ctl_heap[0], make_small(DOP_UNLINK), local, remote);
482
return pack_and_send(c_p, c_p_locks, dep, ctl, THE_NON_VALUE, 0);
486
/* A local process that's beeing monitored by a remote one exits. We send:
487
{DOP_MONITOR_P_EXIT, Local pid or name, Remote pid, ref, reason},
488
which is rather sad as only the ref is needed, no pid's... */
489
/* SMP NOTE: See "SMP NOTE on dist_*() functions" above */
490
int dist_m_exit(Process *c_p, Uint32 c_p_locks,
491
DistEntry *dep, Eterm watcher, Eterm watched,
334
492
Eterm ref, Eterm reason)
339
ctl = TUPLE5(hp, make_small(DOP_MONITOR_P_EXIT),
497
ctl = TUPLE5(&ctl_heap[0], make_small(DOP_MONITOR_P_EXIT),
340
498
watched, watcher, ref, reason);
342
del_link(find_link_by_ref(&(dep->links), ref));
501
ASSERT(!erts_lookup_monitor(dep->monitors, ref));
344
return pack_and_send(dep, ctl, THE_NON_VALUE, 1);
504
return pack_and_send(c_p, c_p_locks, dep, ctl, THE_NON_VALUE, 1);
347
int dist_monitor(DistEntry *dep, Eterm watcher, Eterm watched, Eterm ref)
506
/* We want to monitor a process (named or unnamed) on another node, we send:
507
{DOP_MONITOR_P, Local pid, Remote pid or name, Ref}, which is exactly what's
508
needed on the other side... */
509
/* SMP NOTE: See "SMP NOTE on dist_*() functions" above */
510
int dist_monitor(Process *c_p, Uint32 c_p_locks,
511
DistEntry *dep, Eterm watcher, Eterm watched, Eterm ref)
516
ctl = TUPLE4(&ctl_heap[0],
353
517
make_small(DOP_MONITOR_P),
354
518
watcher, watched, ref);
356
return pack_and_send(dep, ctl, THE_NON_VALUE, 0);
520
return pack_and_send(c_p, c_p_locks, dep, ctl, THE_NON_VALUE, 0);
359
int dist_demonitor(DistEntry *dep, Eterm watcher, Eterm watched,
523
/* A local process monitoring a remote one wants to stop monitoring, either
524
because of a demonitor bif call or because the local process died. We send
525
{DOP_DEMONITOR_P, Local pid, Remote pid or name, ref}, which is once again
526
rather redundant as only the ref will be needed on the other side... */
528
/* SMP NOTE: See "SMP NOTE on dist_*() functions" above */
529
int dist_demonitor(Process *c_p, Uint32 c_p_locks,
530
DistEntry *dep, Eterm watcher, Eterm watched,
360
531
Eterm ref, int force)
536
ctl = TUPLE4(&ctl_heap[0],
366
537
make_small(DOP_DEMONITOR_P),
367
538
watcher, watched, ref);
369
return pack_and_send(dep, ctl, THE_NON_VALUE, force);
540
return pack_and_send(c_p, c_p_locks, dep, ctl, THE_NON_VALUE, force);
372
int dist_send(Process* sender, DistEntry *dep, Eterm remote, Eterm message)
543
/* SMP NOTE: See "SMP NOTE on dist_*() functions" above */
544
int dist_send(Process* sender, Uint32 sender_locks,
545
DistEntry *dep, Eterm remote, Eterm message)
375
549
Eterm token = NIL;
377
551
if (SEQ_TRACE_TOKEN(sender) != NIL) {
412
590
** this implies that the driver must always be ready to queue
413
591
** data even if it has signaled that it is busy !!!
415
int dist_exit_tt(DistEntry *dep, Eterm local, Eterm remote,
593
/* SMP NOTE: See "SMP NOTE on dist_*() functions" above */
594
int dist_exit_tt(Process* c_p, Uint32 c_p_locks,
595
DistEntry *dep, Eterm local, Eterm remote,
416
596
Eterm reason, Eterm token)
600
ErtsLink *lnk, *sublnk;
420
602
if (token != NIL) {
421
603
/* token should be updated by caller */
422
604
seq_trace_output_exit(token, reason, SEQ_TRACE_SEND, remote, local);
423
ctl = TUPLE5(dmem, make_small(DOP_EXIT_TT), local, remote, token, reason);
605
ctl = TUPLE5(&ctl_heap[0],
606
make_small(DOP_EXIT_TT), local, remote, token, reason);
425
ctl = TUPLE4(dmem, make_small(DOP_EXIT), local, remote, reason);
427
del_link(find_link(&(dep->links), LNK_LINK, local, remote));
429
return pack_and_send(dep, ctl, THE_NON_VALUE, 1); /* forced, i.e ignore busy */
608
ctl = TUPLE4(&ctl_heap[0], make_small(DOP_EXIT), local, remote, reason);
611
lnk = erts_lookup_link(dep->nlinks, local);
614
sublnk = erts_remove_link(&(lnk->root), remote);
615
if (sublnk != NULL) {
616
erts_destroy_link(sublnk);
618
if (lnk->root == NULL) {
619
erts_destroy_link(erts_remove_link(&(dep->nlinks), local));
623
return pack_and_send(c_p, c_p_locks, dep, ctl, THE_NON_VALUE, 1); /* forced, i.e ignore busy */
432
int dist_exit(DistEntry *dep, Eterm local, Eterm remote, Eterm reason)
626
/* SMP NOTE: See "SMP NOTE on dist_*() functions" above */
627
int dist_exit(Process* c_p, Uint32 c_p_locks,
628
DistEntry *dep, Eterm local, Eterm remote, Eterm reason)
434
Eterm ctl = TUPLE4(dmem, make_small(DOP_EXIT), local, remote, reason);
435
del_link(find_link(&(dep->links), LNK_LINK, local, remote));
436
return pack_and_send(dep, ctl, THE_NON_VALUE, 1); /* forced, i.e ignore busy */
631
Eterm ctl = TUPLE4(&ctl_heap[0],
632
make_small(DOP_EXIT), local, remote, reason);
633
ErtsLink *lnk, *sublnk;
635
lnk = erts_lookup_link(dep->nlinks, local);
638
sublnk = erts_remove_link(&(lnk->root), remote);
639
if (sublnk != NULL) {
640
erts_destroy_link(sublnk);
642
if (lnk->root == NULL) {
643
erts_destroy_link(erts_remove_link(&(dep->nlinks), local));
647
return pack_and_send(c_p, c_p_locks, dep, ctl, THE_NON_VALUE, 1); /* forced, i.e ignore busy */
439
650
/* internal version of dist_exit2 that force send through busy port */
440
int dist_exit2(DistEntry *dep, Eterm local, Eterm remote, Eterm reason)
651
/* SMP NOTE: See "SMP NOTE on dist_*() functions" above */
652
int dist_exit2(Process* c_p, Uint32 c_p_locks,
653
DistEntry *dep, Eterm local, Eterm remote, Eterm reason)
442
Eterm ctl = TUPLE4(dmem, make_small(DOP_EXIT2), local, remote, reason);
656
Eterm ctl = TUPLE4(&ctl_heap[0],
657
make_small(DOP_EXIT2), local, remote, reason);
444
return pack_and_send(dep, ctl, THE_NON_VALUE, 0);
659
return pack_and_send(c_p, c_p_locks, dep, ctl, THE_NON_VALUE, 0);
448
int dist_group_leader(DistEntry *dep, Eterm leader, Eterm remote)
663
/* SMP NOTE: See "SMP NOTE on dist_*() functions" above */
664
int dist_group_leader(Process* c_p, Uint32 c_p_locks,
665
DistEntry *dep, Eterm leader, Eterm remote)
450
Eterm ctl = TUPLE3(dmem, make_small(DOP_GROUP_LEADER), leader, remote);
668
Eterm ctl = TUPLE3(&ctl_heap[0],
669
make_small(DOP_GROUP_LEADER), leader, remote);
452
return pack_and_send(dep, ctl, THE_NON_VALUE, 0);
671
return pack_and_send(c_p, c_p_locks, dep, ctl, THE_NON_VALUE, 0);
558
782
to = tuple[3]; /* local proc to link to */
560
if ((rp = pid2proc(to)) == NULL) {
784
rp = erts_pid2proc_opt(NULL, 0,
785
to, ERTS_PROC_LOCK_LINK,
786
ERTS_P2P_FLG_ALLOW_OTHER_X);
787
erts_smp_dist_entry_lock(dep);
561
789
/* This is tricky (we MUST force a distributed send) */
562
790
/* We may send it to net_kernel and let it do the job !!! */
563
dist_exit(dep, to, from, am_noproc);
566
if (find_link(&rp->links,LNK_LINK, from, NIL) != NULL)
568
dep->links = new_link(dep->links,LNK_LINK, to, from);
569
rp->links = new_link(rp->links, LNK_LINK, from, NIL);
791
dist_exit(NULL, 0, dep, to, from, am_noproc);
792
erts_smp_dist_entry_unlock(dep);
796
res = erts_add_link(&(rp->nlinks), LINK_PID, from);
799
/* It was already there! Lets skip the rest... */
800
erts_smp_dist_entry_unlock(dep);
801
erts_smp_proc_unlock(rp, ERTS_PROC_LOCK_LINK);
804
lnk = erts_add_or_lookup_link(&(dep->nlinks), LINK_PID, rp->id);
805
erts_add_link(&(lnk->root), LINK_PID, from);
806
erts_smp_dist_entry_unlock(dep);
570
808
if (IS_TRACED_FL(rp, F_TRACE_PROCS))
571
809
trace_proc(NULL, rp, am_getting_linked, from);
811
erts_smp_proc_unlock(rp, ERTS_PROC_LOCK_LINK);
574
814
case DOP_UNLINK: {
579
if ((rp = pid2proc(to)) == NULL)
818
rp = erts_pid2proc_opt(NULL, 0,
819
to, ERTS_PROC_LOCK_LINK,
820
ERTS_P2P_FLG_ALLOW_OTHER_X);
581
rlinkpp = find_link(&rp->links, LNK_LINK, from, NIL);
583
del_link(find_link(&dep->links, LNK_LINK, to, from));
585
if (IS_TRACED_FL(rp, F_TRACE_PROCS) && rlinkpp != NULL) {
824
erts_smp_dist_entry_lock(dep);
825
lnk = erts_remove_link(&(rp->nlinks), from);
827
erts_destroy_link(lnk);
830
lnk = erts_lookup_link(dep->nlinks, rp->id);
832
sublnk = erts_remove_link(&(lnk->root), from);
833
if (sublnk != NULL) {
834
erts_destroy_link(sublnk);
836
if (lnk->root == NULL) {
837
erts_destroy_link(erts_remove_link(&(dep->nlinks), rp->id));
841
erts_smp_dist_entry_unlock(dep);
843
if (IS_TRACED_FL(rp, F_TRACE_PROCS) && lnk != NULL) {
586
844
trace_proc(NULL, rp, am_getting_unlinked, from);
847
erts_smp_proc_unlock(rp, ERTS_PROC_LOCK_LINK);
591
851
case DOP_MONITOR_P: {
852
/* A remote process wants to monitor us, we get:
853
{DOP_MONITOR_P, Remote pid, local pid or name, ref} */
594
856
watcher = tuple[2];
595
857
watched = tuple[3]; /* local proc to monitor */
600
860
if (is_atom(watched)) {
601
rp = whereis_process(watched);
602
if ((rp == NULL) || (rp->status == P_EXITING)) {
603
dist_m_exit(dep, watcher, watched, ref, am_noproc);
607
} else if ((rp = pid2proc(watched)) == NULL) {
608
dist_m_exit(dep, watcher, watched, ref, am_noproc);
611
dep->links = new_ref_link(dep->links, LNK_LINK1, watcher, watched, ref);
612
rp->links = new_ref_link(rp->links, LNK_LINK1, watcher, watched_p, ref);
862
rp = erts_whereis_process(NULL, 0, watched, ERTS_PROC_LOCK_LINK, 1);
866
rp = erts_pid2proc_opt(NULL, 0,
867
watched, ERTS_PROC_LOCK_LINK,
868
ERTS_P2P_FLG_ALLOW_OTHER_X);
871
erts_smp_dist_entry_lock(dep);
874
dist_m_exit(NULL, 0, dep, watcher, watched, ref, am_noproc);
876
if (is_atom(watched))
878
erts_add_monitor(&(dep->monitors), MON_ORIGIN, ref, watched, name);
879
erts_add_monitor(&(rp->monitors), MON_TARGET, ref, watcher, name);
880
erts_smp_proc_unlock(rp, ERTS_PROC_LOCK_LINK);
883
erts_smp_dist_entry_unlock(dep);
616
888
case DOP_DEMONITOR_P:
889
/* A remote node informs us that a local pid in no longer monitored
890
We get {DOP_DEMONITOR_P, Remote pid, Local pid or name, ref},
891
We need only the ref of course */
617
893
/* watcher = tuple[2]; */
618
894
/* watched = tuple[3]; May be an atom in case of monitor name */
621
lnkp = find_link_by_ref(&dep->links, ref);
624
watched = (*lnkp)->data;
625
if ((rp = pid2proc(watched)) == NULL)
628
del_link(find_link_by_ref(&rp->links, ref));
897
erts_smp_dist_entry_lock(dep);
898
mon = erts_remove_monitor(&(dep->monitors),ref);
899
/* ASSERT(mon != NULL); can happen in case of broken dist message */
901
erts_smp_dist_entry_unlock(dep);
905
erts_destroy_monitor(mon);
906
erts_smp_dist_entry_unlock(dep);
907
rp = erts_pid2proc_opt(NULL, 0,
908
watched, ERTS_PROC_LOCK_LINK,
909
ERTS_P2P_FLG_ALLOW_OTHER_X);
913
mon = erts_remove_monitor(&(rp->monitors),ref);
914
erts_smp_proc_unlock(rp, ERTS_PROC_LOCK_LINK);
919
erts_destroy_monitor(mon);
631
922
case DOP_NODE_LINK: /* XXX never sent ?? */
713
1036
token = tuple[4];
714
token = copy_struct(token, token_size, &hp, &MSO(rp));
716
queue_message_tt(rp, NULL, message, token);
1037
token = copy_struct(token, token_size, &hp, ohp);
1040
HRelease(rp,hp_end,hp);
1043
Uint final_size = hp - &bp->mem[0];
1044
Eterm brefs[2] = {message, token};
1045
ASSERT(i + token_size - (hp_end - hp) == final_size);
1046
bp = erts_resize_message_buffer(bp, final_size, &brefs[0], 2);
1050
erts_queue_message(rp, locks, bp, message, token);
1051
erts_smp_proc_unlock(rp, locks);
721
1055
case DOP_MONITOR_P_EXIT: {
1056
/* We are monitoring a process on the remote node which dies, we get
1057
{DOP_MONITOR_P_EXIT, Remote pid or name, Local pid, ref, reason} */
1062
Uint32 rp_locks = ERTS_PROC_LOCKS_MSG_SEND|ERTS_PROC_LOCK_LINK;
724
1064
/* watched = tuple[2]; */ /* remote proc which died */
1065
/* watcher = tuple[3]; */
727
1067
reason = tuple[5];
729
if ((rp = pid2proc(watcher)) == NULL)
732
lnkp = find_link_by_ref(&rp->links, ref);
738
lnkp = find_link_by_ref(&dep->links, ref);
740
ASSERT(is_pid((*lnkp)->data) || is_atom((*lnkp)->data));
741
watched = (is_atom((*lnkp)->data)
742
? TUPLE2(&lhp[0], (*lnkp)->data, dep->sysname)
745
queue_monitor_message(rp, ref, am_process, watched, reason);
1069
erts_smp_dist_entry_lock(dep);
1070
sysname = dep->sysname;
1071
mon = erts_remove_monitor(&(dep->monitors), ref);
1073
* If demonitor was performed at the same time as the
1074
* monitored process exits, monitoring side will have
1075
* removed info about monitor. In this case, do nothing
1076
* and everything will be as it should.
1078
erts_smp_dist_entry_unlock(dep);
1082
rp = erts_pid2proc(NULL, 0, mon->pid, rp_locks);
1087
erts_destroy_monitor(mon);
1089
mon = erts_remove_monitor(&(rp->monitors),ref);
1092
erts_smp_proc_unlock(rp, rp_locks);
1096
watched = (is_not_nil(mon->name)
1097
? TUPLE2(&lhp[0], mon->name, sysname)
1100
erts_queue_monitor_message(rp, &rp_locks,
1101
ref, am_process, watched, reason);
1102
erts_smp_proc_unlock(rp, rp_locks);
1103
erts_destroy_monitor(mon);
750
1107
case DOP_EXIT_TT:
1109
Uint32 rp_locks = ERTS_PROC_LOCK_LINK|ERTS_PROC_LOCKS_XSIG_SEND;
752
1110
/* 'from', which 'to' is linked to, died */
753
1111
if (type == DOP_EXIT) {
754
1112
from = tuple[2];
764
1122
if (is_not_internal_pid(to) && is_not_internal_port(to))
766
del_link(find_link(&dep->links, LNK_LINK, to, from));
768
if (is_internal_pid(to)) {
770
rp = internal_pid_index(to) < erts_max_processes ?
771
process_tab[internal_pid_index(to)] : NULL;
772
if (INVALID_PID(rp, to))
774
rlinkpp = find_link(&rp->links, LNK_LINK, from, NIL);
1125
erts_smp_dist_entry_lock(dep);
1126
lnk = erts_lookup_link(dep->nlinks, to);
1128
sublnk = erts_remove_link(&(lnk->root), from);
1129
if (sublnk != NULL) {
1130
erts_destroy_link(sublnk);
1132
if (lnk->root == NULL) {
1133
erts_destroy_link(erts_remove_link(&(dep->nlinks), to));
1137
erts_smp_dist_entry_unlock(dep);
1139
rp = erts_pid2proc(NULL, 0, to, rp_locks);
1141
lnk = erts_remove_link(&(rp->nlinks), from);
1143
/* If lnk == NULL, we have unlinked on this side, i.e.
1148
erts_destroy_link(lnk);
777
/* Arndt: Maybe it should never be 'kill', but it can be,
778
namely when a linked process does exit(kill). Until we know
779
whether that is incorrect and what should happen instead,
780
we leave the assertion out. */
781
ASSERT(reason != am_kill); /* should never be kill (killed) */
1150
/* Arndt: Maybe it should never be 'kill', but it can be,
1151
namely when a linked process does exit(kill). Until we know
1152
whether that is incorrect and what should happen instead,
1153
we leave the assertion out. */
1154
ASSERT(reason != am_kill); /* should never be kill (killed) */
783
if (rp->flags & F_TRAPEXIT) {
784
/* token updated by remote node */
785
deliver_exit_message_tt(from, rp, reason, token);
786
if (IS_TRACED_FL(rp, F_TRACE_PROCS) && rlinkpp != NULL) {
787
trace_proc(NULL, rp, am_getting_unlinked, from);
789
} else if (reason == am_normal) {
790
if (IS_TRACED_FL(rp, F_TRACE_PROCS) && rlinkpp != NULL) {
791
trace_proc(NULL, rp, am_getting_unlinked, from);
794
schedule_exit(rp, reason);
1156
xres = erts_send_exit_signal(NULL,
1163
ERTS_XSIG_FLG_IGN_KILL);
1164
if (xres >= 0 && IS_TRACED_FL(rp, F_TRACE_PROCS)) {
1165
/* We didn't exit the process and it is traced */
1166
trace_proc(NULL, rp, am_getting_unlinked, from);
1169
erts_smp_proc_unlock(rp, rp_locks);
1171
else if (is_internal_port(to)) {
798
1172
/* Internal port */
799
1173
int ix = internal_port_index(to);
800
1174
if (! INVALID_PORT(erts_port+ix, to)) {
801
del_link(find_link(&erts_port[ix].links,LNK_LINK,from,NIL));
1175
lnk = erts_remove_link(&(erts_port[ix].nlinks), from);
1177
erts_destroy_link(lnk);
803
do_exit_port(to, from, reason);
1180
erts_do_exit_port(to, from, reason);
807
1184
case DOP_EXIT2_TT:
1186
Uint32 rp_locks = ERTS_PROC_LOCKS_XSIG_SEND;
809
1187
/* 'from' is send an exit signal to 'to' */
810
1188
if (type == DOP_EXIT2) {
811
1189
from = tuple[2];
950
1321
if (!force_busy && (p->status & PORT_BUSY))
952
1324
#ifdef MESS_DEBUG
953
if (is_value(mess)) {
954
erl_printf(CERR,">>ctl+mess>> ");
956
erl_printf(CERR," && ");
958
erl_printf(CERR,"\n\r");
961
erl_printf(CERR,">> ");
963
erl_printf(CERR, "\n\r");
1326
erts_printf(stderr, ">>ctl+mess>> %T && %T\n", ctl, mess);
1328
erts_printf(stderr, ">> %T\n", ctl);
1330
bufp = (byte *) erts_alloc(ERTS_ALC_T_TMP_DIST_BUF, DEFAULT_TMP_DIST_BUF_SZ);
1331
bufsz = DEFAULT_TMP_DIST_BUF_SZ;
967
1333
*t++ = PASS_THROUGH; /* not needed !!! */
968
erts_to_external_format(dep, ctl, &t);
1335
erts_to_external_format(dep, ctl, &t, &bufp, &bufsz);
969
1336
if (is_value(mess))
970
erts_to_external_format(dep, mess, &t);
971
dist_port_command(p, dist_buf, t-dist_buf);
1337
erts_to_external_format(dep, mess, &t, &bufp, &bufsz);
1341
* When we call dist_port_command we should only hold the io lock.
1343
erts_smp_dist_entry_unlock(dep);
1347
erts_smp_proc_unlock(c_p, c_p_locks);
1349
ERTS_SMP_CHK_NO_PROC_LOCKS;
1350
ERTS_SMP_LC_ASSERT(erts_smp_lc_io_is_locked());
1353
dist_port_command(p, bufp, t-bufp);
1354
erts_free(ERTS_ALC_T_TMP_DIST_BUF, (void *) bufp);
1357
/* Restore locks as held when pack_and_send() was called...
1358
* Lock order of interest:
1364
erts_smp_proc_lock(c_p, c_p_locks);
1365
erts_smp_dist_entry_lock(dep);
1371
struct print_to_data {
1376
static void doit_print_monitor_info(ErtsMonitor *mon, void *vptdp)
1378
int to = ((struct print_to_data *) vptdp)->to;
1379
void *arg = ((struct print_to_data *) vptdp)->arg;
1382
rp = erts_pid2proc_unlocked(mon->pid);
1383
if (!rp || (rmon = erts_lookup_monitor(rp->monitors, mon->ref)) == NULL) {
1384
erts_print(to, arg, "Warning, stray monitor for: %T\n", mon->pid);
1385
} else if (mon->type == MON_ORIGIN) {
1386
/* Local pid is being monitored */
1387
erts_print(to, arg, "Remotely monitored by: %T %T\n",
1388
mon->pid, rmon->pid);
1390
erts_print(to, arg, "Remote monitoring: %T ", mon->pid);
1391
if (is_not_atom(rmon->pid))
1392
erts_print(to, arg, "%T\n", rmon->pid);
1394
erts_print(to, arg, "{%T, %T}\n",
1396
rmon->pid); /* which in this case is the
1397
remote system name... */
1401
static void print_monitor_info(int to, void *arg, ErtsMonitor *mon)
1403
struct print_to_data ptd = {to, arg};
1404
erts_doforall_monitors(mon,&doit_print_monitor_info,&ptd);
1408
struct print_to_data *ptdp;
1412
static void doit_print_link_info2(ErtsLink *lnk, void *vpplc)
1414
PrintLinkContext *pplc = (PrintLinkContext *) vpplc;
1415
erts_print(pplc->ptdp->to, pplc->ptdp->arg, "Remote link: %T %T\n",
1416
pplc->from, lnk->pid);
1419
static void doit_print_link_info(ErtsLink *lnk, void *vptdp)
1421
if (is_internal_pid(lnk->pid) && erts_pid2proc_unlocked(lnk->pid)) {
1422
PrintLinkContext plc = {(struct print_to_data *) vptdp, lnk->pid};
1423
erts_doforall_links(lnk->root, &doit_print_link_info2, &plc);
1427
static void print_link_info(int to, void *arg, ErtsLink *lnk)
1429
struct print_to_data ptd = {to, arg};
1430
erts_doforall_links(lnk, &doit_print_link_info, (void *) &ptd);
1434
struct print_to_data ptd;
1436
} PrintNodeLinkContext;
1439
static void doit_print_nodelink_info(ErtsLink *lnk, void *vpcontext)
1441
PrintNodeLinkContext *pcontext = vpcontext;
1443
if (is_internal_pid(lnk->pid) && erts_pid2proc_unlocked(lnk->pid))
1444
erts_print(pcontext->ptd.to, pcontext->ptd.arg,
1445
"Remote monitoring: %T %T\n", lnk->pid, pcontext->sysname);
1448
static void print_nodelink_info(int to, void *arg, ErtsLink *lnk, Eterm sysname)
1450
PrintNodeLinkContext context = {{to, arg}, sysname};
1451
erts_doforall_links(lnk, &doit_print_nodelink_info, &context);
976
info_dist_entry(CIO to, DistEntry *dep, int visible, int connected)
1456
info_dist_entry(int to, void *arg, DistEntry *dep, int visible, int connected)
980
1459
if (visible && connected) {
981
erl_printf(to, "=visible_node:");
1460
erts_print(to, arg, "=visible_node:");
982
1461
} else if (connected) {
983
erl_printf(to, "=hidden_node:");
1462
erts_print(to, arg, "=hidden_node:");
985
erl_printf(to, "=not_connected:");
1464
erts_print(to, arg, "=not_connected:");
987
erl_printf(to, "%d\n", dist_entry_channel_no(dep));
1466
erts_print(to, arg, "%d\n", dist_entry_channel_no(dep));
989
1468
if(connected && is_nil(dep->cid)) {
990
erl_printf(to,"Error: Not connected node still registered as connected:");
991
display(dep->sysname, to);
992
erl_printf(to, "\n");
1470
"Error: Not connected node still registered as connected:%T\n",
996
1475
if(!connected && is_not_nil(dep->cid)) {
997
erl_printf(to,"Error: Connected node not registered as connected:");
998
display(dep->sysname, to);
999
erl_printf(to, "\n");
1477
"Error: Connected node not registered as connected:%T\n",
1003
erl_printf(to, "Name: ");
1004
display(dep->sysname, to);
1482
erts_print(to, arg, "Name: %T", dep->sysname);
1006
erl_printf(to," (refc=%d)", dep->refc);
1484
erts_print(to, arg, " (refc=%d)", erts_refc_read(&dep->refc, 1));
1008
erl_printf(to, "\n");
1486
erts_print(to, arg, "\n");
1009
1487
if (!connected && is_nil(dep->cid)) {
1011
erl_printf(to,"Error: Got links to not connected node:");
1012
display(dep->sysname, to);
1013
erl_printf(to, "\n");
1489
erts_print(to, arg, "Error: Got links to not connected node:%T\n",
1018
erl_printf(to, "Controller: ");
1019
display(dep->cid, to);
1020
erl_printf(to, "\n");
1022
erts_print_node_info(to, dep->sysname, NULL, NULL);
1024
if ((lnk = dep->links)) {
1028
if (is_internal_pid(lnk->item)) {
1029
if (pid2proc(lnk->item) == NULL)
1031
erl_printf (to, "Remote link: ");
1032
display(lnk->item,to);
1033
erl_printf (to, " ");
1034
display(lnk->data,to);
1038
if (is_external_pid(lnk->item)
1039
&& external_pid_dist_entry(lnk->item) != erts_this_dist_entry) {
1040
/* We are being monitored */
1041
if (pid2proc(lnk->data) == NULL)
1043
erl_printf(to, "Remotely monitored by: ");
1044
display(lnk->data,to);
1045
erl_printf (to, " ");
1046
display(lnk->item,to);
1048
/* We are monitoring */
1049
if (pid2proc(lnk->item) == NULL)
1051
erl_printf (to, "Remote monitoring: ");
1052
display(lnk->item,to);
1053
erl_printf (to, " ");
1054
if (is_not_atom(lnk->data)) {
1055
display(lnk->data, to);
1057
erl_printf (to,"{");
1058
display(lnk->data,to);
1059
erl_printf (to,", ");
1060
display(dep->sysname,to);
1061
erl_printf (to,"}");
1066
if (is_internal_pid(lnk->item)) {
1067
if (pid2proc(lnk->item) == NULL)
1069
erl_printf (to, "Remote monitoring: ");
1070
display(lnk->item,to);
1071
erl_printf (to, " ");
1072
display(dep->sysname,to);
1078
erl_printf (to, "Error: Bad remote link type (%d) found", lnk->type);
1080
erl_printf(to," \n");
1495
erts_print(to, arg, "Controller: %T\n", dep->cid, to);
1497
erts_print_node_info(to, arg, dep->sysname, NULL, NULL);
1498
print_monitor_info(to, arg, dep->monitors);
1499
print_link_info(to, arg, dep->nlinks);
1500
print_nodelink_info(to, arg, dep->node_links, dep->sysname);
1088
int distribution_info(CIO to) /* Called by break handler */
1505
int distribution_info(int to, void *arg) /* Called by break handler */
1090
1507
DistEntry *dep;
1092
erl_printf(to, "=node:");
1093
display(erts_this_dist_entry->sysname, to);
1094
erl_printf(to, "\n");
1509
erts_print(to, arg, "=node:%T\n", erts_this_dist_entry->sysname);
1096
1511
if (erts_this_node->sysname == am_Noname) {
1097
erl_printf(to, "=no_distribution\n");
1512
erts_print(to, arg, "=no_distribution\n");
1102
1517
if (!erts_visible_dist_entries && !erts_hidden_dist_entries)
1103
erl_printf(to,"Alive but not holding any connections \n");
1518
erts_print(to, arg, "Alive but not holding any connections \n");
1106
1521
for(dep = erts_visible_dist_entries; dep; dep = dep->next) {
1107
info_dist_entry(to, dep, 1, 1);
1522
info_dist_entry(to, arg, dep, 1, 1);
1110
1525
for(dep = erts_hidden_dist_entries; dep; dep = dep->next) {
1111
info_dist_entry(to, dep, 0, 1);
1526
info_dist_entry(to, arg, dep, 0, 1);
1114
1529
for (dep = erts_not_connected_dist_entries; dep; dep = dep->next) {
1115
info_dist_entry(to, dep, 0, 0);
1530
info_dist_entry(to, arg, dep, 0, 0);
1417
1860
/* Check that local is local */
1418
1861
if (is_internal_pid(local)) {
1420
if ((lp = pid2proc(local)) == NULL)
1421
BIF_RET(am_true); /* ignore */
1423
if ((lp->flags & F_TRAPEXIT) && (BIF_ARG_2 != am_kill))
1424
deliver_exit_message(remote, lp, exit_value);
1425
else if (BIF_ARG_2 != am_normal)
1426
schedule_exit(lp, exit_value);
1864
if (BIF_P->id == local) {
1865
lp_locks = ERTS_PROC_LOCKS_ALL;
1867
erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCKS_ALL_MINOR);
1870
lp_locks = ERTS_PROC_LOCKS_XSIG_SEND;
1871
lp = erts_pid2proc(BIF_P, ERTS_PROC_LOCK_MAIN, local, lp_locks);
1873
BIF_RET(am_true); /* ignore */
1428
if (BIF_P->status != P_RUNNING) {
1429
BIF_P->fvalue = exit_value;
1430
KILL_CATCHES(BIF_P);
1431
BIF_ERROR(BIF_P, USER_EXIT);
1877
(void) erts_send_exit_signal(BIF_P,
1887
* We may have exited current process and may have to take action.
1890
ERTS_SMP_BIF_CHK_PENDING_EXIT(BIF_P, lp_locks);
1891
lp_locks &= ~ERTS_PROC_LOCK_MAIN;
1893
ERTS_BIF_CHK_EXITED(BIF_P);
1896
erts_smp_proc_unlock(lp, lp_locks);
1434
1898
else if (is_internal_port(local)) {
1435
do_exit_port(local, remote, BIF_ARG_2);
1436
if (BIF_P->status != P_RUNNING) {
1437
BIF_P->fvalue = (BIF_ARG_2 == am_kill) ? am_killed : BIF_ARG_2;
1438
KILL_CATCHES(BIF_P);
1439
BIF_ERROR(BIF_P, USER_EXIT);
1899
erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN);
1900
erts_do_exit_port(local, remote, BIF_ARG_2);
1901
erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN);
1902
ERTS_BIF_CHK_EXITED(BIF_P);
1442
1904
else if ((is_external_pid(local) || is_external_port(local))
1443
1905
&& external_dist_entry(local) == erts_this_dist_entry) {
1665
2185
BIF_ERROR(BIF_P, BADARG);
1667
2187
if ((dep = erts_sysname_to_connected_dist_entry(BIF_ARG_1)) == NULL) {
1668
BIF_TRAP2(dmonitor_node_trap, BIF_P, BIF_ARG_1, BIF_ARG_2);
2188
BIF_TRAP3(dmonitor_node_trap, BIF_P, BIF_ARG_1, BIF_ARG_2, BIF_ARG_3);
1670
if (dep == erts_this_dist_entry)
2190
if (dep == erts_this_dist_entry)
2193
erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_LINK);
2194
erts_smp_dist_entry_lock(dep);
1672
2196
if (BIF_ARG_2 == am_true) {
1673
2197
ASSERT(dep->cid != NIL);
1674
dep->links = new_link(dep->links, LNK_NODE, BIF_P->id, NIL);
1676
BIF_P->links = new_link(BIF_P->links, LNK_NODE, BIF_ARG_1, NIL);
2198
lnk = erts_add_or_lookup_link(&(dep->node_links), LINK_NODE,
2200
++ERTS_LINK_ROOT_AS_UINT(lnk);
2201
lnk = erts_add_or_lookup_link(&(BIF_P->nlinks), LINK_NODE, BIF_ARG_1);
2202
++ERTS_LINK_ROOT_AS_UINT(lnk);
1680
del_link(find_link(&(dep->links), LNK_NODE, BIF_P->id,NIL));
1681
del_link(find_link(&(BIF_P->links), LNK_NODE, BIF_ARG_1, NIL));
2205
lnk = erts_lookup_link(dep->node_links, BIF_P->id);
2207
if ((--ERTS_LINK_ROOT_AS_UINT(lnk)) == 0) {
2208
erts_destroy_link(erts_remove_link(&(dep->node_links),
2212
lnk = erts_lookup_link(BIF_P->nlinks, BIF_ARG_1);
2214
if ((--ERTS_LINK_ROOT_AS_UINT(lnk)) == 0) {
2215
erts_destroy_link(erts_remove_link(&(BIF_P->nlinks),
2221
erts_smp_dist_entry_unlock(dep);
2222
erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_LINK);
2225
erts_deref_dist_entry(dep);
2229
/* monitor_node(Node, Bool) -> Bool */
2231
BIF_RETTYPE monitor_node_2(BIF_ALIST_2)
2233
BIF_RET(monitor_node_3(BIF_P,BIF_ARG_1,BIF_ARG_2,NIL));