-
Notifications
You must be signed in to change notification settings - Fork 144
Process aliases #2027
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Process aliases #2027
Changes from all commits
7384818
7fe1642
056bf5b
78111e1
18ff9e0
b6eaf36
af97dbd
8146397
d262e75
6a9730d
628ce83
8c5fd64
caa4fe2
eaf97a7
e971ccd
99d1040
250fb3a
18289cc
3ad27e3
8651323
1232635
d992def
3b126b0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -177,6 +177,14 @@ enum ContextMonitorType | |
| CONTEXT_MONITOR_RESOURCE, | ||
| CONTEXT_MONITOR_LINK_REMOTE, | ||
| CONTEXT_MONITOR_MONITORING_LOCAL_REGISTEREDNAME, | ||
| CONTEXT_MONITOR_ALIAS, | ||
| }; | ||
|
|
||
| enum ContextMonitorAliasType | ||
| { | ||
| ContextMonitorAliasExplicitUnalias, | ||
| ContextMonitorAliasDemonitor, | ||
| ContextMonitorAliasReplyDemonitor, | ||
| }; | ||
|
|
||
| #define UNLINK_ID_LINK_ACTIVE 0x0 | ||
|
|
@@ -200,18 +208,25 @@ struct LinkLocalMonitor | |
| struct MonitorLocalMonitor | ||
| { | ||
| struct Monitor monitor; | ||
| uint64_t ref_ticks; | ||
| RefData ref_data; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's use this as an example.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In this particular case, RefData is needed, because when making a term out of it, we need to know whether to create a process ref or a regular ref. If we need a process ref, then we also need a process id, which we now have in RefData, which is convenient, but we could probably keep a flag instead and get process_id from the context. Still, we'd have to keep a flag, so the savings would be marginal, if any. |
||
| term monitor_obj; | ||
| }; | ||
|
|
||
| struct MonitorLocalRegisteredNameMonitor | ||
| { | ||
| struct Monitor monitor; | ||
| uint64_t ref_ticks; | ||
| RefData ref_data; | ||
| int32_t monitor_process_id; | ||
| term monitor_name; | ||
| }; | ||
|
|
||
| struct MonitorAlias | ||
| { | ||
| struct Monitor monitor; | ||
| RefData ref_data; | ||
| enum ContextMonitorAliasType alias_type; | ||
| }; | ||
|
|
||
| // The other half is called ResourceMonitor and is a linked list of resources | ||
| struct ResourceContextMonitor | ||
| { | ||
|
|
@@ -511,21 +526,23 @@ struct Monitor *monitor_link_new(term link_pid); | |
| * @brief Create a monitor on a process. | ||
| * | ||
| * @param monitor_pid monitored process | ||
| * @param ref_ticks reference of the monitor | ||
| * @param ref_data reference of the monitor | ||
| * @param is_monitoring if ctx is the monitoring process | ||
| * @return the allocated monitor or NULL if allocation failed | ||
| */ | ||
| struct Monitor *monitor_new(term monitor_pid, uint64_t ref_ticks, bool is_monitoring); | ||
| struct Monitor *monitor_new(term monitor_pid, RefData *ref_data, bool is_monitoring); | ||
|
|
||
| struct Monitor *monitor_alias_new(RefData *ref_data, enum ContextMonitorAliasType alias_type); | ||
|
|
||
| /** | ||
| * @brief Create a monitor on a process by registered name. | ||
| * | ||
| * @param monitor_process_id monitored process id | ||
| * @param monitor_name name of the monitor (atom) | ||
| * @param ref_ticks reference of the monitor | ||
| * @param ref_data reference of the monitor | ||
| * @return the allocated monitor or NULL if allocation failed | ||
| */ | ||
| struct Monitor *monitor_registeredname_monitor_new(int32_t monitor_process_id, term monitor_name, uint64_t ref_ticks); | ||
| struct Monitor *monitor_registeredname_monitor_new(int32_t monitor_process_id, term monitor_name, RefData *ref_data); | ||
|
|
||
| /** | ||
| * @brief Create a resource monitor. | ||
|
|
@@ -582,6 +599,22 @@ void context_unlink_ack(Context *ctx, term link_pid, uint64_t unlink_id); | |
| */ | ||
| void context_demonitor(Context *ctx, uint64_t ref_ticks); | ||
|
|
||
| /** | ||
| * @brief Find a process alias | ||
| * | ||
| * @param ctx the context being executed | ||
| * @param ref_ticks reference of the alias to find | ||
| * @return found alias or NULL | ||
| */ | ||
| struct MonitorAlias *context_find_alias(Context *ctx, uint64_t ref_ticks); | ||
|
|
||
| /** | ||
| * @brief Remove an alias of a process | ||
| * | ||
| * @param alias The alias to remove, can be obtained using context_find_alias | ||
| */ | ||
| void context_unalias(struct MonitorAlias *alias); | ||
|
|
||
| /** | ||
| * @brief Get target of a monitor. | ||
| * | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -46,8 +46,6 @@ | |
| extern "C" { | ||
| #endif | ||
|
|
||
| #define INVALID_PROCESS_ID 0 | ||
|
|
||
| struct Context; | ||
|
|
||
| #ifndef TYPEDEF_CONTEXT | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -758,15 +758,16 @@ static bool jit_send(Context *ctx, JITState *jit_state) | |
| return false; | ||
| } | ||
| ctx->x[0] = return_value; | ||
| } else { | ||
| if (term_is_atom(recipient_term)) { | ||
| recipient_term = globalcontext_get_registered_process(ctx->global, term_to_atom_index(recipient_term)); | ||
| if (UNLIKELY(recipient_term == UNDEFINED_ATOM)) { | ||
| set_error(ctx, jit_state, 0, BADARG_ATOM); | ||
| return false; | ||
| } | ||
| } else if (term_is_local_pid_or_port(recipient_term)) { | ||
| int local_process_id = term_to_local_process_id(recipient_term); | ||
| globalcontext_send_message(ctx->global, local_process_id, ctx->x[1]); | ||
| ctx->x[0] = ctx->x[1]; | ||
| } else if (term_is_atom(recipient_term)) { | ||
| recipient_term = globalcontext_get_registered_process(ctx->global, term_to_atom_index(recipient_term)); | ||
| if (UNLIKELY(recipient_term == UNDEFINED_ATOM)) { | ||
| set_error(ctx, jit_state, 0, BADARG_ATOM); | ||
| return false; | ||
| } | ||
|
|
||
| int local_process_id; | ||
| if (term_is_local_pid_or_port(recipient_term)) { | ||
| local_process_id = term_to_local_process_id(recipient_term); | ||
|
|
@@ -776,7 +777,26 @@ static bool jit_send(Context *ctx, JITState *jit_state) | |
| } | ||
| globalcontext_send_message(ctx->global, local_process_id, ctx->x[1]); | ||
| ctx->x[0] = ctx->x[1]; | ||
| } else if (term_is_process_reference(recipient_term)) { | ||
| int32_t process_id = term_process_ref_to_process_id(recipient_term); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See my comment about duplicated code in opcodesswitch.h. |
||
| int64_t ref_ticks = term_to_ref_ticks(recipient_term); | ||
| Context *p = globalcontext_get_process_lock(ctx->global, process_id); | ||
| if (p) { | ||
| struct MonitorAlias *alias = context_find_alias(p, ref_ticks); | ||
| if (!IS_NULL_PTR(alias)) { | ||
| if (alias->alias_type == ContextMonitorAliasReplyDemonitor) { | ||
| context_unalias(alias); | ||
| } | ||
| mailbox_send(p, ctx->x[1]); | ||
| } | ||
| globalcontext_get_process_unlock(ctx->global, p); | ||
| } | ||
| ctx->x[0] = ctx->x[1]; | ||
| } else if (!term_is_reference(recipient_term)) { | ||
| set_error(ctx, jit_state, 0, BADARG_ATOM); | ||
| return false; | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
monitor can be also used with atoms or with tuples for processes on remote nodes.
I suggest introducing
monitor_process_identifier()as Erlang does.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is copy-pasted from the typespec above, I think it should be fixed in a separate PR