Skip to content

Commit 0bd99fd

Browse files
committed
py/modatexit: Switch to using list.
Signed-off-by: Andrew Leech <andrew@alelec.net>
1 parent f80c6c7 commit 0bd99fd

File tree

1 file changed

+19
-38
lines changed

1 file changed

+19
-38
lines changed

py/modatexit.c

Lines changed: 19 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -34,45 +34,26 @@
3434

3535
#if MICROPY_PY_ATEXIT
3636

37-
typedef struct _m_atexit_node_t {
38-
struct _m_atexit_node_t *prev;
39-
struct _m_atexit_node_t *next;
40-
mp_obj_t fn;
41-
} m_atexit_node_t;
42-
43-
// atexit.register(function): Functions are called LIFO when soft-reset / exit is called.
4437
mp_obj_t mp_atexit_register(mp_obj_t function) {
4538
if (!mp_obj_is_callable(function)) {
4639
mp_raise_ValueError(MP_ERROR_TEXT("function not callable"));
4740
}
48-
m_atexit_node_t *node = m_malloc(sizeof(m_atexit_node_t));
49-
if (MP_STATE_VM(atexit) != NULL) {
50-
MP_STATE_VM(atexit)->prev = node;
41+
if (MP_STATE_VM(atexit) == NULL) {
42+
MP_STATE_VM(atexit) = mp_obj_new_list(0, mp_const_none);
5143
}
52-
node->fn = function;
53-
node->prev = NULL;
54-
node->next = MP_STATE_VM(atexit);
55-
MP_STATE_VM(atexit) = node;
44+
mp_obj_list_append(MP_STATE_VM(atexit), function);
5645
// return the passed in function so this can be used as a decorator
5746
return function;
5847
}
5948
static MP_DEFINE_CONST_FUN_OBJ_1(mp_atexit_register_obj, mp_atexit_register);
6049

6150
#if MICROPY_PY_ATEXIT_UNREGISTER
6251
mp_obj_t mp_atexit_unregister(mp_obj_t function) {
63-
m_atexit_node_t *node = MP_STATE_VM(atexit);
64-
while (node != NULL) {
65-
if (mp_obj_equal(node->fn, function)) {
66-
if (node->next != NULL) {
67-
node->next->prev = node->prev;
68-
}
69-
if (node->prev != NULL) {
70-
node->prev->next = node->next;
71-
} else {
72-
MP_STATE_VM(atexit) = node->next;
73-
}
52+
nlr_buf_t nlr;
53+
if (nlr_push(&nlr) == 0) {
54+
while (MP_STATE_VM(atexit) != NULL) {
55+
mp_obj_list_remove(MP_STATE_VM(atexit), function);
7456
}
75-
node = node->next;
7657
}
7758
return mp_const_none;
7859
}
@@ -86,30 +67,30 @@ static const mp_rom_map_elem_t mp_module_atexit_globals_table[] = {
8667
{ MP_ROM_QSTR(MP_QSTR_unregister), MP_ROM_PTR(&mp_atexit_unregister_obj) },
8768
#endif
8869
};
89-
9070
static MP_DEFINE_CONST_DICT(mp_module_atexit_globals, mp_module_atexit_globals_table);
9171

9272
const mp_obj_module_t mp_module_atexit = {
9373
.base = { &mp_type_module },
9474
.globals = (mp_obj_dict_t *)&mp_module_atexit_globals,
9575
};
9676

97-
MP_REGISTER_ROOT_POINTER(struct _m_atexit_node_t *atexit);
77+
MP_REGISTER_ROOT_POINTER(mp_obj_list_t * atexit);
9878
MP_REGISTER_MODULE(MP_QSTR_atexit, mp_module_atexit);
9979

10080
int mp_atexit_execute(void) {
10181
int exit_code = 0;
102-
// This function is intended to be run by a port during its soft-reset / exit.
103-
// walk down linked list last in / first out and execute each function.
104-
// Beware, the sys.settrace function should be disabled before running sys.atexit.
105-
while (MP_STATE_VM(atexit) != NULL) {
106-
nlr_buf_t nlr;
107-
if (nlr_push(&nlr) == 0) {
108-
mp_call_function_0(MP_STATE_VM(atexit)->fn);
109-
} else {
110-
exit_code = pyexec_handle_uncaught_exception(nlr.ret_val);
82+
if (MP_STATE_VM(atexit) != NULL) {
83+
mp_obj_list_t *list = MP_STATE_VM(atexit);
84+
for (size_t i = 0; i < list->len; i++) {
85+
mp_obj_t function = list->items[i];
86+
87+
nlr_buf_t nlr;
88+
if (nlr_push(&nlr) == 0) {
89+
mp_call_function_0(function);
90+
} else {
91+
exit_code = pyexec_handle_uncaught_exception(nlr.ret_val);
92+
}
11193
}
112-
MP_STATE_VM(atexit) = MP_STATE_VM(atexit)->next;
11394
}
11495
return exit_code;
11596
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy