resources.c

Include dependency graph for resources.c:

digraph {
    graph [bgcolor="#00000000"]
    node [shape=rectangle style=filled fillcolor="#FFFFFF" font=Helvetica padding=2]
    edge [color="#1414CE"]
    "2" [label="stdbool.h" tooltip="stdbool.h"]
    "8" [label="atom.h" tooltip="atom.h"]
    "12" [label="assert.h" tooltip="assert.h"]
    "21" [label="synclist.h" tooltip="synclist.h"]
    "27" [label="defaultatoms.h" tooltip="defaultatoms.h"]
    "7" [label="stdint.h" tooltip="stdint.h"]
    "3" [label="stdlib.h" tooltip="stdlib.h"]
    "33" [label="valueshashtable.h" tooltip="valueshashtable.h"]
    "32" [label="exportedfunction.h" tooltip="exportedfunction.h"]
    "5" [label="context.h" tooltip="context.h"]
    "17" [label="utils.h" tooltip="utils.h"]
    "9" [label="atom_table.h" tooltip="atom_table.h"]
    "11" [label="term_typedef.h" tooltip="term_typedef.h"]
    "18" [label="stddef.h" tooltip="stddef.h"]
    "13" [label="limits.h" tooltip="limits.h"]
    "24" [label="refc_binary.h" tooltip="refc_binary.h"]
    "4" [label="string.h" tooltip="string.h"]
    "16" [label="mailbox.h" tooltip="mailbox.h"]
    "30" [label="module.h" tooltip="module.h"]
    "22" [label="term.h" tooltip="term.h"]
    "10" [label="erl_nif.h" tooltip="erl_nif.h"]
    "34" [label="time.h" tooltip="time.h"]
    "1" [label="/home/runner/work/AtomVM/AtomVM/src/libAtomVM/resources.c" tooltip="/home/runner/work/AtomVM/AtomVM/src/libAtomVM/resources.c" fillcolor="#BFBFBF"]
    "25" [label="resources.h" tooltip="resources.h"]
    "20" [label="smp.h" tooltip="smp.h"]
    "28" [label="erl_nif_priv.h" tooltip="erl_nif_priv.h"]
    "29" [label="sys.h" tooltip="sys.h"]
    "31" [label="atomshashtable.h" tooltip="atomshashtable.h"]
    "6" [label="globalcontext.h" tooltip="globalcontext.h"]
    "23" [label="memory.h" tooltip="memory.h"]
    "19" [label="stdio.h" tooltip="stdio.h"]
    "26" [label="timer_list.h" tooltip="timer_list.h"]
    "15" [label="list.h" tooltip="list.h"]
    "14" [label="inttypes.h" tooltip="inttypes.h"]
    "8" -> "7" [dir=forward tooltip="include"]
    "8" -> "3" [dir=forward tooltip="include"]
    "21" -> "19" [dir=forward tooltip="include"]
    "21" -> "15" [dir=forward tooltip="include"]
    "21" -> "20" [dir=forward tooltip="include"]
    "27" -> "6" [dir=forward tooltip="include"]
    "32" -> "22" [dir=forward tooltip="include"]
    "5" -> "6" [dir=forward tooltip="include"]
    "5" -> "15" [dir=forward tooltip="include"]
    "5" -> "16" [dir=forward tooltip="include"]
    "5" -> "20" [dir=forward tooltip="include"]
    "5" -> "22" [dir=forward tooltip="include"]
    "5" -> "26" [dir=forward tooltip="include"]
    "17" -> "18" [dir=forward tooltip="include"]
    "17" -> "19" [dir=forward tooltip="include"]
    "17" -> "3" [dir=forward tooltip="include"]
    "9" -> "2" [dir=forward tooltip="include"]
    "9" -> "8" [dir=forward tooltip="include"]
    "11" -> "12" [dir=forward tooltip="include"]
    "11" -> "13" [dir=forward tooltip="include"]
    "11" -> "14" [dir=forward tooltip="include"]
    "11" -> "7" [dir=forward tooltip="include"]
    "24" -> "2" [dir=forward tooltip="include"]
    "24" -> "3" [dir=forward tooltip="include"]
    "24" -> "15" [dir=forward tooltip="include"]
    "24" -> "25" [dir=forward tooltip="include"]
    "16" -> "2" [dir=forward tooltip="include"]
    "16" -> "15" [dir=forward tooltip="include"]
    "16" -> "11" [dir=forward tooltip="include"]
    "16" -> "17" [dir=forward tooltip="include"]
    "30" -> "2" [dir=forward tooltip="include"]
    "30" -> "7" [dir=forward tooltip="include"]
    "30" -> "8" [dir=forward tooltip="include"]
    "30" -> "9" [dir=forward tooltip="include"]
    "30" -> "31" [dir=forward tooltip="include"]
    "30" -> "5" [dir=forward tooltip="include"]
    "30" -> "32" [dir=forward tooltip="include"]
    "30" -> "6" [dir=forward tooltip="include"]
    "30" -> "22" [dir=forward tooltip="include"]
    "30" -> "33" [dir=forward tooltip="include"]
    "22" -> "2" [dir=forward tooltip="include"]
    "22" -> "7" [dir=forward tooltip="include"]
    "22" -> "19" [dir=forward tooltip="include"]
    "22" -> "3" [dir=forward tooltip="include"]
    "22" -> "4" [dir=forward tooltip="include"]
    "22" -> "23" [dir=forward tooltip="include"]
    "22" -> "24" [dir=forward tooltip="include"]
    "22" -> "17" [dir=forward tooltip="include"]
    "22" -> "11" [dir=forward tooltip="include"]
    "10" -> "11" [dir=forward tooltip="include"]
    "1" -> "2" [dir=forward tooltip="include"]
    "1" -> "3" [dir=forward tooltip="include"]
    "1" -> "4" [dir=forward tooltip="include"]
    "1" -> "5" [dir=forward tooltip="include"]
    "1" -> "27" [dir=forward tooltip="include"]
    "1" -> "10" [dir=forward tooltip="include"]
    "1" -> "28" [dir=forward tooltip="include"]
    "1" -> "24" [dir=forward tooltip="include"]
    "1" -> "25" [dir=forward tooltip="include"]
    "1" -> "29" [dir=forward tooltip="include"]
    "1" -> "17" [dir=forward tooltip="include"]
    "25" -> "3" [dir=forward tooltip="include"]
    "25" -> "10" [dir=forward tooltip="include"]
    "25" -> "15" [dir=forward tooltip="include"]
    "25" -> "23" [dir=forward tooltip="include"]
    "20" -> "2" [dir=forward tooltip="include"]
    "28" -> "5" [dir=forward tooltip="include"]
    "28" -> "23" [dir=forward tooltip="include"]
    "29" -> "6" [dir=forward tooltip="include"]
    "29" -> "30" [dir=forward tooltip="include"]
    "29" -> "7" [dir=forward tooltip="include"]
    "29" -> "34" [dir=forward tooltip="include"]
    "31" -> "8" [dir=forward tooltip="include"]
    "6" -> "7" [dir=forward tooltip="include"]
    "6" -> "8" [dir=forward tooltip="include"]
    "6" -> "9" [dir=forward tooltip="include"]
    "6" -> "10" [dir=forward tooltip="include"]
    "6" -> "15" [dir=forward tooltip="include"]
    "6" -> "16" [dir=forward tooltip="include"]
    "6" -> "20" [dir=forward tooltip="include"]
    "6" -> "21" [dir=forward tooltip="include"]
    "6" -> "22" [dir=forward tooltip="include"]
    "6" -> "26" [dir=forward tooltip="include"]
    "23" -> "7" [dir=forward tooltip="include"]
    "23" -> "3" [dir=forward tooltip="include"]
    "23" -> "10" [dir=forward tooltip="include"]
    "23" -> "11" [dir=forward tooltip="include"]
    "23" -> "17" [dir=forward tooltip="include"]
    "26" -> "2" [dir=forward tooltip="include"]
    "26" -> "7" [dir=forward tooltip="include"]
    "26" -> "15" [dir=forward tooltip="include"]
}

