@@ -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 }
@@ -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,8 @@ 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+ context_unalias (ctx , ref_ticks , true);
1084+
10561085 struct ListHead * item ;
10571086 LIST_FOR_EACH (item , & ctx -> monitors_head ) {
10581087 struct Monitor * monitor = GET_LIST_ENTRY (item , struct Monitor , monitor_list_head );
@@ -1086,11 +1115,46 @@ void context_demonitor(Context *ctx, uint64_t ref_ticks)
10861115 }
10871116 case CONTEXT_MONITOR_LINK_LOCAL :
10881117 case CONTEXT_MONITOR_LINK_REMOTE :
1118+ case CONTEXT_MONITOR_ALIAS :
10891119 break ;
10901120 }
10911121 }
10921122}
10931123
1124+ struct MonitorAlias * context_find_alias (Context * ctx , uint64_t ref_ticks )
1125+ {
1126+ struct ListHead * item ;
1127+ LIST_FOR_EACH (item , & ctx -> monitors_head ) {
1128+ struct Monitor * monitor = GET_LIST_ENTRY (item , struct Monitor , monitor_list_head );
1129+ if (monitor -> monitor_type == CONTEXT_MONITOR_ALIAS ) {
1130+ struct MonitorAlias * alias_monitor = CONTAINER_OF (monitor , struct MonitorAlias , monitor );
1131+ if (alias_monitor -> ref_ticks == ref_ticks ) {
1132+ return alias_monitor ;
1133+ }
1134+ }
1135+ }
1136+
1137+ return NULL ;
1138+ }
1139+
1140+ bool context_unalias (Context * ctx , uint64_t ref_ticks , bool from_demonitor )
1141+ {
1142+ struct MonitorAlias * alias_monitor = context_find_alias (ctx , ref_ticks );
1143+ if (IS_NULL_PTR (alias_monitor )) {
1144+ return false;
1145+ }
1146+
1147+ if (alias_monitor -> alias_type == CONTEXT_MONITOR_ALIAS_DEMONITOR
1148+ || (alias_monitor -> alias_type == CONTEXT_MONITOR_ALIAS_EXPLICIT_UNALIAS && !from_demonitor )) {
1149+ struct Monitor * monitor = & alias_monitor -> monitor ;
1150+ list_remove (& monitor -> monitor_list_head );
1151+ free (monitor );
1152+ return true;
1153+ } else {
1154+ return false;
1155+ }
1156+ }
1157+
10941158term context_get_monitor_pid (Context * ctx , uint64_t ref_ticks , bool * is_monitoring )
10951159{
10961160 struct ListHead * item ;
@@ -1117,6 +1181,7 @@ term context_get_monitor_pid(Context *ctx, uint64_t ref_ticks, bool *is_monitori
11171181 case CONTEXT_MONITOR_LINK_LOCAL :
11181182 case CONTEXT_MONITOR_LINK_REMOTE :
11191183 case CONTEXT_MONITOR_RESOURCE :
1184+ case CONTEXT_MONITOR_ALIAS :
11201185 break ;
11211186 }
11221187 }
@@ -1246,6 +1311,12 @@ COLD_FUNC void context_dump(Context *ctx)
12461311 fprintf (stderr , "\n" );
12471312 break ;
12481313 }
1314+ case CONTEXT_MONITOR_ALIAS : {
1315+ struct MonitorLocalMonitor * monitored_monitor = CONTAINER_OF (monitor , struct MonitorLocalMonitor , monitor );
1316+ fprintf (stderr , "has alias ref=%lu" , (long unsigned ) monitored_monitor -> ref_ticks );
1317+ fprintf (stderr , "\n" );
1318+ break ;
1319+ }
12491320 case CONTEXT_MONITOR_MONITORED_LOCAL : {
12501321 struct MonitorLocalMonitor * monitored_monitor = CONTAINER_OF (monitor , struct MonitorLocalMonitor , monitor );
12511322 fprintf (stderr , "monitored by " );
0 commit comments