Fix minor race condition

This commit is contained in:
gingerBill
2022-12-19 00:29:40 +00:00
parent 01b508f182
commit a13e2f4578
2 changed files with 43 additions and 10 deletions
+38 -10
View File
@@ -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;
} }
+5
View File
@@ -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;