|
@@ -588,42 +588,45 @@ void qi_new_scope(qi_state_t *state) {
|
|
|
qi_list_push(state->scopes, scope);
|
|
|
}
|
|
|
|
|
|
-static bool _qi_old_scope(qi_state_t *state, bool ignore_barriers) {
|
|
|
- qi_scope_t *scope;
|
|
|
- qi_list_t *defers;
|
|
|
-
|
|
|
- if (qi_list_empty(state->scopes))
|
|
|
- return false;
|
|
|
-
|
|
|
- scope = qi_list_last(state->scopes);
|
|
|
- if (!ignore_barriers && scope->is_barrier)
|
|
|
- return false;
|
|
|
+static void qi_scope_run_defers(qi_state_t *state, qi_scope_t *scope) {
|
|
|
+ qi_mutex_lock(scope->mutex);
|
|
|
|
|
|
- defers = scope->defers;
|
|
|
+ qi_list_t *defers = scope->defers;
|
|
|
|
|
|
if (qi_list_empty(defers)) {
|
|
|
- qi_list_pop(state->scopes);
|
|
|
+ qi_mutex_unlock(scope->mutex);
|
|
|
|
|
|
- return true;
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
scope->defers = qi_list_make();
|
|
|
|
|
|
+ qi_mutex_unlock(scope->mutex);
|
|
|
+
|
|
|
for (qi_size_t i = 0; i < qi_list_length(defers); i++) {
|
|
|
qi_defer_t defer = (qi_defer_t)(qi_list_data(defers, i));
|
|
|
|
|
|
defer(state);
|
|
|
- }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+bool qi_old_scope(qi_state_t *state) {
|
|
|
+ qi_scope_t *scope;
|
|
|
+
|
|
|
+ if (qi_list_empty(state->scopes))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ scope = qi_list_last(state->scopes);
|
|
|
+ if (scope->is_barrier)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ qi_scope_run_defers(state, scope);
|
|
|
|
|
|
qi_list_pop(state->scopes);
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-bool qi_old_scope(qi_state_t *state) {
|
|
|
- return _qi_old_scope(state, false);
|
|
|
-}
|
|
|
-
|
|
|
qi_value_t *qi_call_meta(qi_state_t *state, bool *fail_flag, qi_value_t *value,
|
|
|
char *name, qi_size_t count, ...);
|
|
|
|
|
@@ -2865,7 +2868,15 @@ static qi_state_t *qi_state_clone(qi_state_t *state) {
|
|
|
}
|
|
|
|
|
|
void qi_exit(qi_state_t *state, int code) {
|
|
|
- while (_qi_old_scope(state, true)) ;
|
|
|
+ qi_ssize_t scopes_count = qi_list_length(state->scopes);
|
|
|
+
|
|
|
+ if (scopes_count > 1)
|
|
|
+ for (qi_ssize_t i = scopes_count - 1; i >= 0; i--) {
|
|
|
+ qi_scope_t *scope = qi_list_index(state->scopes, i);
|
|
|
+
|
|
|
+ qi_scope_run_defers(state, scope);
|
|
|
+ }
|
|
|
+
|
|
|
qi_finalize();
|
|
|
|
|
|
exit(code);
|