Fix vanilla bug causing integrated server saving from 2 threads concurrently after a crash
This commit is contained in:
parent
c7d887f078
commit
09ff49fe58
3 changed files with 112 additions and 18 deletions
|
@ -20,7 +20,34 @@
|
|||
@SideOnly(Side.CLIENT)
|
||||
public class Minecraft implements IPlayerUsage
|
||||
{
|
||||
@@ -448,7 +454,7 @@
|
||||
@@ -333,21 +339,23 @@
|
||||
File file2 = new File(file1, "crash-" + (new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss")).format(new Date()) + "-client.txt");
|
||||
System.out.println(p_71377_1_.func_71502_e());
|
||||
|
||||
+ int retVal;
|
||||
if (p_71377_1_.func_71497_f() != null)
|
||||
{
|
||||
System.out.println("#@!@# Game crashed! Crash report saved to: #@!@# " + p_71377_1_.func_71497_f());
|
||||
- System.exit(-1);
|
||||
+ retVal = -1;
|
||||
}
|
||||
else if (p_71377_1_.func_147149_a(file2))
|
||||
{
|
||||
System.out.println("#@!@# Game crashed! Crash report saved to: #@!@# " + file2.getAbsolutePath());
|
||||
- System.exit(-1);
|
||||
+ retVal = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.println("#@?@# Game crashed! Crash report could not be saved. #@?@#");
|
||||
- System.exit(-2);
|
||||
+ retVal = -2;
|
||||
}
|
||||
+ FMLCommonHandler.instance().handleExit(retVal);
|
||||
}
|
||||
|
||||
public void func_71367_a(String p_71367_1_, int p_71367_2_)
|
||||
@@ -448,7 +456,7 @@
|
||||
this.field_110451_am = new SimpleReloadableResourceManager(this.field_110452_an);
|
||||
this.field_135017_as = new LanguageManager(this.field_110452_an, this.field_71474_y.field_74363_ab);
|
||||
this.field_110451_am.func_110542_a(this.field_135017_as);
|
||||
|
@ -29,7 +56,7 @@
|
|||
this.field_71446_o = new TextureManager(this.field_110451_am);
|
||||
this.field_110451_am.func_110542_a(this.field_71446_o);
|
||||
this.field_147127_av = new SoundHandler(this.field_110451_am, this.field_71474_y);
|
||||
@@ -508,12 +514,13 @@
|
||||
@@ -508,12 +516,13 @@
|
||||
this.field_71446_o.func_130088_a(TextureMap.field_110576_c, new TextureMap(1, "textures/items"));
|
||||
GL11.glViewport(0, 0, this.field_71443_c, this.field_71440_d);
|
||||
this.field_71452_i = new EffectRenderer(this.field_71441_e, this.field_71446_o);
|
||||
|
@ -44,7 +71,7 @@
|
|||
}
|
||||
else
|
||||
{
|
||||
@@ -527,6 +534,7 @@
|
||||
@@ -527,6 +536,7 @@
|
||||
this.func_71352_k();
|
||||
}
|
||||
|
||||
|
@ -52,7 +79,7 @@
|
|||
Display.setVSyncEnabled(this.field_71474_y.field_74352_v);
|
||||
}
|
||||
|
||||
@@ -916,9 +924,11 @@
|
||||
@@ -916,9 +926,11 @@
|
||||
|
||||
if (!this.field_71454_w)
|
||||
{
|
||||
|
@ -64,7 +91,7 @@
|
|||
}
|
||||
|
||||
GL11.glFlush();
|
||||
@@ -1496,6 +1506,8 @@
|
||||
@@ -1496,6 +1508,8 @@
|
||||
--this.field_71467_ac;
|
||||
}
|
||||
|
||||
|
@ -73,7 +100,7 @@
|
|||
this.field_71424_I.func_76320_a("gui");
|
||||
|
||||
if (!this.field_71445_n)
|
||||
@@ -1646,6 +1658,7 @@
|
||||
@@ -1646,6 +1660,7 @@
|
||||
this.field_71462_r.func_146274_d();
|
||||
}
|
||||
}
|
||||
|
@ -81,7 +108,7 @@
|
|||
}
|
||||
|
||||
if (this.field_71429_W > 0)
|
||||
@@ -1787,6 +1800,7 @@
|
||||
@@ -1787,6 +1802,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -89,7 +116,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
@@ -1978,12 +1992,15 @@
|
||||
@@ -1978,12 +1994,15 @@
|
||||
this.field_71453_ak.func_74428_b();
|
||||
}
|
||||
|
||||
|
@ -105,7 +132,7 @@
|
|||
this.func_71403_a((WorldClient)null);
|
||||
System.gc();
|
||||
ISaveHandler isavehandler = this.field_71469_aa.func_75804_a(p_71371_1_, false);
|
||||
@@ -2019,6 +2036,12 @@
|
||||
@@ -2019,6 +2038,12 @@
|
||||
|
||||
while (!this.field_71437_Z.func_71200_ad())
|
||||
{
|
||||
|
@ -118,7 +145,7 @@
|
|||
String s2 = this.field_71437_Z.func_71195_b_();
|
||||
|
||||
if (s2 != null)
|
||||
@@ -2094,6 +2117,7 @@
|
||||
@@ -2094,6 +2119,7 @@
|
||||
this.field_110448_aq.func_148529_f();
|
||||
this.func_71351_a((ServerData)null);
|
||||
this.field_71455_al = false;
|
||||
|
|
|
@ -29,25 +29,36 @@
|
|||
long i = func_130071_aq();
|
||||
long l = 0L;
|
||||
this.field_147147_p.func_151315_a(new ChatComponentText(this.field_71286_C));
|
||||
@@ -425,12 +431,17 @@
|
||||
@@ -425,12 +431,20 @@
|
||||
Thread.sleep(1L);
|
||||
this.field_71296_Q = true;
|
||||
}
|
||||
+ FMLCommonHandler.instance().handleServerStopping();
|
||||
+ FMLCommonHandler.instance().expectServerStopped(); // has to come before finalTick to avoid race conditions
|
||||
}
|
||||
else
|
||||
{
|
||||
+ FMLCommonHandler.instance().expectServerStopped(); // has to come before finalTick to avoid race conditions
|
||||
this.func_71228_a((CrashReport)null);
|
||||
}
|
||||
}
|
||||
+ catch (StartupQuery.AbortedException e)
|
||||
+ {
|
||||
+ // ignore silently
|
||||
+ FMLCommonHandler.instance().expectServerStopped(); // has to come before finalTick to avoid race conditions
|
||||
+ }
|
||||
catch (Throwable throwable1)
|
||||
{
|
||||
field_147145_h.error("Encountered an unexpected exception", throwable1);
|
||||
@@ -471,6 +482,8 @@
|
||||
@@ -456,6 +470,7 @@
|
||||
field_147145_h.error("We were unable to save this crash report to disk.");
|
||||
}
|
||||
|
||||
+ FMLCommonHandler.instance().expectServerStopped(); // has to come before finalTick to avoid race conditions
|
||||
this.func_71228_a(crashreport);
|
||||
}
|
||||
finally
|
||||
@@ -471,6 +486,8 @@
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -56,7 +67,7 @@
|
|||
this.func_71240_o();
|
||||
}
|
||||
}
|
||||
@@ -513,6 +526,7 @@
|
||||
@@ -513,6 +530,7 @@
|
||||
{
|
||||
long i = System.nanoTime();
|
||||
AxisAlignedBB.func_72332_a().func_72298_a();
|
||||
|
@ -64,7 +75,7 @@
|
|||
++this.field_71315_w;
|
||||
|
||||
if (this.field_71295_T)
|
||||
@@ -566,6 +580,7 @@
|
||||
@@ -566,6 +584,7 @@
|
||||
|
||||
this.field_71304_b.func_76319_b();
|
||||
this.field_71304_b.func_76319_b();
|
||||
|
@ -72,7 +83,7 @@
|
|||
}
|
||||
|
||||
public void func_71190_q()
|
||||
@@ -593,6 +608,7 @@
|
||||
@@ -593,6 +612,7 @@
|
||||
}
|
||||
|
||||
this.field_71304_b.func_76320_a("tick");
|
||||
|
@ -80,7 +91,7 @@
|
|||
CrashReport crashreport;
|
||||
|
||||
try
|
||||
@@ -617,6 +633,7 @@
|
||||
@@ -617,6 +637,7 @@
|
||||
throw new ReportedException(crashreport);
|
||||
}
|
||||
|
||||
|
@ -88,7 +99,7 @@
|
|||
this.field_71304_b.func_76319_b();
|
||||
this.field_71304_b.func_76320_a("tracker");
|
||||
worldserver.func_73039_n().func_72788_a();
|
||||
@@ -648,6 +665,7 @@
|
||||
@@ -648,6 +669,7 @@
|
||||
|
||||
public void func_71256_s()
|
||||
{
|
||||
|
@ -96,7 +107,7 @@
|
|||
(new Thread("Server thread")
|
||||
{
|
||||
private static final String __OBFID = "CL_00001418";
|
||||
@@ -695,7 +713,7 @@
|
||||
@@ -695,7 +717,7 @@
|
||||
|
||||
public String getServerModName()
|
||||
{
|
||||
|
|
|
@ -17,6 +17,8 @@ import java.lang.ref.WeakReference;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import net.minecraft.crash.CrashReport;
|
||||
import net.minecraft.crash.CrashReportCategory;
|
||||
|
@ -86,6 +88,7 @@ public class FMLCommonHandler
|
|||
private Set<SaveHandler> handlerSet = Sets.newSetFromMap(new MapMaker().weakKeys().<SaveHandler,Boolean>makeMap());
|
||||
private WeakReference<SaveHandler> handlerToCheck;
|
||||
private EventBus eventBus = new EventBus();
|
||||
private volatile CountDownLatch exitLatch = null;
|
||||
/**
|
||||
* The FML event bus. Subscribe here for FML related events
|
||||
*
|
||||
|
@ -428,6 +431,50 @@ public class FMLCommonHandler
|
|||
return sidedDelegate.shouldServerShouldBeKilledQuietly();
|
||||
}
|
||||
|
||||
/**
|
||||
* Make handleExit() wait for handleServerStopped().
|
||||
*
|
||||
* For internal use only!
|
||||
*/
|
||||
public void expectServerStopped()
|
||||
{
|
||||
exitLatch = new CountDownLatch(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delayed System.exit() until the server is actually stopped/done saving.
|
||||
*
|
||||
* For internal use only!
|
||||
*
|
||||
* @param retVal Exit code for System.exit()
|
||||
*/
|
||||
public void handleExit(int retVal)
|
||||
{
|
||||
CountDownLatch latch = exitLatch;
|
||||
|
||||
if (latch != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
FMLLog.info("Waiting for the server to terminate/save.");
|
||||
if (!latch.await(10, TimeUnit.SECONDS))
|
||||
{
|
||||
FMLLog.warning("The server didn't stop within 10 seconds, exiting anyway.");
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.info("Server terminated.");
|
||||
}
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
FMLLog.warning("Interrupted wait, exiting.");
|
||||
}
|
||||
}
|
||||
|
||||
System.exit(retVal);
|
||||
}
|
||||
|
||||
public void handleServerStopped()
|
||||
{
|
||||
sidedDelegate.serverStopped();
|
||||
|
@ -435,6 +482,15 @@ public class FMLCommonHandler
|
|||
Loader.instance().serverStopped();
|
||||
// FORCE the internal server to stop: hello optifine workaround!
|
||||
if (server!=null) ObfuscationReflectionHelper.setPrivateValue(MinecraftServer.class, server, false, "field_71316"+"_v", "u", "serverStopped");
|
||||
|
||||
// allow any pending exit to continue, clear exitLatch
|
||||
CountDownLatch latch = exitLatch;
|
||||
|
||||
if (latch != null)
|
||||
{
|
||||
latch.countDown();
|
||||
exitLatch = null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getModName()
|
||||
|
|
Loading…
Reference in a new issue