Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
NLua
Commits
b21a53bc
Unverified
Commit
b21a53bc
authored
Feb 12, 2019
by
Vinicius Jarina
Committed by
GitHub
Feb 12, 2019
Browse files
Fixed cleanup of Lua objects on LuaBase finalizer. (#282)
* Fixed cleanup of Lua objects on LuaBase finalizer.
parent
f4866b5f
Changes
7
Hide whitespace changes
Inline
Side-by-side
src/Lua.cs
View file @
b21a53bc
...
@@ -1084,9 +1084,15 @@ namespace NLua
...
@@ -1084,9 +1084,15 @@ namespace NLua
}
}
#
endregion
#
endregion
internal
void
DisposeInternal
(
int
reference
)
internal
void
DisposeInternal
(
int
reference
,
bool
finalized
)
{
{
if
(
_luaState
!=
null
)
if
(
finalized
&&
_translator
!=
null
)
{
_translator
.
AddFinalizedReference
(
reference
);
return
;
}
if
(
_luaState
!=
null
&&
!
finalized
)
_luaState
.
Unref
(
reference
);
_luaState
.
Unref
(
reference
);
}
}
...
...
src/LuaBase.cs
View file @
b21a53bc
...
@@ -9,10 +9,22 @@ namespace NLua
...
@@ -9,10 +9,22 @@ namespace NLua
{
{
private
bool
_disposed
;
private
bool
_disposed
;
protected
readonly
int
_Reference
;
protected
readonly
int
_Reference
;
protected
WeakReference
<
Lua
>
_
Interpreter
;
Lua
_
lua
;
protected
LuaBase
(
int
reference
)
protected
bool
TryGet
(
out
Lua
lua
)
{
{
if
(
_lua
.
State
==
null
)
{
lua
=
null
;
return
false
;
}
lua
=
_lua
;
return
true
;
}
protected
LuaBase
(
int
reference
,
Lua
lua
)
{
_lua
=
lua
;
_Reference
=
reference
;
_Reference
=
reference
;
}
}
...
@@ -27,27 +39,29 @@ namespace NLua
...
@@ -27,27 +39,29 @@ namespace NLua
GC
.
SuppressFinalize
(
this
);
GC
.
SuppressFinalize
(
this
);
}
}
void
DisposeLuaReference
()
void
DisposeLuaReference
(
bool
finalized
)
{
{
if
(
_
Interpreter
==
null
)
if
(
_
lua
==
null
)
return
;
return
;
Lua
lua
;
Lua
lua
;
if
(!
_Interpreter
.
TryGetTarg
et
(
out
lua
))
if
(!
TryG
et
(
out
lua
))
return
;
return
;
lua
.
DisposeInternal
(
_Reference
);
lua
.
DisposeInternal
(
_Reference
,
finalized
);
}
}
public
virtual
void
Dispose
(
bool
disposeManagedResources
)
public
virtual
void
Dispose
(
bool
disposeManagedResources
)
{
{
if
(
_disposed
)
if
(
_disposed
)
return
;
return
;
// TODO: Remove the disposeManagedResources check
if
(
_Reference
!=
0
&&
disposeManagedResources
)
bool
finalized
=
!
disposeManagedResources
;
if
(
_Reference
!=
0
)
{
{
DisposeLuaReference
();
DisposeLuaReference
(
finalized
);
}
}
_
Interpreter
=
null
;
_
lua
=
null
;
_disposed
=
true
;
_disposed
=
true
;
}
}
...
@@ -58,7 +72,7 @@ namespace NLua
...
@@ -58,7 +72,7 @@ namespace NLua
return
false
;
return
false
;
Lua
lua
;
Lua
lua
;
if
(!
_Interpreter
.
TryGetTarg
et
(
out
lua
))
if
(!
TryG
et
(
out
lua
))
return
false
;
return
false
;
return
lua
.
CompareRef
(
reference
.
_Reference
,
_Reference
);
return
lua
.
CompareRef
(
reference
.
_Reference
,
_Reference
);
...
...
src/LuaFunction.cs
View file @
b21a53bc
...
@@ -10,16 +10,14 @@ namespace NLua
...
@@ -10,16 +10,14 @@ namespace NLua
{
{
internal
readonly
LuaNativeFunction
function
;
internal
readonly
LuaNativeFunction
function
;
public
LuaFunction
(
int
reference
,
Lua
interpreter
):
base
(
reference
)
public
LuaFunction
(
int
reference
,
Lua
interpreter
):
base
(
reference
,
interpreter
)
{
{
function
=
null
;
function
=
null
;
_Interpreter
=
new
WeakReference
<
Lua
>(
interpreter
);
}
}
public
LuaFunction
(
LuaNativeFunction
nativeFunction
,
Lua
interpreter
):
base
(
0
)
public
LuaFunction
(
LuaNativeFunction
nativeFunction
,
Lua
interpreter
):
base
(
0
,
interpreter
)
{
{
function
=
nativeFunction
;
function
=
nativeFunction
;
_Interpreter
=
new
WeakReference
<
Lua
>(
interpreter
);
}
}
/*
/*
...
@@ -29,7 +27,7 @@ namespace NLua
...
@@ -29,7 +27,7 @@ namespace NLua
internal
object
[]
Call
(
object
[]
args
,
Type
[]
returnTypes
)
internal
object
[]
Call
(
object
[]
args
,
Type
[]
returnTypes
)
{
{
Lua
lua
;
Lua
lua
;
if
(!
_Interpreter
.
TryGetTarg
et
(
out
lua
))
if
(!
TryG
et
(
out
lua
))
return
null
;
return
null
;
return
lua
.
CallFunction
(
this
,
args
,
returnTypes
);
return
lua
.
CallFunction
(
this
,
args
,
returnTypes
);
...
@@ -42,8 +40,9 @@ namespace NLua
...
@@ -42,8 +40,9 @@ namespace NLua
public
object
[]
Call
(
params
object
[]
args
)
public
object
[]
Call
(
params
object
[]
args
)
{
{
Lua
lua
;
Lua
lua
;
if
(!
_Interpreter
.
TryGetTarg
et
(
out
lua
))
if
(!
TryG
et
(
out
lua
))
return
null
;
return
null
;
return
lua
.
CallFunction
(
this
,
args
);
return
lua
.
CallFunction
(
this
,
args
);
}
}
...
@@ -53,7 +52,7 @@ namespace NLua
...
@@ -53,7 +52,7 @@ namespace NLua
internal
void
Push
(
LuaState
luaState
)
internal
void
Push
(
LuaState
luaState
)
{
{
Lua
lua
;
Lua
lua
;
if
(!
_Interpreter
.
TryGetTarg
et
(
out
lua
))
if
(!
TryG
et
(
out
lua
))
return
;
return
;
if
(
_Reference
!=
0
)
if
(
_Reference
!=
0
)
...
@@ -75,7 +74,7 @@ namespace NLua
...
@@ -75,7 +74,7 @@ namespace NLua
return
false
;
return
false
;
Lua
lua
;
Lua
lua
;
if
(!
_Interpreter
.
TryGetTarg
et
(
out
lua
))
if
(!
TryG
et
(
out
lua
))
return
false
;
return
false
;
if
(
_Reference
!=
0
&&
l
.
_Reference
!=
0
)
if
(
_Reference
!=
0
&&
l
.
_Reference
!=
0
)
...
...
src/LuaTable.cs
View file @
b21a53bc
...
@@ -10,9 +10,8 @@ namespace NLua
...
@@ -10,9 +10,8 @@ namespace NLua
{
{
public
class
LuaTable
:
LuaBase
public
class
LuaTable
:
LuaBase
{
{
public
LuaTable
(
int
reference
,
Lua
interpreter
):
base
(
reference
)
public
LuaTable
(
int
reference
,
Lua
interpreter
):
base
(
reference
,
interpreter
)
{
{
_Interpreter
=
new
WeakReference
<
Lua
>(
interpreter
);
}
}
/*
/*
...
@@ -22,14 +21,14 @@ namespace NLua
...
@@ -22,14 +21,14 @@ namespace NLua
get
get
{
{
Lua
lua
;
Lua
lua
;
if
(!
_Interpreter
.
TryGetTarg
et
(
out
lua
))
if
(!
TryG
et
(
out
lua
))
return
null
;
return
null
;
return
lua
.
GetObject
(
_Reference
,
field
);
return
lua
.
GetObject
(
_Reference
,
field
);
}
}
set
set
{
{
Lua
lua
;
Lua
lua
;
if
(!
_Interpreter
.
TryGetTarg
et
(
out
lua
))
if
(!
TryG
et
(
out
lua
))
return
;
return
;
lua
.
SetObject
(
_Reference
,
field
,
value
);
lua
.
SetObject
(
_Reference
,
field
,
value
);
}
}
...
@@ -42,7 +41,7 @@ namespace NLua
...
@@ -42,7 +41,7 @@ namespace NLua
get
get
{
{
Lua
lua
;
Lua
lua
;
if
(!
_Interpreter
.
TryGetTarg
et
(
out
lua
))
if
(!
TryG
et
(
out
lua
))
return
null
;
return
null
;
return
lua
.
GetObject
(
_Reference
,
field
);
return
lua
.
GetObject
(
_Reference
,
field
);
...
@@ -50,7 +49,7 @@ namespace NLua
...
@@ -50,7 +49,7 @@ namespace NLua
set
set
{
{
Lua
lua
;
Lua
lua
;
if
(!
_Interpreter
.
TryGetTarg
et
(
out
lua
))
if
(!
TryG
et
(
out
lua
))
return
;
return
;
lua
.
SetObject
(
_Reference
,
field
,
value
);
lua
.
SetObject
(
_Reference
,
field
,
value
);
...
@@ -60,7 +59,7 @@ namespace NLua
...
@@ -60,7 +59,7 @@ namespace NLua
public
IDictionaryEnumerator
GetEnumerator
()
public
IDictionaryEnumerator
GetEnumerator
()
{
{
Lua
lua
;
Lua
lua
;
if
(!
_Interpreter
.
TryGetTarg
et
(
out
lua
))
if
(!
TryG
et
(
out
lua
))
return
null
;
return
null
;
return
lua
.
GetTableDict
(
this
).
GetEnumerator
();
return
lua
.
GetTableDict
(
this
).
GetEnumerator
();
...
@@ -71,7 +70,7 @@ namespace NLua
...
@@ -71,7 +70,7 @@ namespace NLua
get
get
{
{
Lua
lua
;
Lua
lua
;
if
(!
_Interpreter
.
TryGetTarg
et
(
out
lua
))
if
(!
TryG
et
(
out
lua
))
return
null
;
return
null
;
return
lua
.
GetTableDict
(
this
).
Keys
;
return
lua
.
GetTableDict
(
this
).
Keys
;
...
@@ -84,7 +83,7 @@ namespace NLua
...
@@ -84,7 +83,7 @@ namespace NLua
get
get
{
{
Lua
lua
;
Lua
lua
;
if
(!
_Interpreter
.
TryGetTarg
et
(
out
lua
))
if
(!
TryG
et
(
out
lua
))
return
null
;
return
null
;
return
lua
.
GetTableDict
(
this
).
Values
;
return
lua
.
GetTableDict
(
this
).
Values
;
...
@@ -99,7 +98,7 @@ namespace NLua
...
@@ -99,7 +98,7 @@ namespace NLua
internal
object
RawGet
(
string
field
)
internal
object
RawGet
(
string
field
)
{
{
Lua
lua
;
Lua
lua
;
if
(!
_Interpreter
.
TryGetTarg
et
(
out
lua
))
if
(!
TryG
et
(
out
lua
))
return
null
;
return
null
;
return
lua
.
RawGetObject
(
_Reference
,
field
);
return
lua
.
RawGetObject
(
_Reference
,
field
);
...
...
src/LuaUserData.cs
View file @
b21a53bc
...
@@ -5,9 +5,8 @@ namespace NLua
...
@@ -5,9 +5,8 @@ namespace NLua
{
{
public
class
LuaUserData
:
LuaBase
public
class
LuaUserData
:
LuaBase
{
{
public
LuaUserData
(
int
reference
,
Lua
interpreter
):
base
(
reference
)
public
LuaUserData
(
int
reference
,
Lua
interpreter
):
base
(
reference
,
interpreter
)
{
{
_Interpreter
=
new
WeakReference
<
Lua
>(
interpreter
);
}
}
/*
/*
...
@@ -17,7 +16,7 @@ namespace NLua
...
@@ -17,7 +16,7 @@ namespace NLua
get
get
{
{
Lua
lua
;
Lua
lua
;
if
(!
_Interpreter
.
TryGetTarg
et
(
out
lua
))
if
(!
TryG
et
(
out
lua
))
return
null
;
return
null
;
return
lua
.
GetObject
(
_Reference
,
field
);
return
lua
.
GetObject
(
_Reference
,
field
);
...
@@ -25,7 +24,7 @@ namespace NLua
...
@@ -25,7 +24,7 @@ namespace NLua
set
set
{
{
Lua
lua
;
Lua
lua
;
if
(!
_Interpreter
.
TryGetTarg
et
(
out
lua
))
if
(!
TryG
et
(
out
lua
))
return
;
return
;
lua
.
SetObject
(
_Reference
,
field
,
value
);
lua
.
SetObject
(
_Reference
,
field
,
value
);
...
@@ -39,7 +38,7 @@ namespace NLua
...
@@ -39,7 +38,7 @@ namespace NLua
get
get
{
{
Lua
lua
;
Lua
lua
;
if
(!
_Interpreter
.
TryGetTarg
et
(
out
lua
))
if
(!
TryG
et
(
out
lua
))
return
null
;
return
null
;
return
lua
.
GetObject
(
_Reference
,
field
);
return
lua
.
GetObject
(
_Reference
,
field
);
...
@@ -47,7 +46,7 @@ namespace NLua
...
@@ -47,7 +46,7 @@ namespace NLua
set
set
{
{
Lua
lua
;
Lua
lua
;
if
(!
_Interpreter
.
TryGetTarg
et
(
out
lua
))
if
(!
TryG
et
(
out
lua
))
return
;
return
;
lua
.
SetObject
(
_Reference
,
field
,
value
);
lua
.
SetObject
(
_Reference
,
field
,
value
);
...
@@ -61,7 +60,7 @@ namespace NLua
...
@@ -61,7 +60,7 @@ namespace NLua
public
object
[]
Call
(
params
object
[]
args
)
public
object
[]
Call
(
params
object
[]
args
)
{
{
Lua
lua
;
Lua
lua
;
if
(!
_Interpreter
.
TryGetTarg
et
(
out
lua
))
if
(!
TryG
et
(
out
lua
))
return
null
;
return
null
;
return
lua
.
CallFunction
(
this
,
args
);
return
lua
.
CallFunction
(
this
,
args
);
...
...
src/ObjectTranslator.cs
View file @
b21a53bc
...
@@ -49,6 +49,9 @@ namespace NLua
...
@@ -49,6 +49,9 @@ namespace NLua
readonly
Dictionary
<
object
,
int
>
_objectsBackMap
=
new
Dictionary
<
object
,
int
>(
new
ReferenceComparer
());
readonly
Dictionary
<
object
,
int
>
_objectsBackMap
=
new
Dictionary
<
object
,
int
>(
new
ReferenceComparer
());
// object # to object (FIXME - it should be possible to get object address as an object #)
// object # to object (FIXME - it should be possible to get object address as an object #)
readonly
Dictionary
<
int
,
object
>
_objects
=
new
Dictionary
<
int
,
object
>();
readonly
Dictionary
<
int
,
object
>
_objects
=
new
Dictionary
<
int
,
object
>();
readonly
Queue
<
int
>
finalizedReferences
=
new
Queue
<
int
>();
internal
EventHandlerContainer
PendingEvents
=
new
EventHandlerContainer
();
internal
EventHandlerContainer
PendingEvents
=
new
EventHandlerContainer
();
MetaFunctions
metaFunctions
;
MetaFunctions
metaFunctions
;
List
<
Assembly
>
assemblies
;
List
<
Assembly
>
assemblies
;
...
@@ -851,6 +854,9 @@ namespace NLua
...
@@ -851,6 +854,9 @@ namespace NLua
*/
*/
internal
LuaTable
GetTable
(
LuaState
luaState
,
int
index
)
internal
LuaTable
GetTable
(
LuaState
luaState
,
int
index
)
{
{
// Before create new tables, check if there is any finalized object to clean.
CleanFinalizedReferences
(
luaState
);
luaState
.
PushCopy
(
index
);
luaState
.
PushCopy
(
index
);
int
reference
=
luaState
.
Ref
(
LuaRegistry
.
Index
);
int
reference
=
luaState
.
Ref
(
LuaRegistry
.
Index
);
if
(
reference
==
-
1
)
if
(
reference
==
-
1
)
...
@@ -863,6 +869,9 @@ namespace NLua
...
@@ -863,6 +869,9 @@ namespace NLua
*/
*/
internal
LuaUserData
GetUserData
(
LuaState
luaState
,
int
index
)
internal
LuaUserData
GetUserData
(
LuaState
luaState
,
int
index
)
{
{
// Before create new tables, check if there is any finalized object to clean.
CleanFinalizedReferences
(
luaState
);
luaState
.
PushCopy
(
index
);
luaState
.
PushCopy
(
index
);
int
reference
=
luaState
.
Ref
(
LuaRegistry
.
Index
);
int
reference
=
luaState
.
Ref
(
LuaRegistry
.
Index
);
if
(
reference
==
-
1
)
if
(
reference
==
-
1
)
...
@@ -875,6 +884,9 @@ namespace NLua
...
@@ -875,6 +884,9 @@ namespace NLua
*/
*/
internal
LuaFunction
GetFunction
(
LuaState
luaState
,
int
index
)
internal
LuaFunction
GetFunction
(
LuaState
luaState
,
int
index
)
{
{
// Before create new tables, check if there is any finalized object to clean.
CleanFinalizedReferences
(
luaState
);
luaState
.
PushCopy
(
index
);
luaState
.
PushCopy
(
index
);
int
reference
=
luaState
.
Ref
(
LuaRegistry
.
Index
);
int
reference
=
luaState
.
Ref
(
LuaRegistry
.
Index
);
if
(
reference
==
-
1
)
if
(
reference
==
-
1
)
...
@@ -1102,5 +1114,22 @@ namespace NLua
...
@@ -1102,5 +1114,22 @@ namespace NLua
PushObject
(
luaState
,
res
,
"luaNet_metatable"
);
PushObject
(
luaState
,
res
,
"luaNet_metatable"
);
return
1
;
return
1
;
}
}
internal
void
AddFinalizedReference
(
int
reference
)
{
finalizedReferences
.
Enqueue
(
reference
);
}
void
CleanFinalizedReferences
(
LuaState
state
)
{
if
(
finalizedReferences
.
Count
==
0
)
return
;
while
(
finalizedReferences
.
Count
!=
0
)
{
int
reference
=
finalizedReferences
.
Dequeue
();
state
.
Unref
(
LuaRegistry
.
Index
,
reference
);
}
}
}
}
}
}
\ No newline at end of file
tests/src/LuaTests.cs
View file @
b21a53bc
...
@@ -2,8 +2,7 @@
...
@@ -2,8 +2,7 @@
using
System.Text
;
using
System.Text
;
using
System.Reflection
;
using
System.Reflection
;
using
System.Threading
;
using
System.Threading
;
using
KeraLua
;
using
NLua
;
using
NLua
;
using
NLua.Exceptions
;
using
NLua.Exceptions
;
...
@@ -13,6 +12,9 @@ using NLuaTest.TestTypes;
...
@@ -13,6 +12,9 @@ using NLuaTest.TestTypes;
using
NUnit.Framework
;
using
NUnit.Framework
;
using
Lua
=
NLua
.
Lua
;
using
LuaFunction
=
NLua
.
LuaFunction
;
// ReSharper disable StringLiteralTypo
// ReSharper disable StringLiteralTypo
namespace
NLuaTest
namespace
NLuaTest
...
@@ -2350,6 +2352,80 @@ namespace NLuaTest
...
@@ -2350,6 +2352,80 @@ namespace NLuaTest
}
}
}
}
[
Test
]
public
static
void
TestUseLuaObjectAfterDisposeShouldNotCrash
()
{
LuaTable
table
;
LuaFunction
function
;
using
(
var
lua
=
new
Lua
())
{
lua
.
DoString
(
"function F(a) return 2*a end"
);
function
=
lua
.
GetFunction
(
"F"
);
table
=
lua
.
DoString
(
"return { foo =\"Um dois tres\"}"
)
[
0
]
as
LuaTable
;
}
Assert
.
IsNotNull
(
function
);
Assert
.
IsNotNull
(
table
);
Assert
.
IsNull
(
table
[
"foo"
]);
var
result
=
function
.
Call
(
2
);
Assert
.
IsNull
(
result
);
}
void
ImplicitlyCreateATable
(
Lua
lua
)
{
var
x
=
lua
.
DoString
(
"return { foo = 1, bar = { la = 1 , la2 = 3, la4 = \"aidsjiasjdiasjdiajsdi\"} }"
)[
0
]
as
LuaTable
;
var
foo
=
x
[
"foo"
];
x
=
null
;
}
void
PleaseRunFinalizers
()
{
for
(
int
i
=
0
;
i
<
5
;
i
++)
{
GC
.
Collect
();
GC
.
WaitForPendingFinalizers
();
Thread
.
Sleep
(
0
);
}
}
///*
// * Tests if Lua objects are being released on finalizer
// */
[
Test
]
public
void
TestTableFinalizerDispose
()
{
using
(
Lua
lua
=
new
Lua
())
{
int
before
=
lua
.
State
.
GarbageCollector
(
LuaGC
.
Count
,
0
);
for
(
int
i
=
0
;
i
<
1000
;
i
++)
ImplicitlyCreateATable
(
lua
);
int
after1
=
lua
.
State
.
GarbageCollector
(
LuaGC
.
Count
,
0
);
PleaseRunFinalizers
();
ImplicitlyCreateATable
(
lua
);
lua
.
State
.
GarbageCollector
(
LuaGC
.
Collect
,
0
);
int
after2
=
lua
.
State
.
GarbageCollector
(
LuaGC
.
Count
,
0
);
int
ratio
=
after2
/
before
;
int
ratio2
=
after1
/
after2
;
// The ratio two is very uncertain, lets use 5x, just to have some certain that
// the gc collect the tables
Assert
.
True
(
ratio2
>=
5
,
"#1:"
+
ratio2
);
Assert
.
True
(
ratio
<=
1
,
"#2:"
+
ratio
);
}
}
static
Lua
m_lua
;
static
Lua
m_lua
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment