-
Notifications
You must be signed in to change notification settings - Fork 747
Add soft shutdown #958
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add soft shutdown #958
Changes from 1 commit
d1928dc
f000e08
f882400
b7715ee
41ac665
c6dae9e
4e19a4f
657452e
91f64b9
b07b844
7db724e
2a88be4
2940973
d108913
cc9e7e5
1cb8e8c
653a263
b3e889b
04d6dfb
5150e61
65e209e
cad95da
0dee5da
00a0b32
77da6df
2039e69
fe5050d
593fb00
1ce83fc
fba616a
bdc0f72
49d98e8
433d0f6
9b4864b
1b466df
49130c4
76ba510
1ff21ac
0b01378
631bb43
bf3d9f8
da97502
e8b3160
80d4fa0
9874cd1
8da561b
9499c64
431d644
2b84394
5ade069
8dabed7
f4bb77a
670bd74
3cb56f1
3c9a83c
992c469
924b217
df84e29
8b51621
97c8c2a
39f47c8
aa63f0b
5b2f3d4
35cbe55
f23cae6
183f9d8
9d57a82
08fad26
bcfdcc7
66ab719
1428af3
8e3c028
b387e9e
f85999e
cb65af3
498fc8c
cc2219e
8c8d66e
4f00165
39e20e3
da7c150
02b1ada
a8840b2
dec7a74
e877b33
6d738bf
ff5edc3
5ac75ba
65cb22e
73865d4
1a75f51
9b6d140
d9d5562
9b62a61
4f0420e
4ab9f1c
32bcb3a
0077ea8
38ea0b6
06a656e
09f8281
7ec9a6c
802a43a
0fdf969
3a8c72d
b52bc01
bfbf2c3
883c4ce
7e0d56d
82034dc
4ba50a7
1ecdce8
b35f441
ce8ee90
4c4bcb0
f575bd3
d1799aa
d2408b9
fd2b662
2b7bcac
0af3504
ba1df6e
639ba1f
7e5ab52
8075f48
eb8cb8a
308f0f2
1ae0bfe
07aefe6
5387b05
b203674
19d1379
25a4064
1272b89
8c133e3
d9b21a5
c8dee53
598cb77
83e8dd5
6db3181
e38a363
b409a89
f5c24b0
0d6c645
fa89b48
80a7644
12c0206
6a3cfc8
98da1fa
d7d44e8
6aa75c5
2343f89
cc6b8e4
d5fcfa4
fa47957
ff956e4
c7b134c
97e61a5
0b9d2c1
178cbc8
3a17f36
3203457
8d00e4c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
…down
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -70,7 +70,7 @@ internal static void Stash() | |
Marshal.WriteIntPtr(mem, (IntPtr)ms.Length); | ||
Marshal.Copy(data, 0, mem + IntPtr.Size, (int)ms.Length); | ||
|
||
IntPtr capsule = PySys_GetObject("clr_data"); | ||
IntPtr capsule = PySys_GetObject("clr_data").DangerousGetAddress(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why can't this work with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It could, but it would not improve readability. While we do get a borrowed reference, we really do own this reference. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not so sure. It took some time to figure out, that in 73-80 Maybe extract clearing of existing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, I get what you are saying now. I'll factor out the clearing. |
||
if (capsule != IntPtr.Zero) | ||
{ | ||
IntPtr oldData = PyCapsule_GetPointer(capsule, null); | ||
|
@@ -96,7 +96,7 @@ internal static void StashPop() | |
|
||
private static void StashPopImpl() | ||
{ | ||
IntPtr capsule = PySys_GetObject("clr_data"); | ||
IntPtr capsule = PySys_GetObject("clr_data").DangerousGetAddress(); | ||
if (capsule == IntPtr.Zero) | ||
{ | ||
return; | ||
|
@@ -129,7 +129,7 @@ private static void StashPopImpl() | |
|
||
public static bool HasStashData() | ||
{ | ||
return PySys_GetObject("clr_data") != IntPtr.Zero; | ||
return !PySys_GetObject("clr_data").IsNull; | ||
} | ||
|
||
public static void ClearStash() | ||
|
@@ -248,8 +248,7 @@ private static Dictionary<ManagedType, PyObjectSerializeContext> StashPopObjects | |
private static void StashPushModules(RuntimeDataStorage storage) | ||
{ | ||
var pyModules = PyImport_GetModuleDict(); | ||
var itemsRef = PyDict_Items(pyModules); | ||
var items = itemsRef.DangerousGetAddress(); | ||
var items = PyDict_Items(pyModules); | ||
long length = PyList_Size(items); | ||
var modules = new Dictionary<IntPtr, IntPtr>(); ; | ||
for (long i = 0; i < length; i++) | ||
|
@@ -264,7 +263,7 @@ private static void StashPushModules(RuntimeDataStorage storage) | |
modules.Add(name, module); | ||
} | ||
} | ||
itemsRef.Dispose(); | ||
items.Dispose(); | ||
storage.AddValue("modules", modules); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,7 +14,7 @@ class RuntimeState | |
|
||
public static void Save() | ||
{ | ||
if (PySys_GetObject("dummy_gc") != IntPtr.Zero) | ||
if (!PySys_GetObject("dummy_gc").IsNull) | ||
{ | ||
throw new Exception("Runtime State set already"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use |
||
} | ||
|
@@ -79,7 +79,7 @@ public static void Save() | |
|
||
public static void Restore() | ||
{ | ||
var dummyGCAddr = PySys_GetObject("dummy_gc"); | ||
var dummyGCAddr = PySys_GetObject("dummy_gc").DangerousGetAddress(); | ||
if (dummyGCAddr == IntPtr.Zero) | ||
{ | ||
throw new InvalidOperationException("Runtime state have not set"); | ||
|
@@ -95,11 +95,11 @@ public static void Restore() | |
private static void ResotreModules(IntPtr dummyGC) | ||
{ | ||
var intialModules = PySys_GetObject("initial_modules"); | ||
Debug.Assert(intialModules != IntPtr.Zero); | ||
Debug.Assert(!intialModules.IsNull); | ||
var modules = PyImport_GetModuleDict(); | ||
foreach (var name in GetModuleNames()) | ||
{ | ||
if (PySet_Contains(intialModules, name) == 1) | ||
if (PySet_Contains(intialModules.DangerousGetAddress(), name) == 1) | ||
{ | ||
continue; | ||
} | ||
|
@@ -122,7 +122,7 @@ private static void RestoreObjects(IntPtr dummyGC) | |
{ | ||
throw new Exception("To prevent crash by _PyObject_GC_UNTRACK in Python internal, UseDummyGC should be enabled when using ResotreObjects"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use |
||
} | ||
IntPtr intialObjs = PySys_GetObject("initial_objs"); | ||
IntPtr intialObjs = PySys_GetObject("initial_objs").DangerousGetAddress(); | ||
Debug.Assert(intialObjs != IntPtr.Zero); | ||
foreach (var obj in PyGCGetObjects()) | ||
{ | ||
|
@@ -149,10 +149,10 @@ public static IEnumerable<IntPtr> PyGCGetObjects() | |
PythonException.ThrowIfIsNull(gc); | ||
var get_objects = PyObject_GetAttrString(gc, "get_objects"); | ||
var objs = PyObject_CallObject(get_objects, IntPtr.Zero); | ||
var length = PyList_Size(objs); | ||
var length = PyList_Size(new BorrowedReference(objs)); | ||
for (long i = 0; i < length; i++) | ||
{ | ||
var obj = PyList_GetItem(objs, i); | ||
var obj = PyList_GetItem(new BorrowedReference(objs), i); | ||
yield return obj.DangerousGetAddress(); | ||
} | ||
XDecref(objs); | ||
|
@@ -163,10 +163,10 @@ public static IEnumerable<IntPtr> GetModuleNames() | |
{ | ||
var modules = PyImport_GetModuleDict(); | ||
var names = PyDict_Keys(modules); | ||
var length = PyList_Size(names); | ||
var length = PyList_Size(new BorrowedReference(names)); | ||
for (int i = 0; i < length; i++) | ||
{ | ||
var name = PyList_GetItem(names, i); | ||
var name = PyList_GetItem(new BorrowedReference(names), i); | ||
yield return name.DangerousGetAddress(); | ||
} | ||
XDecref(names); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should not be changed. If a function is needed, that allows access to the raw pointer when it is
null
, it should be a separate function for clarity.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add an unchecked version
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That checking is not necessary, because the method already named DangerousXXX, why it even can't obtain a null pointer. If it needs some null validation, it should do by the invoker not the internal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@amos402 if the check is missed by accident by the invoker, the bug would be much easier to trace if it fails at the first access rather than much later on, when the raw null pointer is actually dereferenced.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I concern is the method conformed the single responsibility or not. It is unfit that a method like this can't obtain a null pointer. For example,
std::shared_ptr<T>::get
can illustrate this point.Anyway, I don't want to argue about this, if you insist, just check it, I don't mind it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tend to agree with @amos402, a method prefixed with
Dangerous
should let me do dangerous things. However, I think this modification should go in another PR as it modifies the current behaviour, and adding a checked version would add up a lot of changes all over the place.