@@ -260,6 +260,7 @@ void context_destroy(Context *ctx)
260260 case CONTEXT_MONITOR_MONITORED_LOCAL :
261261 case CONTEXT_MONITOR_MONITORING_LOCAL :
262262 case CONTEXT_MONITOR_MONITORING_LOCAL_REGISTEREDNAME :
263+ case CONTEXT_MONITOR_ALIAS :
263264 UNREACHABLE ();
264265 }
265266 }
@@ -774,15 +775,15 @@ static struct Monitor *context_monitors_handle_terminate(Context *ctx)
774775 Context * target = globalcontext_get_process_nolock (glb , local_process_id );
775776 // Target cannot be NULL as we processed Demonitor signals
776777 assert (target != NULL );
777- int required_terms = REF_SIZE + TUPLE_SIZE (5 );
778+ int required_terms = TERM_BOXED_PROCESS_REF_SIZE + TUPLE_SIZE (5 );
778779 if (UNLIKELY (memory_ensure_free (ctx , required_terms ) != MEMORY_GC_OK )) {
779780 // TODO: handle out of memory here
780781 fprintf (stderr , "Cannot handle out of memory.\n" );
781782 globalcontext_get_process_unlock (glb , target );
782783 AVM_ABORT ();
783784 }
784785 // Prepare the message on ctx's heap which will be freed afterwards.
785- term ref = term_from_ref_ticks ( monitored_monitor -> ref_ticks , & ctx -> heap );
786+ term ref = term_make_process_reference ( target -> process_id , monitored_monitor -> ref_ticks , & ctx -> heap );
786787
787788 term port_or_process = term_pid_or_port_from_context (ctx );
788789 term port_or_process_atom
@@ -799,6 +800,9 @@ static struct Monitor *context_monitors_handle_terminate(Context *ctx)
799800 free (monitor );
800801 break ;
801802 }
803+ case CONTEXT_MONITOR_ALIAS : {
804+ free (monitor );
805+ }
802806 }
803807 }
804808 return result ;
@@ -869,6 +873,19 @@ struct Monitor *monitor_registeredname_monitor_new(int32_t monitor_process_id, t
869873 return & monitor -> monitor ;
870874}
871875
876+ struct Monitor * monitor_alias_new (uint64_t ref_ticks , enum ContextMonitorAliasType alias_type )
877+ {
878+ struct MonitorAlias * monitor = malloc (sizeof (struct MonitorAlias ));
879+ if (IS_NULL_PTR (monitor )) {
880+ return NULL ;
881+ }
882+ monitor -> monitor .monitor_type = CONTEXT_MONITOR_ALIAS ;
883+ monitor -> ref_ticks = ref_ticks ;
884+ monitor -> alias_type = alias_type ;
885+
886+ return & monitor -> monitor ;
887+ }
888+
872889struct Monitor * monitor_resource_monitor_new (void * resource , uint64_t ref_ticks )
873890{
874891 struct ResourceContextMonitor * monitor = malloc (sizeof (struct ResourceContextMonitor ));
@@ -920,6 +937,16 @@ bool context_add_monitor(Context *ctx, struct Monitor *new_monitor)
920937 }
921938 break ;
922939 }
940+ case CONTEXT_MONITOR_ALIAS : {
941+ struct MonitorAlias * new_alias_monitor = CONTAINER_OF (new_monitor , struct MonitorAlias , monitor );
942+ struct MonitorAlias * existing_alias_monitor = CONTAINER_OF (existing , struct MonitorAlias , monitor );
943+
944+ if (UNLIKELY (existing_alias_monitor -> alias_type == new_alias_monitor -> alias_type && existing_alias_monitor -> ref_ticks == new_alias_monitor -> ref_ticks )) {
945+ free (new_monitor );
946+ return false;
947+ }
948+ break ;
949+ }
923950 case CONTEXT_MONITOR_RESOURCE : {
924951 struct ResourceContextMonitor * new_resource_monitor = CONTAINER_OF (new_monitor , struct ResourceContextMonitor , monitor );
925952 struct ResourceContextMonitor * existing_resource_monitor = CONTAINER_OF (existing , struct ResourceContextMonitor , monitor );
@@ -1053,6 +1080,11 @@ void context_unlink_ack(Context *ctx, term link_pid, uint64_t unlink_id)
10531080
10541081void context_demonitor (Context * ctx , uint64_t ref_ticks )
10551082{
1083+ struct MonitorAlias * alias = context_find_alias (ctx , ref_ticks );
1084+ if (alias != NULL && alias -> alias_type != ContextMonitorAliasExplicitUnalias ) {
1085+ context_unalias (alias );
1086+ }
1087+
10561088 struct ListHead * item ;
10571089 LIST_FOR_EACH (item , & ctx -> monitors_head ) {
10581090 struct Monitor * monitor = GET_LIST_ENTRY (item , struct Monitor , monitor_list_head );
@@ -1086,11 +1118,36 @@ void context_demonitor(Context *ctx, uint64_t ref_ticks)
10861118 }
10871119 case CONTEXT_MONITOR_LINK_LOCAL :
10881120 case CONTEXT_MONITOR_LINK_REMOTE :
1121+ case CONTEXT_MONITOR_ALIAS :
10891122 break ;
10901123 }
10911124 }
10921125}
10931126
1127+ struct MonitorAlias * context_find_alias (Context * ctx , uint64_t ref_ticks )
1128+ {
1129+ struct ListHead * item ;
1130+ LIST_FOR_EACH (item , & ctx -> monitors_head ) {
1131+ struct Monitor * monitor = GET_LIST_ENTRY (item , struct Monitor , monitor_list_head );
1132+ if (monitor -> monitor_type == CONTEXT_MONITOR_ALIAS ) {
1133+ struct MonitorAlias * alias_monitor = CONTAINER_OF (monitor , struct MonitorAlias , monitor );
1134+ if (alias_monitor -> ref_ticks == ref_ticks ) {
1135+ return alias_monitor ;
1136+ }
1137+ }
1138+ }
1139+
1140+ return NULL ;
1141+ }
1142+
1143+ void context_unalias (struct MonitorAlias * alias )
1144+ {
1145+ TERM_DEBUG_ASSERT (alias != NULL );
1146+ struct Monitor * monitor = & alias -> monitor ;
1147+ list_remove (& monitor -> monitor_list_head );
1148+ free (monitor );
1149+ }
1150+
10941151term context_get_monitor_pid (Context * ctx , uint64_t ref_ticks , bool * is_monitoring )
10951152{
10961153 struct ListHead * item ;
@@ -1117,6 +1174,7 @@ term context_get_monitor_pid(Context *ctx, uint64_t ref_ticks, bool *is_monitori
11171174 case CONTEXT_MONITOR_LINK_LOCAL :
11181175 case CONTEXT_MONITOR_LINK_REMOTE :
11191176 case CONTEXT_MONITOR_RESOURCE :
1177+ case CONTEXT_MONITOR_ALIAS :
11201178 break ;
11211179 }
11221180 }
@@ -1246,6 +1304,12 @@ COLD_FUNC void context_dump(Context *ctx)
12461304 fprintf (stderr , "\n" );
12471305 break ;
12481306 }
1307+ case CONTEXT_MONITOR_ALIAS : {
1308+ struct MonitorLocalMonitor * monitored_monitor = CONTAINER_OF (monitor , struct MonitorLocalMonitor , monitor );
1309+ fprintf (stderr , "has alias ref=%lu" , (long unsigned ) monitored_monitor -> ref_ticks );
1310+ fprintf (stderr , "\n" );
1311+ break ;
1312+ }
12491313 case CONTEXT_MONITOR_MONITORED_LOCAL : {
12501314 struct MonitorLocalMonitor * monitored_monitor = CONTAINER_OF (monitor , struct MonitorLocalMonitor , monitor );
12511315 fprintf (stderr , "monitored by " );
0 commit comments