@@ -91,16 +91,32 @@ static class MonitoringConfigTracker implements Runnable {
9191
9292 private static final Set <Class <?>> UNKNOWN_FILE_CONFIG_CLASSES = Collections .synchronizedSet (new ReferenceOpenHashSet <>());
9393
94- private boolean isSaving (FileConfig config ) throws ReflectiveOperationException {
94+ private void protectFromSaving (FileConfig config , Runnable runnable ) throws ReflectiveOperationException {
9595 if (WRITE_SYNC_CONFIG .isAssignableFrom (config .getClass ())) {
96- return CURRENTLY_WRITING .getBoolean (config );
96+ // keep trying to write, releasing the config lock each time in case something else needs to lock it
97+ // for any reason
98+ while (true ) {
99+ // acquiring synchronized block here should in theory prevent any other concurrent loads/saves, based
100+ // off WriteSyncFileConfig implementation
101+ synchronized (config ) {
102+ if (CURRENTLY_WRITING .getBoolean (config )) {
103+ ModernFixMixinPlugin .instance .logger .fatal ("Config being written during load!!!" );
104+ try { Thread .sleep (500 ); } catch (InterruptedException e ) { Thread .currentThread ().interrupt (); }
105+ continue ;
106+ }
107+ // at this point, currentlyWriting is false, and we acquired synchronized lock, should be good to
108+ // go
109+ runnable .run ();
110+ break ;
111+ }
112+ }
97113 } else if (AUTOSAVE_CONFIG .isAssignableFrom (config .getClass ())) {
98114 FileConfig fc = (FileConfig )AUTOSAVE_FILECONFIG .get (config );
99- return isSaving (fc );
115+ protectFromSaving (fc , runnable );
100116 } else {
101117 if (UNKNOWN_FILE_CONFIG_CLASSES .add (config .getClass ()))
102118 ModernFixMixinPlugin .instance .logger .warn ("Unexpected FileConfig class: {}" , config .getClass ().getName ());
103- return false ;
119+ runnable . run () ;
104120 }
105121 }
106122
@@ -115,21 +131,12 @@ public void run() {
115131 Field theField = getCurrentlyWritingFieldOnWatcher (this .configTracker );
116132 if (theField != null ) {
117133 CommentedFileConfig cfg = (CommentedFileConfig )theField .get (this .configTracker );
118- while (isSaving (cfg )) {
119- // block until the config is no longer marked as saving
120- // Forge shouldn't save the config twice in a row under normal conditions so this should fix the
121- // original bug
122- try {
123- Thread .sleep (500 );
124- } catch (InterruptedException e ) {
125- return ;
126- }
127- }
134+ // will synchronize and check saving flag
135+ protectFromSaving (cfg , configTracker );
128136 }
129137 } catch (ReflectiveOperationException e ) {
130138 e .printStackTrace ();
131139 }
132- configTracker .run ();
133140 }
134141 }
135142}
0 commit comments