mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 07:38:48 +00:00
Fix minor race condition
This commit is contained in:
+38
-10
@@ -184,6 +184,7 @@ gb_internal void init_decl_info(DeclInfo *d, Scope *scope, DeclInfo *parent) {
|
|||||||
ptr_set_init(&d->deps, heap_allocator());
|
ptr_set_init(&d->deps, heap_allocator());
|
||||||
ptr_set_init(&d->type_info_deps, heap_allocator());
|
ptr_set_init(&d->type_info_deps, heap_allocator());
|
||||||
array_init (&d->labels, heap_allocator());
|
array_init (&d->labels, heap_allocator());
|
||||||
|
mutex_init(&d->proc_checked_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_internal DeclInfo *make_decl_info(Scope *scope, DeclInfo *parent) {
|
gb_internal DeclInfo *make_decl_info(Scope *scope, DeclInfo *parent) {
|
||||||
@@ -193,6 +194,7 @@ gb_internal DeclInfo *make_decl_info(Scope *scope, DeclInfo *parent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// gb_internal void destroy_declaration_info(DeclInfo *d) {
|
// gb_internal void destroy_declaration_info(DeclInfo *d) {
|
||||||
|
// mutex_destroy(&d->proc_checked_mutex);
|
||||||
// ptr_set_destroy(&d->deps);
|
// ptr_set_destroy(&d->deps);
|
||||||
// array_free(&d->labels);
|
// array_free(&d->labels);
|
||||||
// }
|
// }
|
||||||
@@ -1200,30 +1202,51 @@ gb_internal CheckerContext make_checker_context(Checker *c) {
|
|||||||
|
|
||||||
ctx.type_path = new_checker_type_path();
|
ctx.type_path = new_checker_type_path();
|
||||||
ctx.type_level = 0;
|
ctx.type_level = 0;
|
||||||
|
mutex_init(&ctx.mutex);
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
gb_internal void destroy_checker_context(CheckerContext *ctx) {
|
gb_internal void destroy_checker_context(CheckerContext *ctx) {
|
||||||
|
mutex_destroy(&ctx->mutex);
|
||||||
destroy_checker_type_path(ctx->type_path);
|
destroy_checker_type_path(ctx->type_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_internal void add_curr_ast_file(CheckerContext *ctx, AstFile *file) {
|
gb_internal bool add_curr_ast_file(CheckerContext *ctx, AstFile *file) {
|
||||||
if (file != nullptr) {
|
if (file != nullptr) {
|
||||||
ctx->file = file;
|
ctx->file = file;
|
||||||
ctx->decl = file->pkg->decl_info;
|
ctx->decl = file->pkg->decl_info;
|
||||||
ctx->scope = file->scope;
|
ctx->scope = file->scope;
|
||||||
ctx->pkg = file->pkg;
|
ctx->pkg = file->pkg;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
gb_internal void reset_checker_context(CheckerContext *ctx, AstFile *file, UntypedExprInfoMap *untyped) {
|
gb_internal void reset_checker_context(CheckerContext *ctx, AstFile *file, UntypedExprInfoMap *untyped) {
|
||||||
if (ctx == nullptr) {
|
if (ctx == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
destroy_checker_context(ctx);
|
GB_ASSERT(ctx->checker != nullptr);
|
||||||
|
mutex_lock(&ctx->mutex);
|
||||||
|
|
||||||
auto *queue = ctx->procs_to_check_queue;
|
auto *queue = ctx->procs_to_check_queue;
|
||||||
*ctx = make_checker_context(ctx->checker);
|
auto type_path = ctx->type_path;
|
||||||
|
array_clear(type_path);
|
||||||
|
|
||||||
|
zero_size(&ctx->pkg, gb_size_of(CheckerContext) - gb_offset_of(CheckerContext, pkg));
|
||||||
|
|
||||||
|
ctx->file = nullptr;
|
||||||
|
ctx->scope = builtin_pkg->scope;
|
||||||
|
ctx->pkg = builtin_pkg;
|
||||||
|
ctx->decl = nullptr;
|
||||||
|
|
||||||
|
ctx->type_path = type_path;
|
||||||
|
ctx->type_level = 0;
|
||||||
|
|
||||||
add_curr_ast_file(ctx, file);
|
add_curr_ast_file(ctx, file);
|
||||||
|
|
||||||
ctx->procs_to_check_queue = queue;
|
ctx->procs_to_check_queue = queue;
|
||||||
ctx->untyped = untyped;
|
ctx->untyped = untyped;
|
||||||
|
|
||||||
|
mutex_unlock(&ctx->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -5067,11 +5090,14 @@ gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *u
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Entity *e = pi->decl->entity;
|
Entity *e = pi->decl->entity;
|
||||||
if (pi->decl->proc_checked) {
|
|
||||||
if (e != nullptr) {
|
MUTEX_GUARD_BLOCK(&pi->decl->proc_checked_mutex) {
|
||||||
GB_ASSERT(e->flags & EntityFlag_ProcBodyChecked);
|
if (pi->decl->proc_checked) {
|
||||||
|
if (e != nullptr) {
|
||||||
|
GB_ASSERT(e->flags & EntityFlag_ProcBodyChecked);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckerContext ctx = make_checker_context(c);
|
CheckerContext ctx = make_checker_context(c);
|
||||||
@@ -5128,10 +5154,12 @@ gb_internal bool check_proc_info(Checker *c, ProcInfo *pi, UntypedExprInfoMap *u
|
|||||||
}
|
}
|
||||||
|
|
||||||
check_proc_body(&ctx, pi->token, pi->decl, pi->type, pi->body);
|
check_proc_body(&ctx, pi->token, pi->decl, pi->type, pi->body);
|
||||||
if (e != nullptr) {
|
MUTEX_GUARD_BLOCK(&pi->decl->proc_checked_mutex) {
|
||||||
e->flags |= EntityFlag_ProcBodyChecked;
|
if (e != nullptr) {
|
||||||
|
e->flags |= EntityFlag_ProcBodyChecked;
|
||||||
|
}
|
||||||
|
pi->decl->proc_checked = true;
|
||||||
}
|
}
|
||||||
pi->decl->proc_checked = true;
|
|
||||||
add_untyped_expressions(&c->info, ctx.untyped);
|
add_untyped_expressions(&c->info, ctx.untyped);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -158,6 +158,7 @@ struct DeclInfo {
|
|||||||
bool is_using;
|
bool is_using;
|
||||||
bool where_clauses_evaluated;
|
bool where_clauses_evaluated;
|
||||||
bool proc_checked;
|
bool proc_checked;
|
||||||
|
BlockingMutex proc_checked_mutex;
|
||||||
isize defer_used;
|
isize defer_used;
|
||||||
bool defer_use_checked;
|
bool defer_use_checked;
|
||||||
|
|
||||||
@@ -377,13 +378,17 @@ struct CheckerInfo {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct CheckerContext {
|
struct CheckerContext {
|
||||||
|
// Order matters here
|
||||||
|
BlockingMutex mutex;
|
||||||
Checker * checker;
|
Checker * checker;
|
||||||
CheckerInfo * info;
|
CheckerInfo * info;
|
||||||
|
|
||||||
AstPackage * pkg;
|
AstPackage * pkg;
|
||||||
AstFile * file;
|
AstFile * file;
|
||||||
Scope * scope;
|
Scope * scope;
|
||||||
DeclInfo * decl;
|
DeclInfo * decl;
|
||||||
|
|
||||||
|
// Order doesn't matter after this
|
||||||
u32 state_flags;
|
u32 state_flags;
|
||||||
bool in_defer; // TODO(bill): Actually handle correctly
|
bool in_defer; // TODO(bill): Actually handle correctly
|
||||||
Type * type_hint;
|
Type * type_hint;
|
||||||
|
|||||||
Reference in New Issue
Block a user