|
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.
|
@@ -666,6 +687,18 @@ static struct Monitor *context_monitors_handle_terminate(Context *ctx)
|
666 | 687 | free(monitor);
|
667 | 688 | break;
|
668 | 689 | }
|
| 690 | + case CONTEXT_MONITOR_MONITORING_LOCAL_REGISTEREDNAME: { |
| 691 | + // We are the monitoring process. |
| 692 | + struct MonitorLocalRegisteredNameMonitor *monitoring_monitor = CONTAINER_OF(monitor, struct MonitorLocalRegisteredNameMonitor, monitor); |
| 693 | + int32_t local_process_id = monitoring_monitor->monitor_process_id; |
| 694 | + Context *target = globalcontext_get_process_nolock(glb, local_process_id); |
| 695 | + if (LIKELY(target != NULL)) { |
| 696 | + // target can be null if we didn't process a MonitorDownSignal |
| 697 | + mailbox_send_ref_signal(target, DemonitorSignal, monitoring_monitor->ref_ticks); |
| 698 | + } |
| 699 | + free(monitor); |
| 700 | + break; |
| 701 | + } |
669 | 702 | case CONTEXT_MONITOR_LINK_LOCAL: {
|
670 | 703 | struct LinkLocalMonitor *link_monitor = CONTAINER_OF(monitor, struct LinkLocalMonitor, monitor);
|
671 | 704 | // Handle the case of inactive link.
|
@@ -790,6 +823,20 @@ struct Monitor *monitor_new(term monitor_pid, uint64_t ref_ticks, bool is_monito
|
790 | 823 | return &monitor->monitor;
|
791 | 824 | }
|
792 | 825 |
|
| 826 | +struct Monitor *monitor_registeredname_monitor_new(int32_t monitor_process_id, term monitor_name, uint64_t ref_ticks) |
| 827 | +{ |
| 828 | + struct MonitorLocalRegisteredNameMonitor *monitor = malloc(sizeof(struct MonitorLocalRegisteredNameMonitor)); |
| 829 | + if (IS_NULL_PTR(monitor)) { |
| 830 | + return NULL; |
| 831 | + } |
| 832 | + monitor->monitor.monitor_type = CONTEXT_MONITOR_MONITORING_LOCAL_REGISTEREDNAME; |
| 833 | + monitor->monitor_process_id = monitor_process_id; |
| 834 | + monitor->monitor_name = monitor_name; |
| 835 | + monitor->ref_ticks = ref_ticks; |
| 836 | + |
| 837 | + return &monitor->monitor; |
| 838 | +} |
| 839 | + |
793 | 840 | struct Monitor *monitor_resource_monitor_new(void *resource, uint64_t ref_ticks)
|
794 | 841 | {
|
795 | 842 | struct ResourceContextMonitor *monitor = malloc(sizeof(struct ResourceContextMonitor));
|
@@ -829,6 +876,17 @@ bool context_add_monitor(Context *ctx, struct Monitor *new_monitor)
|
829 | 876 | }
|
830 | 877 | break;
|
831 | 878 | }
|
| 879 | + case CONTEXT_MONITOR_MONITORING_LOCAL_REGISTEREDNAME: { |
| 880 | + struct MonitorLocalRegisteredNameMonitor *new_local_registeredname_monitor = CONTAINER_OF(new_monitor, struct MonitorLocalRegisteredNameMonitor, monitor); |
| 881 | + struct MonitorLocalRegisteredNameMonitor *existing_local_registeredname_monitor = CONTAINER_OF(existing, struct MonitorLocalRegisteredNameMonitor, monitor); |
| 882 | + if (UNLIKELY(existing_local_registeredname_monitor->monitor_process_id == new_local_registeredname_monitor->monitor_process_id |
| 883 | + && existing_local_registeredname_monitor->monitor_name == new_local_registeredname_monitor->monitor_name |
| 884 | + && existing_local_registeredname_monitor->ref_ticks == new_local_registeredname_monitor->ref_ticks)) { |
| 885 | + free(new_monitor); |
| 886 | + return false; |
| 887 | + } |
| 888 | + break; |
| 889 | + } |
832 | 890 | case CONTEXT_MONITOR_RESOURCE: {
|
833 | 891 | struct ResourceContextMonitor *new_resource_monitor = CONTAINER_OF(new_monitor, struct ResourceContextMonitor, monitor);
|
834 | 892 | struct ResourceContextMonitor *existing_resource_monitor = CONTAINER_OF(existing, struct ResourceContextMonitor, monitor);
|
@@ -976,6 +1034,15 @@ void context_demonitor(Context *ctx, uint64_t ref_ticks)
|
976 | 1034 | }
|
977 | 1035 | break;
|
978 | 1036 | }
|
| 1037 | + case CONTEXT_MONITOR_MONITORING_LOCAL_REGISTEREDNAME: { |
| 1038 | + struct MonitorLocalRegisteredNameMonitor *local_registeredname_monitor = CONTAINER_OF(monitor, struct MonitorLocalRegisteredNameMonitor, monitor); |
| 1039 | + if (local_registeredname_monitor->ref_ticks == ref_ticks) { |
| 1040 | + list_remove(&monitor->monitor_list_head); |
| 1041 | + free(monitor); |
| 1042 | + return; |
| 1043 | + } |
| 1044 | + break; |
| 1045 | + } |
979 | 1046 | case CONTEXT_MONITOR_RESOURCE: {
|
980 | 1047 | struct ResourceContextMonitor *resource_monitor = CONTAINER_OF(monitor, struct ResourceContextMonitor, monitor);
|
981 | 1048 | if (resource_monitor->ref_ticks == ref_ticks) {
|
@@ -1006,6 +1073,14 @@ term context_get_monitor_pid(Context *ctx, uint64_t ref_ticks, bool *is_monitori
|
1006 | 1073 | }
|
1007 | 1074 | break;
|
1008 | 1075 | }
|
| 1076 | + case CONTEXT_MONITOR_MONITORING_LOCAL_REGISTEREDNAME: { |
| 1077 | + struct MonitorLocalRegisteredNameMonitor *local_registeredname_monitor = CONTAINER_OF(monitor, struct MonitorLocalRegisteredNameMonitor, monitor); |
| 1078 | + if (local_registeredname_monitor->ref_ticks == ref_ticks) { |
| 1079 | + *is_monitoring = true; |
| 1080 | + return term_from_local_process_id(local_registeredname_monitor->monitor_process_id); |
| 1081 | + } |
| 1082 | + break; |
| 1083 | + } |
1009 | 1084 | case CONTEXT_MONITOR_LINK_LOCAL:
|
1010 | 1085 | case CONTEXT_MONITOR_LINK_REMOTE:
|
1011 | 1086 | case CONTEXT_MONITOR_RESOURCE:
|
@@ -1146,6 +1221,16 @@ COLD_FUNC void context_dump(Context *ctx)
|
1146 | 1221 | fprintf(stderr, "\n");
|
1147 | 1222 | break;
|
1148 | 1223 | }
|
| 1224 | + case CONTEXT_MONITOR_MONITORING_LOCAL_REGISTEREDNAME: { |
| 1225 | + struct MonitorLocalRegisteredNameMonitor *local_registeredname_monitor = CONTAINER_OF(monitor, struct MonitorLocalRegisteredNameMonitor, monitor); |
| 1226 | + fprintf(stderr, "monitor to "); |
| 1227 | + term_display(stderr, local_registeredname_monitor->monitor_name, ctx); |
| 1228 | + fprintf(stderr, " ("); |
| 1229 | + term_display(stderr, term_from_local_process_id(local_registeredname_monitor->monitor_process_id), ctx); |
| 1230 | + fprintf(stderr, ") ref=%lu", (long unsigned) local_registeredname_monitor->ref_ticks); |
| 1231 | + fprintf(stderr, "\n"); |
| 1232 | + break; |
| 1233 | + } |
1149 | 1234 | case CONTEXT_MONITOR_RESOURCE: {
|
1150 | 1235 | struct ResourceContextMonitor *resource_monitor = CONTAINER_OF(monitor, struct ResourceContextMonitor, monitor);
|
1151 | 1236 | fprintf(stderr, "monitored by resource %p ref=%lu", resource_monitor->resource_obj, (long unsigned) resource_monitor->ref_ticks);
|
|
0 commit comments