Functions

ErlNifResourceType *enif_init_resource_type(ErlNifEnv *env, const char *name, const ErlNifResourceTypeInit *init, ErlNifResourceFlags flags, ErlNifResourceFlags *tried)

Create or take over (code upgrade) a resource type.

Parameters:
  • env – the current environment

  • init – a structure describing the callbacks. Callbacks can be NULL if not used.

  • name – name of the resource (copied)

  • flagsERL_NIF_RT_CREATE or ERL_NIF_RT_TAKEOVER to create or take over.

  • tried – on output, updated to ERL_NIF_RT_CREATE or ERL_NIF_RT_TAKEOVER depending on what has been done. On failure, updated to flags. Can be NULL.

Returns:

the resource type or NULL on failure.

void *enif_alloc_resource(ErlNifResourceType *type, unsigned size)

Allocate a resource for given type for size bytes.

Parameters:
  • type – a trype created by enif_init_resource_type.

  • size – the size in bytes.

Returns:

a pointer or NULL on failure.

int enif_get_resource(ErlNifEnv *env, ERL_NIF_TERM t, ErlNifResourceType *type, void **objp)

Get a pointer to a resource from a term representing it.

Parameters:
  • env – the current environment

  • t – the term

  • type – the resource type

  • objp – on output the pointer to the resource

Returns:

true on success, false on failure, if term is not a resource of type type

int enif_keep_resource(void *resource)

Increment reference count of a resource.

