Browse Source

Fixed CopyFrom implementation locking

4.0.0-beta
Anairkoen Schno 4 years ago
parent
commit
710a7bc21e
3 changed files with 26 additions and 14 deletions
  1. +4
    -1
      IPA.Loader/Config/SelfConfig.cs
  2. +1
    -1
      IPA.Loader/Config/Stores/CustomObjectConverter.cs
  3. +21
    -12
      IPA.Loader/Config/Stores/GeneratedStore.cs

+ 4
- 1
IPA.Loader/Config/SelfConfig.cs View File

@ -25,8 +25,11 @@ namespace IPA.Config
Instance = LoaderConfig.Generated<SelfConfig>(); Instance = LoaderConfig.Generated<SelfConfig>();
} }
protected virtual void CopyFrom(SelfConfig cfg) { }
protected internal virtual void OnReload() protected internal virtual void OnReload()
{ {
if (Regenerate)
CopyFrom(new SelfConfig());
StandardLogger.Configure(); StandardLogger.Configure();
} }
@ -72,7 +75,7 @@ namespace IPA.Config
// END: section ignore // END: section ignore
public virtual bool Regenerate { get; set; } = true;
public virtual bool Regenerate { get; set; } = false;
public class Updates_ public class Updates_
{ {


+ 1
- 1
IPA.Loader/Config/Stores/CustomObjectConverter.cs View File

@ -35,7 +35,7 @@ namespace IPA.Config.Stores.Converters
else else
{ {
var newObj = Create(null); var newObj = Create(null);
newObj.CopyFrom(obj);
newObj.CopyFrom(obj, false); // don't use lock because it won't be used
return newObj.Serialize(); return newObj.Serialize();
} }
} }


+ 21
- 12
IPA.Loader/Config/Stores/GeneratedStore.cs View File

