mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-08 11:34:20 +00:00
Fix race condition with regards to #soa arrays by using the fields mutex
This commit is contained in:
@@ -2553,6 +2553,8 @@ gb_internal Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_e
|
||||
GB_ASSERT(is_type_struct(elem));
|
||||
|
||||
Type *old_struct = base_type(elem);
|
||||
RW_MUTEX_GUARD(&old_struct->Struct.fields_mutex);
|
||||
|
||||
field_count = old_struct->Struct.fields.count;
|
||||
|
||||
soa_struct = alloc_type_struct();
|
||||
@@ -2593,21 +2595,19 @@ gb_internal Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_e
|
||||
}
|
||||
|
||||
if (soa_kind != StructSoa_Fixed) {
|
||||
Entity *len_field = alloc_entity_field(scope, empty_token, t_int, false, cast(i32)field_count+0);
|
||||
Entity *len_field = alloc_entity_field(scope, make_token_ident("__$len"), t_int, false, cast(i32)field_count+0);
|
||||
soa_struct->Struct.fields[field_count+0] = len_field;
|
||||
add_entity(ctx, scope, nullptr, len_field);
|
||||
add_entity_use(ctx, nullptr, len_field);
|
||||
|
||||
if (soa_kind == StructSoa_Dynamic) {
|
||||
Entity *cap_field = alloc_entity_field(scope, empty_token, t_int, false, cast(i32)field_count+1);
|
||||
Entity *cap_field = alloc_entity_field(scope, make_token_ident("__$cap"), t_int, false, cast(i32)field_count+1);
|
||||
soa_struct->Struct.fields[field_count+1] = cap_field;
|
||||
add_entity(ctx, scope, nullptr, cap_field);
|
||||
add_entity_use(ctx, nullptr, cap_field);
|
||||
|
||||
Token token = {};
|
||||
token.string = str_lit("allocator");
|
||||
init_mem_allocator(ctx->checker);
|
||||
Entity *allocator_field = alloc_entity_field(scope, token, t_allocator, false, cast(i32)field_count+2);
|
||||
Entity *allocator_field = alloc_entity_field(scope, make_token_ident("allocator"), t_allocator, false, cast(i32)field_count+2);
|
||||
soa_struct->Struct.fields[field_count+2] = allocator_field;
|
||||
add_entity(ctx, scope, nullptr, allocator_field);
|
||||
add_entity_use(ctx, nullptr, allocator_field);
|
||||
|
||||
@@ -119,17 +119,25 @@ struct MutexGuard {
|
||||
explicit MutexGuard(RecursiveMutex *rm) noexcept : rm{rm} {
|
||||
mutex_lock(this->rm);
|
||||
}
|
||||
explicit MutexGuard(RwMutex *rm) noexcept : rwm{rwm} {
|
||||
rw_mutex_lock(this->rwm);
|
||||
}
|
||||
explicit MutexGuard(BlockingMutex &bm) noexcept : bm{&bm} {
|
||||
mutex_lock(this->bm);
|
||||
}
|
||||
explicit MutexGuard(RecursiveMutex &rm) noexcept : rm{&rm} {
|
||||
mutex_lock(this->rm);
|
||||
}
|
||||
explicit MutexGuard(RwMutex &rwm) noexcept : rwm{&rwm} {
|
||||
rw_mutex_lock(this->rwm);
|
||||
}
|
||||
~MutexGuard() noexcept {
|
||||
if (this->bm) {
|
||||
mutex_unlock(this->bm);
|
||||
} else if (this->rm) {
|
||||
mutex_unlock(this->rm);
|
||||
} else if (this->rwm) {
|
||||
rw_mutex_unlock(this->rwm);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,10 +145,12 @@ struct MutexGuard {
|
||||
|
||||
BlockingMutex *bm;
|
||||
RecursiveMutex *rm;
|
||||
RwMutex *rwm;
|
||||
};
|
||||
|
||||
#define MUTEX_GUARD_BLOCK(m) if (MutexGuard GB_DEFER_3(_mutex_guard_){m})
|
||||
#define MUTEX_GUARD(m) mutex_lock(m); defer (mutex_unlock(m))
|
||||
#define RW_MUTEX_GUARD(m) rw_mutex_lock(m); defer (rw_mutex_unlock(m))
|
||||
|
||||
|
||||
struct RecursiveMutex {
|
||||
|
||||
Reference in New Issue
Block a user