Switched to using SafeHandle for native code interrupt #297

Closed
itsff wants to merge 1 commits from fix/issue_295 into master
3 changed files with 97 additions and 79 deletions
Showing only changes of commit 0371d9f613 - Show all commits

View File

@@ -20,18 +20,40 @@ namespace Facebook.Yoga
private const string DllName = "yoga"; private const string DllName = "yoga";
#endif #endif
internal class YGNodeHandle : SafeHandle
{
private YGNodeHandle() : base(IntPtr.Zero, true)
{
}
public override bool IsInvalid
{
get
{
return this.handle == IntPtr.Zero;
}
}
protected override bool ReleaseHandle()
{
Native.YGNodeFree(this.handle);
GC.KeepAlive(this);
woehrl01 commented 2016-12-22 22:13:50 -08:00 (Migrated from github.com)
Review

Out of curiosity, why do we need the GC.KeepAlive here?

Out of curiosity, why do we need the GC.KeepAlive here?
itsff commented 2016-12-23 10:06:59 -08:00 (Migrated from github.com)
Review

Likely not necessary, but I wasn't sure of the implementation of the parent class. Shouldn't hurt.

Likely not necessary, but I wasn't sure of the implementation of the parent class. Shouldn't hurt.
return true;
}
}
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGInteropSetLogger( public static extern void YGInteropSetLogger(
[MarshalAs(UnmanagedType.FunctionPtr)] YogaLogger.Func func); [MarshalAs(UnmanagedType.FunctionPtr)] YogaLogger.Func func);
[DllImport(DllName)] [DllImport(DllName)]
public static extern IntPtr YGNodeNew(); public static extern YGNodeHandle YGNodeNew();
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeFree(IntPtr node); public static extern void YGNodeFree(IntPtr node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeReset(IntPtr node); public static extern void YGNodeReset(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern int YGNodeGetInstanceCount(); public static extern int YGNodeGetInstanceCount();
@@ -46,237 +68,237 @@ namespace Facebook.Yoga
YogaExperimentalFeature feature); YogaExperimentalFeature feature);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeInsertChild(IntPtr node, IntPtr child, uint index); public static extern void YGNodeInsertChild(YGNodeHandle node, YGNodeHandle child, uint index);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeRemoveChild(IntPtr node, IntPtr child); public static extern void YGNodeRemoveChild(YGNodeHandle node, YGNodeHandle child);
[DllImport(DllName)] [DllImport(DllName)]
public static extern IntPtr YGNodeGetChild(IntPtr node, uint index); public static extern YGNodeHandle YGNodeGetChild(YGNodeHandle node, uint index);
[DllImport(DllName)] [DllImport(DllName)]
public static extern uint YGNodeGetChildCount(IntPtr node); public static extern uint YGNodeGetChildCount(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeCalculateLayout(IntPtr node, public static extern void YGNodeCalculateLayout(YGNodeHandle node,
float availableWidth, float availableWidth,
float availableHeight, float availableHeight,
YogaDirection parentDirection); YogaDirection parentDirection);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeMarkDirty(IntPtr node); public static extern void YGNodeMarkDirty(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
public static extern bool YGNodeIsDirty(IntPtr node); public static extern bool YGNodeIsDirty(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodePrint(IntPtr node, YogaPrintOptions options); public static extern void YGNodePrint(YGNodeHandle node, YogaPrintOptions options);
[DllImport(DllName)] [DllImport(DllName)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
public static extern bool YGValueIsUndefined(float value); public static extern bool YGValueIsUndefined(float value);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeCopyStyle(IntPtr dstNode, IntPtr srcNode); public static extern void YGNodeCopyStyle(YGNodeHandle dstNode, YGNodeHandle srcNode);
#region YG_NODE_PROPERTY #region YG_NODE_PROPERTY
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeSetContext(IntPtr node, IntPtr context); public static extern void YGNodeSetContext(YGNodeHandle node, IntPtr context);
[DllImport(DllName)] [DllImport(DllName)]
public static extern IntPtr YGNodeGetContext(IntPtr node); public static extern IntPtr YGNodeGetContext(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeSetMeasureFunc( public static extern void YGNodeSetMeasureFunc(
IntPtr node, YGNodeHandle node,
[MarshalAs(UnmanagedType.FunctionPtr)] YogaMeasureFunc measureFunc); [MarshalAs(UnmanagedType.FunctionPtr)] YogaMeasureFunc measureFunc);
[DllImport(DllName)] [DllImport(DllName)]
[return: MarshalAs(UnmanagedType.FunctionPtr)] [return: MarshalAs(UnmanagedType.FunctionPtr)]
public static extern YogaMeasureFunc YGNodeGetMeasureFunc(IntPtr node); public static extern YogaMeasureFunc YGNodeGetMeasureFunc(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeSetHasNewLayout(IntPtr node, [MarshalAs(UnmanagedType.I1)] bool hasNewLayout); public static extern void YGNodeSetHasNewLayout(YGNodeHandle node, [MarshalAs(UnmanagedType.I1)] bool hasNewLayout);
woehrl01 commented 2016-12-22 22:12:54 -08:00 (Migrated from github.com)
Review

I think this must return only intptr as we don't own the underlying node here.

I think this must return only intptr as we don't own the underlying node here.
splhack commented 2016-12-23 07:55:40 -08:00 (Migrated from github.com)
Review

I'll remove this declaration in merge commit since managed code doesn't use it

I'll remove this declaration in merge commit since managed code doesn't use it
itsff commented 2016-12-23 10:06:04 -08:00 (Migrated from github.com)
Review

You guys beat me to it. Thank you for noticing this one (@woehrl01) and removing it (@splhack). It could have caused some confusion and lifetime problems. We should similarly remove YGNodeSetContext and YGNodeSetContext since this functionality is achieved by the YogaNode::Data property.

You guys beat me to it. Thank you for noticing this one (@woehrl01) and removing it (@splhack). It could have caused some confusion and lifetime problems. We should similarly remove `YGNodeSetContext` and `YGNodeSetContext` since this functionality is achieved by the `YogaNode::Data` property.
[DllImport(DllName)] [DllImport(DllName)]
[return: MarshalAs(UnmanagedType.I1)] [return: MarshalAs(UnmanagedType.I1)]
public static extern bool YGNodeGetHasNewLayout(IntPtr node); public static extern bool YGNodeGetHasNewLayout(YGNodeHandle node);
#endregion #endregion
#region YG_NODE_STYLE_PROPERTY #region YG_NODE_STYLE_PROPERTY
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetDirection(IntPtr node, YogaDirection direction); public static extern void YGNodeStyleSetDirection(YGNodeHandle node, YogaDirection direction);
[DllImport(DllName)] [DllImport(DllName)]
public static extern YogaDirection YGNodeStyleGetDirection(IntPtr node); public static extern YogaDirection YGNodeStyleGetDirection(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetFlexDirection(IntPtr node, YogaFlexDirection flexDirection); public static extern void YGNodeStyleSetFlexDirection(YGNodeHandle node, YogaFlexDirection flexDirection);
[DllImport(DllName)] [DllImport(DllName)]
public static extern YogaFlexDirection YGNodeStyleGetFlexDirection(IntPtr node); public static extern YogaFlexDirection YGNodeStyleGetFlexDirection(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetJustifyContent(IntPtr node, YogaJustify justifyContent); public static extern void YGNodeStyleSetJustifyContent(YGNodeHandle node, YogaJustify justifyContent);
[DllImport(DllName)] [DllImport(DllName)]
public static extern YogaJustify YGNodeStyleGetJustifyContent(IntPtr node); public static extern YogaJustify YGNodeStyleGetJustifyContent(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetAlignContent(IntPtr node, YogaAlign alignContent); public static extern void YGNodeStyleSetAlignContent(YGNodeHandle node, YogaAlign alignContent);
[DllImport(DllName)] [DllImport(DllName)]
public static extern YogaAlign YGNodeStyleGetAlignContent(IntPtr node); public static extern YogaAlign YGNodeStyleGetAlignContent(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetAlignItems(IntPtr node, YogaAlign alignItems); public static extern void YGNodeStyleSetAlignItems(YGNodeHandle node, YogaAlign alignItems);
[DllImport(DllName)] [DllImport(DllName)]
public static extern YogaAlign YGNodeStyleGetAlignItems(IntPtr node); public static extern YogaAlign YGNodeStyleGetAlignItems(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetAlignSelf(IntPtr node, YogaAlign alignSelf); public static extern void YGNodeStyleSetAlignSelf(YGNodeHandle node, YogaAlign alignSelf);
[DllImport(DllName)] [DllImport(DllName)]
public static extern YogaAlign YGNodeStyleGetAlignSelf(IntPtr node); public static extern YogaAlign YGNodeStyleGetAlignSelf(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetPositionType(IntPtr node, YogaPositionType positionType); public static extern void YGNodeStyleSetPositionType(YGNodeHandle node, YogaPositionType positionType);
[DllImport(DllName)] [DllImport(DllName)]
public static extern YogaPositionType YGNodeStyleGetPositionType(IntPtr node); public static extern YogaPositionType YGNodeStyleGetPositionType(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetFlexWrap(IntPtr node, YogaWrap flexWrap); public static extern void YGNodeStyleSetFlexWrap(YGNodeHandle node, YogaWrap flexWrap);
[DllImport(DllName)] [DllImport(DllName)]
public static extern YogaWrap YGNodeStyleGetFlexWrap(IntPtr node); public static extern YogaWrap YGNodeStyleGetFlexWrap(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetOverflow(IntPtr node, YogaOverflow flexWrap); public static extern void YGNodeStyleSetOverflow(YGNodeHandle node, YogaOverflow flexWrap);
[DllImport(DllName)] [DllImport(DllName)]
public static extern YogaOverflow YGNodeStyleGetOverflow(IntPtr node); public static extern YogaOverflow YGNodeStyleGetOverflow(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetFlex(IntPtr node, float flex); public static extern void YGNodeStyleSetFlex(YGNodeHandle node, float flex);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetFlexGrow(IntPtr node, float flexGrow); public static extern void YGNodeStyleSetFlexGrow(YGNodeHandle node, float flexGrow);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetFlexGrow(IntPtr node); public static extern float YGNodeStyleGetFlexGrow(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetFlexShrink(IntPtr node, float flexShrink); public static extern void YGNodeStyleSetFlexShrink(YGNodeHandle node, float flexShrink);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetFlexShrink(IntPtr node); public static extern float YGNodeStyleGetFlexShrink(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetFlexBasis(IntPtr node, float flexBasis); public static extern void YGNodeStyleSetFlexBasis(YGNodeHandle node, float flexBasis);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetFlexBasis(IntPtr node); public static extern float YGNodeStyleGetFlexBasis(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetWidth(IntPtr node, float width); public static extern void YGNodeStyleSetWidth(YGNodeHandle node, float width);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetWidth(IntPtr node); public static extern float YGNodeStyleGetWidth(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetHeight(IntPtr node, float height); public static extern void YGNodeStyleSetHeight(YGNodeHandle node, float height);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetHeight(IntPtr node); public static extern float YGNodeStyleGetHeight(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetMinWidth(IntPtr node, float minWidth); public static extern void YGNodeStyleSetMinWidth(YGNodeHandle node, float minWidth);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetMinWidth(IntPtr node); public static extern float YGNodeStyleGetMinWidth(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetMinHeight(IntPtr node, float minHeight); public static extern void YGNodeStyleSetMinHeight(YGNodeHandle node, float minHeight);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetMinHeight(IntPtr node); public static extern float YGNodeStyleGetMinHeight(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetMaxWidth(IntPtr node, float maxWidth); public static extern void YGNodeStyleSetMaxWidth(YGNodeHandle node, float maxWidth);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetMaxWidth(IntPtr node); public static extern float YGNodeStyleGetMaxWidth(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetMaxHeight(IntPtr node, float maxHeight); public static extern void YGNodeStyleSetMaxHeight(YGNodeHandle node, float maxHeight);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetMaxHeight(IntPtr node); public static extern float YGNodeStyleGetMaxHeight(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetAspectRatio(IntPtr node, float aspectRatio); public static extern void YGNodeStyleSetAspectRatio(YGNodeHandle node, float aspectRatio);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetAspectRatio(IntPtr node); public static extern float YGNodeStyleGetAspectRatio(YGNodeHandle node);
#endregion #endregion
#region YG_NODE_STYLE_EDGE_PROPERTY #region YG_NODE_STYLE_EDGE_PROPERTY
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetPosition(IntPtr node, YogaEdge edge, float position); public static extern void YGNodeStyleSetPosition(YGNodeHandle node, YogaEdge edge, float position);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetPosition(IntPtr node, YogaEdge edge); public static extern float YGNodeStyleGetPosition(YGNodeHandle node, YogaEdge edge);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetMargin(IntPtr node, YogaEdge edge, float margin); public static extern void YGNodeStyleSetMargin(YGNodeHandle node, YogaEdge edge, float margin);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetMargin(IntPtr node, YogaEdge edge); public static extern float YGNodeStyleGetMargin(YGNodeHandle node, YogaEdge edge);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetPadding(IntPtr node, YogaEdge edge, float padding); public static extern void YGNodeStyleSetPadding(YGNodeHandle node, YogaEdge edge, float padding);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetPadding(IntPtr node, YogaEdge edge); public static extern float YGNodeStyleGetPadding(YGNodeHandle node, YogaEdge edge);
[DllImport(DllName)] [DllImport(DllName)]
public static extern void YGNodeStyleSetBorder(IntPtr node, YogaEdge edge, float border); public static extern void YGNodeStyleSetBorder(YGNodeHandle node, YogaEdge edge, float border);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeStyleGetBorder(IntPtr node, YogaEdge edge); public static extern float YGNodeStyleGetBorder(YGNodeHandle node, YogaEdge edge);
#endregion #endregion
#region YG_NODE_LAYOUT_PROPERTY #region YG_NODE_LAYOUT_PROPERTY
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeLayoutGetLeft(IntPtr node); public static extern float YGNodeLayoutGetLeft(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeLayoutGetTop(IntPtr node); public static extern float YGNodeLayoutGetTop(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeLayoutGetRight(IntPtr node); public static extern float YGNodeLayoutGetRight(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeLayoutGetBottom(IntPtr node); public static extern float YGNodeLayoutGetBottom(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeLayoutGetWidth(IntPtr node); public static extern float YGNodeLayoutGetWidth(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern float YGNodeLayoutGetHeight(IntPtr node); public static extern float YGNodeLayoutGetHeight(YGNodeHandle node);
[DllImport(DllName)] [DllImport(DllName)]
public static extern YogaDirection YGNodeLayoutGetDirection(IntPtr node); public static extern YogaDirection YGNodeLayoutGetDirection(YGNodeHandle node);
#endregion #endregion
} }

View File

@@ -17,7 +17,7 @@ namespace Facebook.Yoga
{ {
public partial class YogaNode : IEnumerable<YogaNode> public partial class YogaNode : IEnumerable<YogaNode>
{ {
private IntPtr _ygNode; private Native.YGNodeHandle _ygNode;
private WeakReference _parent; private WeakReference _parent;
private List<YogaNode> _children; private List<YogaNode> _children;
private MeasureFunction _measureFunction; private MeasureFunction _measureFunction;
@@ -29,17 +29,12 @@ namespace Facebook.Yoga
YogaLogger.Initialize(); YogaLogger.Initialize();
_ygNode = Native.YGNodeNew(); _ygNode = Native.YGNodeNew();
if (_ygNode == IntPtr.Zero) if (_ygNode.IsInvalid)
{ {
throw new InvalidOperationException("Failed to allocate native memory"); throw new InvalidOperationException("Failed to allocate native memory");
} }
} }
~YogaNode()
{
Native.YGNodeFree(_ygNode);
}
public void Reset() public void Reset()
{ {
_measureFunction = null; _measureFunction = null;

View File

@@ -3,7 +3,8 @@
"version": "3.0.0-*", "version": "3.0.0-*",
"dependencies": { "dependencies": {
"NETStandard.Library": "1.6.0" "NETStandard.Library": "1.6.0",
"System.Runtime.Handles": "4.3.0"
}, },
"frameworks": { "frameworks": {