From 04cedf5ece2cb23709a09d948121e9da532f72ee Mon Sep 17 00:00:00 2001 From: PhatPhuckDave Date: Fri, 28 Mar 2025 11:33:36 +0100 Subject: [PATCH] Fix the concurrent map writes --- main.go | 63 +++++++++++++-------------------------------------------- 1 file changed, 14 insertions(+), 49 deletions(-) diff --git a/main.go b/main.go index 8536b91..e7d1223 100644 --- a/main.go +++ b/main.go @@ -21,14 +21,14 @@ type GlobalStats struct { TotalModifications int ProcessedFiles int FailedFiles int - ModificationsPerCommand map[string]int + ModificationsPerCommand sync.Map } var ( repo *git.Repository worktree *git.Worktree stats GlobalStats = GlobalStats{ - ModificationsPerCommand: make(map[string]int), + ModificationsPerCommand: sync.Map{}, } ) @@ -54,46 +54,6 @@ func main() { fmt.Fprintf(os.Stderr, " Glob patterns are supported for file selection (*.xml, data/**.xml, etc.)\n") } // TODO: Fix bed shitting when doing *.yml in barotrauma directory - // TODO: Fix disaster: - // fatal error: concurrent map writes - // - // goroutine 243 [running]: - // internal/runtime/maps.fatal({0x8b9c77?, 0xc003399ce8?}) - // C:/Users/Administrator/scoop/apps/go/current/src/runtime/panic.go:1058 +0x18 - // main.main.func2({0x0?, 0x0?, 0x0?}) - // C:/Users/Administrator/Seafile/Projects-Go/GoProjects/modifier/main.go:137 +0x31d - // modify/logger.SafeGoWithArgs.func1() - // C:/Users/Administrator/Seafile/Projects-Go/GoProjects/modifier/logger/panic_handler.go:31 +0x43 - // created by modify/logger.SafeGoWithArgs in goroutine 1 - // C:/Users/Administrator/Seafile/Projects-Go/GoProjects/modifier/logger/panic_handler.go:29 +0x86 - // - // goroutine 1 [chan send]: - // main.main() - // C:/Users/Administrator/Seafile/Projects-Go/GoProjects/modifier/main.go:107 +0x5aa - // - // goroutine 547 [sync.Mutex.Lock]: - // internal/sync.runtime_SemacquireMutex(0x0?, 0x5b?, 0x0?) - // C:/Users/Administrator/scoop/apps/go/current/src/runtime/sema.go:95 +0x25 - // internal/sync.(*Mutex).lockSlow(0xc0000a2240) - // C:/Users/Administrator/scoop/apps/go/current/src/internal/sync/mutex.go:149 +0x15d - // internal/sync.(*Mutex).Lock(...) - // C:/Users/Administrator/scoop/apps/go/current/src/internal/sync/mutex.go:70 - // sync.(*Mutex).Lock(...) - // C:/Users/Administrator/scoop/apps/go/current/src/sync/mutex.go:46 - // modify/logger.(*Logger).log(0xc0000a2240, 0x1, {0x8bf8ab, 0x1e}, {0xc007049d08, 0x1, 0x1}) - // C:/Users/Administrator/Seafile/Projects-Go/GoProjects/modifier/logger/logger.go:321 +0x9d - // modify/logger.(*Logger).Warning(...) - // C:/Users/Administrator/Seafile/Projects-Go/GoProjects/modifier/logger/logger.go:335 - // modify/logger.Warning({0x8bf8ab?, 0x5c?}, {0xc004d87d08?, 0xc006b85ae0?, 0x53f3b9?}) - // C:/Users/Administrator/Seafile/Projects-Go/GoProjects/modifier/logger/logger.go:373 +0x87 - // modify/processor.ProcessRegex({0xc004025000, 0x1f0}, {{0xc00026c450, 0xa}, {0xc000015bd0, 0x4b}, {0xc000261c00, 0xf4}, {0xc000282110, 0x1, ...}, ...}) - // C:/Users/Administrator/Seafile/Projects-Go/GoProjects/modifier/processor/regex.go:64 +0x5c5 - // main.main.func2({0x0?, 0x0?, 0x0?}) - // C:/Users/Administrator/Seafile/Projects-Go/GoProjects/modifier/main.go:128 +0x471 - // modify/logger.SafeGoWithArgs.func1() - // C:/Users/Administrator/Seafile/Projects-Go/GoProjects/modifier/logger/panic_handler.go:31 +0x43 - // created by modify/logger.SafeGoWithArgs in goroutine 1 - // C:/Users/Administrator/Seafile/Projects-Go/GoProjects/modifier/logger/panic_handler.go:29 +0x86 flag.Parse() args := flag.Args() @@ -178,7 +138,11 @@ func main() { // It is not guranteed that all the commands will be executed... // TODO: Make this better // We'd have to pass the map to executemodifications or something... - stats.ModificationsPerCommand[command.Name] += len(commands) + count, ok := stats.ModificationsPerCommand.Load(command.Name) + if !ok { + count = 0 + } + stats.ModificationsPerCommand.Store(command.Name, count.(int)+len(commands)) } if len(modifications) == 0 { @@ -261,15 +225,16 @@ func main() { stats.TotalModifications, stats.ProcessedFiles, stats.ProcessedFiles+stats.FailedFiles) fmt.Printf("Operation complete! Modified %d values in %d/%d files\n", stats.TotalModifications, stats.ProcessedFiles, stats.ProcessedFiles+stats.FailedFiles) - sortedCommands := make([]string, 0, len(stats.ModificationsPerCommand)) - for command := range stats.ModificationsPerCommand { - sortedCommands = append(sortedCommands, command) - } + sortedCommands := []string{} + stats.ModificationsPerCommand.Range(func(key, value interface{}) bool { + sortedCommands = append(sortedCommands, key.(string)) + return true + }) sort.Strings(sortedCommands) for _, command := range sortedCommands { - count := stats.ModificationsPerCommand[command] - if count > 0 { + count, _ := stats.ModificationsPerCommand.Load(command) + if count.(int) > 0 { logger.Info("\tCommand %q made %d modifications", command, count) } else { logger.Warning("\tCommand %q made no modifications", command)