refactoring Skeleton creation

This commit is contained in:
Christian Köllner 2020-04-10 19:23:16 +02:00
parent 3d0683288a
commit de788bca6b
9 changed files with 24 additions and 35 deletions

View File

@ -1046,7 +1046,7 @@ namespace Capnp.Net.Runtime.Tests
{ {
LaunchCompatTestProcess("server:MoreStuff", stdout => LaunchCompatTestProcess("server:MoreStuff", stdout =>
{ {
for (int i = 0; i < 100; i++) for (int i = 0; i < 20; i++)
{ {
EmbargoErrorImpl(stdout); EmbargoErrorImpl(stdout);
} }

View File

@ -67,7 +67,7 @@ namespace Capnp.Net.Runtime.Tests
public void EmbargoServer() public void EmbargoServer()
{ {
var t2 = new TcpRpcInterop(); var t2 = new TcpRpcInterop();
Repeat(100, t2.EmbargoServer); Repeat(20, t2.EmbargoServer);
} }
[TestMethod] [TestMethod]

View File

@ -19,7 +19,7 @@
/// <exception cref="System.TypeLoadException">Problem with building the Skeleton type, or problem with loading some dependent class.</exception> /// <exception cref="System.TypeLoadException">Problem with building the Skeleton type, or problem with loading some dependent class.</exception>
public static BareProxy FromImpl(object impl) public static BareProxy FromImpl(object impl)
{ {
return new BareProxy(CapabilityReflection.CreateSkeleton(impl).AsCapability()); return new BareProxy(CapabilityReflection.CreateSkeletonInternal(impl).AsCapability());
} }
/// <summary> /// <summary>

View File

@ -94,6 +94,8 @@ namespace Capnp.Rpc
new ConditionalWeakTable<Type, ProxyFactory>(); new ConditionalWeakTable<Type, ProxyFactory>();
static ConditionalWeakTable<Type, SkeletonFactory> _skeletonMap = static ConditionalWeakTable<Type, SkeletonFactory> _skeletonMap =
new ConditionalWeakTable<Type, SkeletonFactory>(); new ConditionalWeakTable<Type, SkeletonFactory>();
static ConditionalWeakTable<object, Skeleton> _implMap =
new ConditionalWeakTable<object, Skeleton>();
static CapabilityReflection() static CapabilityReflection()
{ {
@ -155,15 +157,23 @@ namespace Capnp.Rpc
/// <exception cref="System.Reflection.TargetInvocationException">Problem with instatiating the Skeleton (constructor threw exception).</exception> /// <exception cref="System.Reflection.TargetInvocationException">Problem with instatiating the Skeleton (constructor threw exception).</exception>
/// <exception cref="MemberAccessException">Caller does not have permission to invoke the Skeleton constructor.</exception> /// <exception cref="MemberAccessException">Caller does not have permission to invoke the Skeleton constructor.</exception>
/// <exception cref="TypeLoadException">Problem with building the Skeleton type, or problem with loading some dependent class.</exception> /// <exception cref="TypeLoadException">Problem with building the Skeleton type, or problem with loading some dependent class.</exception>
public static Skeleton CreateSkeleton(object obj) [Obsolete("Do not use this method directly. Instead, pass objects directly or use Proxy.Share<T>(). This method will be removed with next release.")]
public static Skeleton CreateSkeleton(object obj) => CreateSkeletonInternal(obj);
internal static Skeleton CreateSkeletonInternal(object obj)
{ {
if (obj == null) if (obj == null)
throw new ArgumentNullException(nameof(obj)); throw new ArgumentNullException(nameof(obj));
var factory = GetSkeletonFactory(obj.GetType()); var result = _implMap.GetValue(obj, _ =>
var skeleton = factory.NewSkeleton(); {
skeleton.Bind(obj); var factory = GetSkeletonFactory(_.GetType());
return skeleton; var skeleton = factory.NewSkeleton();
skeleton.Bind(obj);
return skeleton;
});
return result;
} }
static ProxyFactory GetProxyFactory(Type type) static ProxyFactory GetProxyFactory(Type type)

View File

@ -180,7 +180,7 @@ namespace Capnp.Rpc.Interception
break; break;
default: default:
Bob = Skeleton.GetOrCreateSkeleton(value, false); Bob = CapabilityReflection.CreateSkeletonInternal(value);
break; break;
} }

View File

@ -53,7 +53,7 @@ namespace Capnp.Rpc.Interception
default: default:
var temp = (CapabilityReflection.CreateProxy<TCap>( var temp = (CapabilityReflection.CreateProxy<TCap>(
Skeleton.GetOrCreateSkeleton(cap, false).AsCapability())) as TCap; CapabilityReflection.CreateSkeletonInternal(cap).AsCapability())) as TCap;
return Attach(policy, temp!)!; return Attach(policy, temp!)!;
} }
} }

View File

@ -1570,7 +1570,7 @@ namespace Capnp.Rpc
/// </summary> /// </summary>
public object Main public object Main
{ {
set { BootstrapCap = Skeleton.GetOrCreateSkeleton(value, false); } set { BootstrapCap = value is Skeleton skeleton ? skeleton : CapabilityReflection.CreateSkeletonInternal(value); }
} }
} }
} }

View File

@ -18,6 +18,7 @@ namespace Capnp.Rpc
public SkeletonRelinquisher(Skeleton skeleton) public SkeletonRelinquisher(Skeleton skeleton)
{ {
_skeleton = skeleton; _skeleton = skeleton;
_skeleton.Claim();
} }
public void Dispose() public void Dispose()
@ -26,28 +27,6 @@ namespace Capnp.Rpc
} }
} }
static readonly ConditionalWeakTable<object, Skeleton> _implMap =
new ConditionalWeakTable<object, Skeleton>();
internal static Skeleton GetOrCreateSkeleton<T>(T impl, bool addRef)
where T: class
{
if (impl == null)
throw new ArgumentNullException(nameof(impl));
if (impl is Skeleton skel)
return skel;
skel = _implMap.GetValue(impl, _ => CapabilityReflection.CreateSkeleton(_));
if (addRef)
{
skel.Claim();
}
return skel;
}
/// <summary> /// <summary>
/// Claims ownership on the given capability, preventing its automatic disposal. /// Claims ownership on the given capability, preventing its automatic disposal.
/// </summary> /// </summary>
@ -56,7 +35,7 @@ namespace Capnp.Rpc
/// <returns>A disposable object. Calling Dispose() on the returned instance relinquishes ownership again.</returns> /// <returns>A disposable object. Calling Dispose() on the returned instance relinquishes ownership again.</returns>
public static IDisposable Claim<T>(T impl) where T: class public static IDisposable Claim<T>(T impl) where T: class
{ {
return new SkeletonRelinquisher(GetOrCreateSkeleton(impl, true)); return new SkeletonRelinquisher(CapabilityReflection.CreateSkeletonInternal(impl));
} }
/// <summary> /// <summary>

View File

@ -1291,7 +1291,7 @@ namespace Capnp
case Rpc.Skeleton providedCapability: case Rpc.Skeleton providedCapability:
return ProvideCapability(providedCapability); return ProvideCapability(providedCapability);
default: default:
return ProvideCapability(Rpc.Skeleton.GetOrCreateSkeleton(obj, false)); return ProvideCapability(Rpc.CapabilityReflection.CreateSkeletonInternal(obj));
} }
} }