Parameters:
  • resource – the resource to keep

Returns:

true.

int enif_release_resource(void *resource)

Decrement reference count of a resource.

Parameters:
  • resource – the resource to release

Returns:

true.

ERL_NIF_TERM enif_make_resource(ErlNifEnv *env, void *obj)

create a term from a resource

the term can be later passed to enif_get_resource. The resource is typically released (by calling enif_release_resource) just after calling this function to “transfer ownership” to Erlang code so that it will be destroyed when garbage collected.

Parameters:
  • env – current environment

  • obj – resource

Returns:

a new term representing the resource

int enif_select(ErlNifEnv *env, ErlNifEvent event, enum ErlNifSelectFlags mode, void *obj, const ErlNifPid *pid, ERL_NIF_TERM ref)

Run a POSIX-like select on a given object (event) and send a message when the object is readable or writable.

Actual implementation is platform dependent and platforms may not implement this feature.

On generic_unix, this is currently implemented using what sys_poll_events uses, namely kqueue(2) (if available) or poll(2). Please note that kqueue(2) and poll(2) behave differently for some objects, for example for vnodes and EOF.

On esp32, this is currently implemented using poll(2).

Parameters:
  • env – current environment

  • event – event object (typically a file descriptor)

  • mode – select mode (ERL_NIF_SELECT_READ and/or ERL_NIF_SELECT_WRITE) optionally with ERL_NIF_SELECT_CANCEL to cancel, or ERL_NIF_SELECT_STOP to stop.

  • obj – resource object working as a container of the event object.

  • pid – process id to send a message to or NULL to use the current process (from env)

  • ref – reference object used in sent messages or undefined atom.

Returns:

a negative value on failure, 0 or flags on success.

term select_event_make_notification(void *rsrc_obj, uint64_t ref_ticks, bool is_write, Heap *heap)

Build a select event notification.

Parameters:
  • rsrc_obj – the resource to build the notification for

  • ref_ticks – the reference or 0 if it’s undefined

  • is_write – if the notification is for a write or a read

  • heap – the heap to create the notification in, should have enough memory available (see SELECT_EVENT_NOTIFICATION_SIZE)

static void select_event_send_notification(struct SelectEvent *select_event, bool is_write, GlobalContext *global)
bool select_event_notify(ErlNifEvent event, bool is_read, bool is_write, GlobalContext *global)

Send a notification that an event was selected.

This function is called from sys_poll_events platform function if a select event was selected and the read or write flag was set. It modifies the select_event object so the notification is only sent once.

The function can also be called from a select task loop if AVM_SELECT_IN_TASK is defined.

It is not an error to call this function with an event that is not in the list.

This function calls sys_unregister_select_event.

Parameters:
  • event – the event to notify

  • is_read – if the event was selected for reading

  • is_write – if the event was selected for writing

  • global – the global context

Returns:

true if the event was found

static inline void select_event_destroy(struct SelectEvent *select_event, GlobalContext *global)
void select_event_count_and_destroy_closed(struct ListHead *select_events, size_t *read, size_t *write, size_t *either, GlobalContext *global)

Count events available for reading and/or writing and destroy the events marked for close.

Convenience function that can be called by sys_poll_events and iterates on events to be closed and count them.

The function can also be called from a select task loop if AVM_SELECT_IN_TASK is defined.

Parameters:
  • select_events – list of events, with a write lock

  • read – on output number of events with read = 1, can be NULL

  • write – on output number of events with write = 1, can be NULL

  • either – on output number of events with either read = 1 or write = 1, can be NULL

  • global – the global context

int enif_monitor_process(ErlNifEnv *env, void *obj, const ErlNifPid *target_pid, ErlNifMonitor *mon)

Monitor a process by using a resource object.

The monitor is automatically removed after being triggered or if the associated resource is deallocated.

Parameters:
  • env – current environment

  • obj – resource to use for monitor

  • target_pid – process to monitor

  • mon – on output, monitor object (can be NULL)

Returns:

0 on success, <0 if no down callback is provided with resource (badarg), >0 if the process is no longer alive

int enif_demonitor_process(ErlNifEnv *env, void *obj, const ErlNifMonitor *mon)

Unmonitor a process.

Parameters:
  • caller_env – current environment

  • obj – resource used by monitor

  • mon – monitor

Returns:

0 on success

void destroy_resource_monitors(struct RefcBinary *resource, GlobalContext *global)

Destroy monitors associated with a resource.

Parameters:
  • resource – resource to destroy monitors for

  • global – the global context

int enif_compare_monitors(const ErlNifMonitor *monitor1, const ErlNifMonitor *monitor2)

compare two monitors

Parameters:
  • monitor1 – first monitor

  • monitor2 – second monitor

Returns:

0 if equals, < 0 if monitor1 < monitor2, > 0 if monitor1 > monitor2.