@ -113,7 +113,7 @@ namespace IPA.Config.Stores
} }
internal interface IGeneratedStore<T> : IGeneratedStore where T : class internal interface IGeneratedStore<T> : IGeneratedStore where T : class
{ {
void CopyFrom(T source);
void CopyFrom(T source, bool useLock);
} }
internal class Impl : IConfigStore internal class Impl : IConfigStore
@ -500,7 +500,7 @@ namespace IPA.Config.Stores
foreach (var member in structure) foreach (var member in structure)
{ {
EmitMemberFix(il, member, GetLocal);
EmitMemberFix(il, member, false, GetLocal);
} }
il.Emit(OpCodes.Pop); il.Emit(OpCodes.Pop);
@ -694,14 +694,18 @@ namespace IPA.Config.Stores
var IGeneratedStore_T_CopyFrom = IGeneratedStore_T_t.GetMethod(nameof(IGeneratedStore<Config>.CopyFrom)); var IGeneratedStore_T_CopyFrom = IGeneratedStore_T_t.GetMethod(nameof(IGeneratedStore<Config>.CopyFrom));
#region IGeneratedStore<T>.CopyFrom #region IGeneratedStore<T>.CopyFrom
var copyFrom = typeBuilder.DefineMethod($"<>{nameof(IGeneratedStore<Config>.CopyFrom)}", virtualMemberMethod, null, new[] { type });
var copyFrom = typeBuilder.DefineMethod($"<>{nameof(IGeneratedStore<Config>.CopyFrom)}", virtualMemberMethod, null, new[] { type, typeof(bool) });
typeBuilder.DefineMethodOverride(copyFrom, IGeneratedStore_T_CopyFrom); typeBuilder.DefineMethodOverride(copyFrom, IGeneratedStore_T_CopyFrom);
{ {
var il = copyFrom.GetILGenerator(); var il = copyFrom.GetILGenerator();
var startLock = il.DefineLabel();
il.Emit(OpCodes.Ldarg_2);
il.Emit(OpCodes.Brfalse, startLock);
il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, Impl.ImplTakeWriteMethod); // take the write lock il.Emit(OpCodes.Call, Impl.ImplTakeWriteMethod); // take the write lock
il.MarkLabel(startLock);
var GetLocal = MakeGetLocal(il); var GetLocal = MakeGetLocal(il);
@ -712,7 +716,7 @@ namespace IPA.Config.Stores
EmitStore(il, member, il => EmitStore(il, member, il =>
{ {
EmitLoad(il, member, il => il.Emit(OpCodes.Ldarg_1)); EmitLoad(il, member, il => il.Emit(OpCodes.Ldarg_1));
EmitCorrectMember(il, member, GetLocal);
EmitCorrectMember(il, member, false, GetLocal);
}); });
il.BeginCatchBlock(typeof(Exception)); il.BeginCatchBlock(typeof(Exception));
@ -720,11 +724,14 @@ namespace IPA.Config.Stores
EmitWarnException(il, $"Error while copying from member {member.Name}"); EmitWarnException(il, $"Error while copying from member {member.Name}");
il.EndExceptionBlock(); il.EndExceptionBlock();
}
}
var endLock = il.DefineLabel();
il.Emit(OpCodes.Ldarg_2);
il.Emit(OpCodes.Brfalse, endLock);
il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, Impl.ImplReleaseWriteMethod); // release write lock il.Emit(OpCodes.Call, Impl.ImplReleaseWriteMethod); // release write lock
il.MarkLabel(endLock);
il.Emit(OpCodes.Ret); il.Emit(OpCodes.Ret);
} }
#endregion #endregion
@ -855,6 +862,7 @@ namespace IPA.Config.Stores
il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Ldc_I4_1);
il.Emit(OpCodes.Call, copyFrom); // call internal il.Emit(OpCodes.Call, copyFrom); // call internal
il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0);
@ -922,7 +930,7 @@ namespace IPA.Config.Stores
il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldarg_1);
EmitCorrectMember(il, member, GetLocal);
EmitCorrectMember(il, member, false, GetLocal);
il.Emit(OpCodes.Call, set); il.Emit(OpCodes.Call, set);
il.BeginFinallyBlock(); il.BeginFinallyBlock();
@ -998,7 +1006,7 @@ namespace IPA.Config.Stores
} }
// expects start value on stack, exits with final value on stack // expects start value on stack, exits with final value on stack
private static void EmitCorrectMember(ILGenerator il, SerializedMemberInfo member, GetLocal GetLocal)
private static void EmitCorrectMember(ILGenerator il, SerializedMemberInfo member, bool shouldLock, GetLocal GetLocal)
{ {
if (!NeedsCorrection(member)) return; if (!NeedsCorrection(member)) return;
@ -1012,7 +1020,7 @@ namespace IPA.Config.Stores
il.Emit(OpCodes.Call, member.Nullable_Value.GetGetMethod()); il.Emit(OpCodes.Call, member.Nullable_Value.GetGetMethod());
} }
// TODO: impl
// TODO: impl the rest of this
// currently the only thing for this is where expect == Map, so do generate shit // currently the only thing for this is where expect == Map, so do generate shit
il.Emit(OpCodes.Dup); il.Emit(OpCodes.Dup);
@ -1025,6 +1033,7 @@ namespace IPA.Config.Stores
EmitCreateChildGenerated(il, member.Type); EmitCreateChildGenerated(il, member.Type);
il.Emit(OpCodes.Dup); il.Emit(OpCodes.Dup);
il.Emit(OpCodes.Ldloc, valLocal); il.Emit(OpCodes.Ldloc, valLocal);
il.Emit(shouldLock ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
il.Emit(OpCodes.Callvirt, copyFrom); il.Emit(OpCodes.Callvirt, copyFrom);
if (member.IsNullable) if (member.IsNullable)
@ -1034,7 +1043,7 @@ namespace IPA.Config.Stores
} }
// expects the this param to be on the stack // expects the this param to be on the stack
private static void EmitMemberFix(ILGenerator il, SerializedMemberInfo member, GetLocal GetLocal)
private static void EmitMemberFix(ILGenerator il, SerializedMemberInfo member, bool shouldLock, GetLocal GetLocal)
{ {
if (!NeedsCorrection(member)) return; if (!NeedsCorrection(member)) return;
@ -1043,7 +1052,7 @@ namespace IPA.Config.Stores
EmitStore(il, member, il => EmitStore(il, member, il =>
{ {
EmitLoad(il, member); // load the member EmitLoad(il, member); // load the member
EmitCorrectMember(il, member, GetLocal); // correct it
EmitCorrectMember(il, member, shouldLock, GetLocal); // correct it
}); });
} }


Loading…
Cancel
Save