|
1 | 1 | # Module Callbacks
|
2 | 2 |
|
3 |
| -The BEAM provides for a module to have several event-callbacks that are fired |
4 |
| -when a module is created. Zigler labels these callbacks in the following way: |
| 3 | +The BEAM provides for a module to have several event-callbacks that are fired when a module is |
| 4 | +created. Zigler labels these callbacks in the following way: |
5 | 5 |
|
6 | 6 | - [`on_load`](#on_load) - when the module is being loaded
|
7 | 7 | - [`on_upgrade`](#on_upgrade) - when the module is being loaded to replace another module
|
8 | 8 | - [`on_unload`](#on_unload) - when the module is being purged
|
9 | 9 |
|
10 |
| -These labeled are passed as options to the `use Zig` directive with the |
11 |
| -name of the function to be used as the callback. All three are optional. |
12 |
| -You may use just the atom to stand a function with the same name, e.g: |
13 |
| -`callbacks: [:on_load]` is shorthand for `callbacks: [on_load: :on_load]` |
| 10 | +These labeled are passed as options to the `use Zig` directive with the name of the function to be |
| 11 | +used as the callback. All three are optional. You may use just the atom to stand a function with the |
| 12 | +same name, e.g: `callbacks: [:on_load]` is shorthand for `callbacks: [on_load: :on_load]` |
14 | 13 |
|
15 |
| -> ### Callbacks are pub {: .info } |
| 14 | +> ### Callbacks are pub {: .info} |
16 | 15 | >
|
17 |
| -> Be sure to make your callback functions `pub`. You do *not* need to |
18 |
| -> add them to the module's `ignore` option. |
| 16 | +> Be sure to make your callback functions `pub`. You do *not* need to add them to the module's |
| 17 | +> `ignore` option. |
19 | 18 |
|
20 |
| -> ### Context in callbacks {: .info } |
21 |
| -> |
| 19 | +> ### Context in callbacks {: .info} |
| 20 | +> |
22 | 21 | > For all callbacks, the context is set as follows:
|
23 |
| -> |
24 |
| -> - `env`: the `e.ErlNifEnv` value passed to the callback function; |
25 |
| -> - `mode`: `.callback`; |
26 |
| -> - `allocator`: `beam.allocator`; |
27 |
| -> |
28 |
| -> Thus you should be able to use `beam.get`, `beam.make`, or `beam.send` |
29 |
| -> with the appropriate context set without extra options. |
| 22 | +- `env`: the `e.ErlNifEnv` value passed to the callback function; |
| 23 | +- `mode`: `.callback`; |
| 24 | +- `allocator`: `beam.allocator`; |
| 25 | +> |
| 26 | +> Thus you should be able to use `beam.get`, `beam.make`, or `beam.send` with the appropriate context |
| 27 | +> set without extra options. |
30 | 28 |
|
31 | 29 | ## on_load
|
32 | 30 |
|
33 | 31 | The on_load callback may have one of the following function signatures:
|
34 | 32 |
|
35 | 33 | - `fn (?*?*T, U) void`: if the on_load function can never fail.
|
36 |
| -- `fn (?*?*T, U) !void`: if the on_load function can fail with an error. |
37 |
| - The module load integer will reflect the integer value of the error. |
38 |
| - > #### Zig error integers {: .warning } |
39 |
| - > |
40 |
| - > Note that the integer representation of a zig error may change between |
41 |
| - > compilations. Translating this integer back to a meaningful value may |
42 |
| - > be challenging. |
43 |
| -- `fn (?*?*T, U) int`: the on_load function will be considered to fail if |
44 |
| - the integer value is not `0`. |
45 |
| -- `fn (?*?*T, U) E`: for an `enum` type `E`, the on_load function will be |
46 |
| - considered to fail if the enum value is not zero. It's recommended that |
47 |
| - the enum type `E` be defined as so: `const E = enum{ ok = 0, ...};` |
48 |
| -- `fn (beam.env, ?*?*anyopaque, e.ErlNifTerm) c_int`: this is a |
49 |
| - "raw" call that corresponds to the expected signature of a `upgrade` callback. |
| 34 | +- `fn (?*?*T, U) !void`: if the on_load function can fail with an error. The module load integer will |
| 35 | + reflect the integer value of the error. |
| 36 | +- |
| 37 | +> #### Zig error integers {: .warning} |
| 38 | +> |
| 39 | +> Note that the integer representation of a zig error may change between compilations. Translating |
| 40 | +> this integer back to a meaningful value may be challenging. |
| 41 | +- `fn (?*?*T, U) int`: the on_load function will be considered to fail if the integer value is not |
| 42 | + `0`. |
| 43 | +- `fn (?*?*T, U) E`: for an `enum` type `E`, the on_load function will be considered to fail if the |
| 44 | + enum value is not zero. It's recommended that the enum type `E` be defined as so: `const E = enum{ ok = 0, ...};` |
| 45 | +- `fn (beam.env, ?*?*anyopaque, e.ErlNifTerm) c_int`: this is a "raw" call that corresponds to the |
| 46 | + expected signature of a `upgrade` callback. |
50 | 47 |
|
51 | 48 | ### on_load Callback types
|
52 | 49 |
|
53 |
| -`T` may be any type at all, which is considered the *private data* of |
54 |
| -the module. Any information may be stored in a `*T`, and the double |
55 |
| -pointer is passed to the callback for the pointer to be communicated |
56 |
| -to the VM. The `*T` supplied will be accessible via the `enif_priv_data` |
57 |
| -function |
| 50 | +`T` may be any type at all, which is considered the *private data* of the module. Any information |
| 51 | +may be stored in a `*T`, and the double pointer is passed to the callback for the pointer to be |
| 52 | +communicated to the VM. The `*T` supplied will be accessible via the `enif_priv_data` function |
58 | 53 |
|
59 |
| -`U` must be a type that can be passed as the first argument of `beam.make`, |
60 |
| -and the value of `U` will be set by the result of an `__on_load__/0` function |
61 |
| -defined in the module body. The result of this function call will be passed |
62 |
| -to the `on_load` |
| 54 | +`U` must be a type that can be passed as the first argument of `beam.make`, and the value of `U` |
| 55 | +will be set by the result of an `__on_load__/0` function defined in the module body. The result of |
| 56 | +this function call will be passed to the `on_load` |
63 | 57 |
|
64 |
| -> ### on_load and resources {: .info } |
| 58 | +> ### on_load and resources {: .info} |
65 | 59 | >
|
66 |
| -> The beam nif guide says that resources must be initialized in the `load` |
67 |
| -> callback. The `on_load` callback must NOT initialize resources. This |
68 |
| -> is performed in a function that will wrap your `on_load` callback. |
| 60 | +> The beam nif guide says that resources must be initialized in the `load` callback. The `on_load` |
| 61 | +> callback must NOT initialize resources. This is performed in a function that will wrap your |
| 62 | +> `on_load` callback. |
69 | 63 |
|
70 | 64 | #### Example
|
71 | 65 |
|
|
105 | 99 | The on_upgrade callback may have one of the following function signatures:
|
106 | 100 |
|
107 | 101 | - `fn (?*?*T, ?*?*U, V) void`: if the on_load function can never fail.
|
108 |
| -- `fn (?*?*T, ?*?*U, V) !void`: if the on_load function can fail with an error. |
109 |
| - The module load integer will reflect the integer value of the error. |
110 |
| - > #### Zig error integers {: .warning } |
111 |
| - > |
112 |
| - > Note that the integer representation of a zig error may change between |
113 |
| - > compilations. Translating this integer back to a meaningful value may |
114 |
| - > be challenging. |
115 |
| -- `fn (?*?*T, ?*?*U, V) int`: the on_load function will be considered to fail if |
116 |
| - the integer value is not `0`. |
117 |
| -- `fn (?*?*T, ?*?*U, V) E`: for an `enum` type `E`, the on_load function will be |
118 |
| - considered to fail if the enum value is not zero. It's recommended that |
119 |
| - the enum type `E` be defined as so: `const E = enum{ ok = 0, ...};` |
120 |
| -- `fn (beam.env, ?*?*anyopaque, ?*?*anyopaque, e.ErlNifTerm) c_int`: this is a |
121 |
| - "raw" call that corresponds to the expected signature of a `upgrade` callback. |
| 102 | +- `fn (?*?*T, ?*?*U, V) !void`: if the on_load function can fail with an error. The module load |
| 103 | + integer will reflect the integer value of the error. |
| 104 | +- |
| 105 | +> #### Zig error integers {: .warning} |
| 106 | +> |
| 107 | +> Note that the integer representation of a zig error may change between compilations. Translating |
| 108 | +> this integer back to a meaningful value may be challenging. |
| 109 | +- `fn (?*?*T, ?*?*U, V) int`: the on_load function will be considered to fail if the integer value is |
| 110 | + not `0`. |
| 111 | +- `fn (?*?*T, ?*?*U, V) E`: for an `enum` type `E`, the on_load function will be considered to fail if |
| 112 | + the enum value is not zero. It's recommended that the enum type `E` be defined as so: `const E = enum{ ok = 0, ...};` |
| 113 | +- `fn (beam.env, ?*?*anyopaque, ?*?*anyopaque, e.ErlNifTerm) c_int`: this is a "raw" call that |
| 114 | + corresponds to the expected signature of a `upgrade` callback. |
122 | 115 |
|
123 | 116 | ### on_upgrade Callback types
|
124 | 117 |
|
125 |
| -`T` and `U` may be any type at all, which is considered the *private data* of |
126 |
| -the module. Any information may be stored in these pointers, and the double |
127 |
| -pointer is passed to the callback for the pointer to be communicated |
128 |
| -to the VM. The `*U` data supplied will be accessible via the `enif_priv_data` |
129 |
| -function |
| 118 | +`T` and `U` may be any type at all, which is considered the *private data* of the module. Any |
| 119 | +information may be stored in these pointers, and the double pointer is passed to the callback for |
| 120 | +the pointer to be communicated to the VM. The `*U` data supplied will be accessible via the |
| 121 | +`enif_priv_data` function |
130 | 122 |
|
131 |
| -`V` must be a type that can be passed as the first argument of `beam.make`, |
132 |
| -and the value of `V` will be set by the result of an `__on_load__/0` function |
133 |
| -defined in the module body. The result of this function call will be passed |
134 |
| -to the `on_load` |
| 123 | +`V` must be a type that can be passed as the first argument of `beam.make`, and the value of `V` |
| 124 | +will be set by the result of an `__on_load__/0` function defined in the module body. The result of |
| 125 | +this function call will be passed to the `on_load` |
135 | 126 |
|
136 |
| -> ### on_upgrade and resources {: .info } |
| 127 | +> ### on_upgrade and resources {: .info} |
137 | 128 | >
|
138 |
| -> The beam nif guide says that resources must be initialized in the `upgrade` |
139 |
| -> callback. The `on_upgrade` callback must NOT initialize resources. This |
140 |
| -> is performed in a function that will wrap your `on_upgrade` callback. |
| 129 | +> The beam nif guide says that resources must be initialized in the `upgrade` callback. The |
| 130 | +> `on_upgrade` callback must NOT initialize resources. This is performed in a function that will wrap |
| 131 | +> your `on_upgrade` callback. |
141 | 132 |
|
142 | 133 | ## on_unload
|
143 | 134 |
|
144 | 135 | The on_unload callback may have one of the following function signatures:
|
145 | 136 |
|
146 | 137 | - `fn (?*T) void`: if you would like your inbound private data to be typed.
|
147 |
| -- `fn (beam.env, ?*anyopaque) void`: this is a "raw" call that corresponds |
148 |
| - to the expected signature of a `upgrade` callback. |
| 138 | +- `fn (beam.env, ?*anyopaque) void`: this is a "raw" call that corresponds to the expected signature |
| 139 | + of a `upgrade` callback. |
0 commit comments