|
30 | 30 | #include "globalcontext.h"
|
31 | 31 | #include "list.h"
|
32 | 32 | #include "mailbox.h"
|
| 33 | +#include "memory.h" |
33 | 34 | #include "smp.h"
|
34 | 35 | #include "synclist.h"
|
35 | 36 | #include "sys.h"
|
@@ -252,6 +253,7 @@ void context_destroy(Context *ctx)
|
252 | 253 | case CONTEXT_MONITOR_LINK_LOCAL:
|
253 | 254 | case CONTEXT_MONITOR_MONITORED_LOCAL:
|
254 | 255 | case CONTEXT_MONITOR_MONITORING_LOCAL:
|
| 256 | + case CONTEXT_MONITOR_MONITORING_LOCAL_REGISTEREDNAME: |
255 | 257 | UNREACHABLE();
|
256 | 258 | }
|
257 | 259 | }
|
@@ -418,15 +420,34 @@ void context_process_monitor_down_signal(Context *ctx, struct TermSignal *signal
|
418 | 420 | LIST_FOR_EACH (item, &ctx->monitors_head) {
|
419 | 421 | struct Monitor *monitor = GET_LIST_ENTRY(item, struct Monitor, monitor_list_head);
|
420 | 422 | if (monitor->monitor_type == CONTEXT_MONITOR_MONITORING_LOCAL) {
|
421 |
| - struct MonitorLocalMonitor *monitored_monitor = CONTAINER_OF(monitor, struct MonitorLocalMonitor, monitor); |
422 |
| - if (monitored_monitor->monitor_obj == monitor_obj && monitored_monitor->ref_ticks == ref_ticks) { |
| 423 | + struct MonitorLocalMonitor *monitoring_monitor = CONTAINER_OF(monitor, struct MonitorLocalMonitor, monitor); |
| 424 | + if (monitoring_monitor->monitor_obj == monitor_obj && monitoring_monitor->ref_ticks == ref_ticks) { |
423 | 425 | // Remove link
|
424 | 426 | list_remove(&monitor->monitor_list_head);
|
425 | 427 | free(monitor);
|
426 | 428 | // Enqueue the term as a message.
|
427 | 429 | mailbox_send(ctx, signal->signal_term);
|
428 | 430 | break;
|
429 | 431 | }
|
| 432 | + } else if (monitor->monitor_type == CONTEXT_MONITOR_MONITORING_LOCAL_REGISTEREDNAME) { |
| 433 | + int32_t monitor_process_id = term_to_local_process_id(monitor_obj); |
| 434 | + struct MonitorLocalRegisteredNameMonitor *monitoring_monitor = CONTAINER_OF(monitor, struct MonitorLocalRegisteredNameMonitor, monitor); |
| 435 | + if (monitoring_monitor->monitor_process_id == monitor_process_id && monitoring_monitor->ref_ticks == ref_ticks) { |
| 436 | + // Remove link |
| 437 | + list_remove(&monitor->monitor_list_head); |
| 438 | + |
| 439 | + // We need to modify the monitor_obj item |
| 440 | + BEGIN_WITH_STACK_HEAP(TUPLE_SIZE(2), temp_heap) |
| 441 | + term name_tuple = term_alloc_tuple(2, &temp_heap); |
| 442 | + term_put_tuple_element(name_tuple, 0, monitoring_monitor->monitor_name); |
| 443 | + term_put_tuple_element(name_tuple, 1, ctx->global->node_name); |
| 444 | + term_put_tuple_element(signal->signal_term, 3, name_tuple); |
| 445 | + mailbox_send(ctx, signal->signal_term); |
| 446 | + END_WITH_STACK_HEAP(temp_heap, ctx->global); |
| 447 | + |
| 448 | + free(monitor); |
| 449 | + break; |
| 450 | + } |
430 | 451 | }
|
431 | 452 | }
|
432 | 453 | // If monitor was not found, it was removed and message should not be sent.
|
@@ -623,6 +644,18 @@ static struct Monitor *context_monitors_handle_terminate(Context *ctx)
|
623 | 644 | free(monitor);
|
624 | 645 | break;
|
625 | 646 | }
|
| 647 | + case CONTEXT_MONITOR_MONITORING_LOCAL_REGISTEREDNAME: { |
| 648 | + // We are the monitoring process. |
| 649 | + struct MonitorLocalRegisteredNameMonitor *monitoring_monitor = CONTAINER_OF(monitor, struct MonitorLocalRegisteredNameMonitor, monitor); |
| 650 | + int32_t local_process_id = monitoring_monitor->monitor_process_id; |
| 651 | + Context *target = globalcontext_get_process_nolock(glb, local_process_id); |
| 652 | + if (LIKELY(target != NULL)) { |
| 653 | + // target can be null if we didn't process a MonitorDownSignal |
| 654 | + mailbox_send_ref_signal(target, DemonitorSignal, monitoring_monitor->ref_ticks); |
| 655 | + } |
| 656 | + free(monitor); |
| 657 | + break; |
| 658 | + } |
626 | 659 | case CONTEXT_MONITOR_LINK_LOCAL: {
|
627 | 660 | struct LinkLocalMonitor *link_monitor = CONTAINER_OF(monitor, struct LinkLocalMonitor, monitor);
|
628 | 661 | // Handle the case of inactive link.
|
@@ -747,6 +780,20 @@ struct Monitor *monitor_new(term monitor_pid, uint64_t ref_ticks, bool is_monito
|
747 | 780 | return &monitor->monitor;
|
748 | 781 | }
|
749 | 782 |
|
| 783 | +struct Monitor *monitor_registeredname_monitor_new(int32_t monitor_process_id, term monitor_name, uint64_t ref_ticks) |
| 784 | +{ |
| 785 | + struct MonitorLocalRegisteredNameMonitor *monitor = malloc(sizeof(struct MonitorLocalRegisteredNameMonitor)); |
| 786 | + if (IS_NULL_PTR(monitor)) { |
| 787 | + return NULL; |
| 788 | + } |
| 789 | + monitor->monitor.monitor_type = CONTEXT_MONITOR_MONITORING_LOCAL_REGISTEREDNAME; |
| 790 | + monitor->monitor_process_id = monitor_process_id; |
| 791 | + monitor->monitor_name = monitor_name; |
| 792 | + monitor->ref_ticks = ref_ticks; |
| 793 | + |
| 794 | + return &monitor->monitor; |
| 795 | +} |
| 796 | + |
750 | 797 | struct Monitor *monitor_resource_monitor_new(void *resource, uint64_t ref_ticks)
|
751 | 798 | {
|
752 | 799 | struct ResourceContextMonitor *monitor = malloc(sizeof(struct ResourceContextMonitor));
|
@@ -786,6 +833,17 @@ bool context_add_monitor(Context *ctx, struct Monitor *new_monitor)
|
786 | 833 | }
|
787 | 834 | break;
|
788 | 835 | }
|
| 836 | + case CONTEXT_MONITOR_MONITORING_LOCAL_REGISTEREDNAME: { |
| 837 | + struct MonitorLocalRegisteredNameMonitor *new_local_registeredname_monitor = CONTAINER_OF(new_monitor, struct MonitorLocalRegisteredNameMonitor, monitor); |
| 838 | + struct MonitorLocalRegisteredNameMonitor *existing_local_registeredname_monitor = CONTAINER_OF(existing, struct MonitorLocalRegisteredNameMonitor, monitor); |
| 839 | + if (UNLIKELY(existing_local_registeredname_monitor->monitor_process_id == new_local_registeredname_monitor->monitor_process_id |
| 840 | + && existing_local_registeredname_monitor->monitor_name == new_local_registeredname_monitor->monitor_name |
| 841 | + && existing_local_registeredname_monitor->ref_ticks == new_local_registeredname_monitor->ref_ticks)) { |
| 842 | + free(new_monitor); |
| 843 | + return false; |
| 844 | + } |
| 845 | + break; |
| 846 | + } |
789 | 847 | case CONTEXT_MONITOR_RESOURCE: {
|
790 | 848 | struct ResourceContextMonitor *new_resource_monitor = CONTAINER_OF(new_monitor, struct ResourceContextMonitor, monitor);
|
791 | 849 | struct ResourceContextMonitor *existing_resource_monitor = CONTAINER_OF(existing, struct ResourceContextMonitor, monitor);
|
@@ -933,6 +991,15 @@ void context_demonitor(Context *ctx, uint64_t ref_ticks)
|
933 | 991 | }
|
934 | 992 | break;
|
935 | 993 | }
|
| 994 | + case CONTEXT_MONITOR_MONITORING_LOCAL_REGISTEREDNAME: { |
| 995 | + struct MonitorLocalRegisteredNameMonitor *local_registeredname_monitor = CONTAINER_OF(monitor, struct MonitorLocalRegisteredNameMonitor, monitor); |
| 996 | + if (local_registeredname_monitor->ref_ticks == ref_ticks) { |
| 997 | + list_remove(&monitor->monitor_list_head); |
| 998 | + free(monitor); |
| 999 | + return; |
| 1000 | + } |
| 1001 | + break; |
| 1002 | + } |
936 | 1003 | case CONTEXT_MONITOR_RESOURCE: {
|
937 | 1004 | struct ResourceContextMonitor *resource_monitor = CONTAINER_OF(monitor, struct ResourceContextMonitor, monitor);
|
938 | 1005 | if (resource_monitor->ref_ticks == ref_ticks) {
|
@@ -963,6 +1030,14 @@ term context_get_monitor_pid(Context *ctx, uint64_t ref_ticks, bool *is_monitori
|
963 | 1030 | }
|
964 | 1031 | break;
|
965 | 1032 | }
|
| 1033 | + case CONTEXT_MONITOR_MONITORING_LOCAL_REGISTEREDNAME: { |
| 1034 | + struct MonitorLocalRegisteredNameMonitor *local_registeredname_monitor = CONTAINER_OF(monitor, struct MonitorLocalRegisteredNameMonitor, monitor); |
| 1035 | + if (local_registeredname_monitor->ref_ticks == ref_ticks) { |
| 1036 | + *is_monitoring = true; |
| 1037 | + return term_from_local_process_id(local_registeredname_monitor->monitor_process_id); |
| 1038 | + } |
| 1039 | + break; |
| 1040 | + } |
966 | 1041 | case CONTEXT_MONITOR_LINK_LOCAL:
|
967 | 1042 | case CONTEXT_MONITOR_LINK_REMOTE:
|
968 | 1043 | case CONTEXT_MONITOR_RESOURCE:
|
@@ -1103,6 +1178,16 @@ COLD_FUNC void context_dump(Context *ctx)
|
1103 | 1178 | fprintf(stderr, "\n");
|
1104 | 1179 | break;
|
1105 | 1180 | }
|
| 1181 | + case CONTEXT_MONITOR_MONITORING_LOCAL_REGISTEREDNAME: { |
| 1182 | + struct MonitorLocalRegisteredNameMonitor *local_registeredname_monitor = CONTAINER_OF(monitor, struct MonitorLocalRegisteredNameMonitor, monitor); |
| 1183 | + fprintf(stderr, "monitor to "); |
| 1184 | + term_display(stderr, local_registeredname_monitor->monitor_name, ctx); |
| 1185 | + fprintf(stderr, " ("); |
| 1186 | + term_display(stderr, term_from_local_process_id(local_registeredname_monitor->monitor_process_id), ctx); |
| 1187 | + fprintf(stderr, ") ref=%lu", (long unsigned) local_registeredname_monitor->ref_ticks); |
| 1188 | + fprintf(stderr, "\n"); |
| 1189 | + break; |
| 1190 | + } |
1106 | 1191 | case CONTEXT_MONITOR_RESOURCE: {
|
1107 | 1192 | struct ResourceContextMonitor *resource_monitor = CONTAINER_OF(monitor, struct ResourceContextMonitor, monitor);
|
1108 | 1193 | fprintf(stderr, "monitored by resource %p ref=%lu", resource_monitor->resource_obj, (long unsigned) resource_monitor->ref_ticks);
|
|
0 commit comments