Skip to content

Commit 51dfb5b

Browse files
committed
[GR-35002] Cancel FileIO finalizer if initialization fails.
PullRequest: graalpython/2040
2 parents 5b3dfa1 + 90246cd commit 51dfb5b

29 files changed

+305
-228
lines changed

graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_fileio.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
*graalpython.lib-python.3.test.test_fileio.COtherFileTests.testTruncateOnWindows
4242
*graalpython.lib-python.3.test.test_fileio.COtherFileTests.testUnclosedFDOnException
4343
*graalpython.lib-python.3.test.test_fileio.COtherFileTests.testUnicodeOpen
44+
*graalpython.lib-python.3.test.test_fileio.COtherFileTests.testBytesOpen
45+
*graalpython.lib-python.3.test.test_fileio.COtherFileTests.testUtf8BytesOpen
4446
*graalpython.lib-python.3.test.test_fileio.COtherFileTests.testWarnings
4547
*graalpython.lib-python.3.test.test_fileio.COtherFileTests.test_open_code
4648
*graalpython.lib-python.3.test.test_fileio.PyAutoFileTests.testAttributes
@@ -85,6 +87,8 @@
8587
*graalpython.lib-python.3.test.test_fileio.PyOtherFileTests.testTruncateOnWindows
8688
*graalpython.lib-python.3.test.test_fileio.PyOtherFileTests.testUnclosedFDOnException
8789
*graalpython.lib-python.3.test.test_fileio.PyOtherFileTests.testUnicodeOpen
90+
*graalpython.lib-python.3.test.test_fileio.PyOtherFileTests.testBytesOpen
91+
*graalpython.lib-python.3.test.test_fileio.PyOtherFileTests.testUtf8BytesOpen
8892
*graalpython.lib-python.3.test.test_fileio.PyOtherFileTests.testWarnings
8993
*graalpython.lib-python.3.test.test_fileio.PyOtherFileTests.test_open_code
9094
*graalpython.lib-python.3.test.test_fileio.TestMain.test_main

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixModuleBuiltins.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -523,13 +523,19 @@ protected ArgumentClinicProvider getArgumentClinic() {
523523

524524
@Specialization
525525
PNone close(VirtualFrame frame, int fd,
526-
@CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib) {
526+
@CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
527+
@Cached GilNode gil) {
527528
try {
528529
PythonContext ctx = getContext();
529530
if (ctx.getSharedMultiprocessingData().decrementFDRefCount(fd)) {
530531
return PNone.NONE;
531532
}
532-
posixLib.close(getPosixSupport(), fd);
533+
gil.release(true);
534+
try {
535+
posixLib.close(getPosixSupport(), fd);
536+
} finally {
537+
gil.acquire();
538+
}
533539
return PNone.NONE;
534540
} catch (PosixException e) {
535541
throw raiseOSErrorFromPosixException(frame, e);
@@ -816,11 +822,17 @@ protected ArgumentClinicProvider getArgumentClinic() {
816822
PNone ftruncate(VirtualFrame frame, int fd, long length,
817823
@CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib,
818824
@Cached SysModuleBuiltins.AuditNode auditNode,
825+
@Cached GilNode gil,
819826
@Cached BranchProfile errorProfile) {
820827
auditNode.audit("os.truncate", fd, length);
821828
while (true) {
822829
try {
823-
posixLib.ftruncate(getPosixSupport(), fd, length);
830+
gil.release(true);
831+
try {
832+
posixLib.ftruncate(getPosixSupport(), fd, length);
833+
} finally {
834+
gil.acquire();
835+
}
824836
return PNone.NONE;
825837
} catch (PosixException e) {
826838
errorProfile.enter();

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/AbstractBufferedIOBuiltins.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@
4949
import com.oracle.graal.python.PythonLanguage;
5050
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
5151
import com.oracle.graal.python.builtins.PythonBuiltins;
52+
import com.oracle.graal.python.builtins.modules.io.BufferedIONodes.RawTellNode;
53+
import com.oracle.graal.python.builtins.modules.io.BufferedIONodesFactory.RawTellNodeGen;
5254
import com.oracle.graal.python.builtins.objects.PNone;
5355
import com.oracle.graal.python.builtins.objects.exception.OSErrorEnum;
5456
import com.oracle.graal.python.builtins.objects.exception.PBaseException;
@@ -63,6 +65,7 @@
6365
import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
6466
import com.oracle.graal.python.nodes.object.GetClassNode;
6567
import com.oracle.graal.python.runtime.PosixSupportLibrary;
68+
import com.oracle.graal.python.runtime.PosixSupportLibrary.PosixException;
6669
import com.oracle.graal.python.runtime.PythonOptions;
6770
import com.oracle.graal.python.runtime.exception.PException;
6871
import com.oracle.graal.python.runtime.object.PythonObjectFactory;
@@ -78,7 +81,7 @@ abstract class AbstractBufferedIOBuiltins extends PythonBuiltins {
7881

7982
public abstract static class BufferedInitNode extends PNodeWithRaise {
8083

81-
@Child BufferedIONodes.RawTellNode rawTellNode = BufferedIONodesFactory.RawTellNodeGen.create(true);
84+
@Child private RawTellNode rawTellNode = RawTellNodeGen.create(true);
8285

8386
public abstract void execute(VirtualFrame frame, PBuffered self, int bufferSize, PythonObjectFactory factory);
8487

@@ -94,7 +97,7 @@ void bufferSizeError(PBuffered self, int bufferSize, PythonObjectFactory factory
9497
throw raise(ValueError, BUF_SIZE_POS);
9598
}
9699

97-
public static void init(PBuffered self, int bufferSize, PythonObjectFactory factory) {
100+
private static void init(PBuffered self, int bufferSize, PythonObjectFactory factory) {
98101
self.initBuffer(bufferSize);
99102
self.setLock(factory.createLock());
100103
self.setOwner(0);
@@ -111,7 +114,7 @@ public static void internalInit(PBuffered self, int bufferSize, PythonObjectFact
111114
init(self, bufferSize, factory);
112115
try {
113116
FileIOBuiltins.TellNode.internalTell(self.getFileIORaw(), posixSupport, posixLib);
114-
} catch (PosixSupportLibrary.PosixException e) {
117+
} catch (PosixException e) {
115118
// ignore.. it's ok if it's not seekable
116119
}
117120
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedIOMixinBuiltins.java

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@
7777
import com.oracle.graal.python.annotations.ArgumentClinic;
7878
import com.oracle.graal.python.builtins.Builtin;
7979
import com.oracle.graal.python.builtins.CoreFunctions;
80+
import com.oracle.graal.python.builtins.modules.io.BufferedIONodes.CheckIsClosedNode;
81+
import com.oracle.graal.python.builtins.modules.io.BufferedIONodes.EnterBufferedNode;
82+
import com.oracle.graal.python.builtins.modules.io.BufferedIONodes.FlushAndRewindUnlockedNode;
83+
import com.oracle.graal.python.builtins.modules.io.BufferedIONodes.RawTellNode;
8084
import com.oracle.graal.python.builtins.objects.PNone;
8185
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
8286
import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs;
@@ -104,7 +108,7 @@
104108
import com.oracle.truffle.api.profiles.ConditionProfile;
105109

106110
@CoreFunctions(extendClasses = {PBufferedReader, PBufferedWriter, PBufferedRandom})
107-
public class BufferedIOMixinBuiltins extends AbstractBufferedIOBuiltins {
111+
public final class BufferedIOMixinBuiltins extends AbstractBufferedIOBuiltins {
108112
@Override
109113
protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFactories() {
110114
return BufferedIOMixinBuiltinsFactory.getFactories();
@@ -115,7 +119,7 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
115119
abstract static class CloseNode extends PythonUnaryWithInitErrorBuiltinNode {
116120

117121
private static Object close(VirtualFrame frame, PBuffered self,
118-
BufferedIONodes.EnterBufferedNode lock,
122+
EnterBufferedNode lock,
119123
PyObjectCallMethodObjArgs callMethodClose) {
120124
try {
121125
lock.enter(self);
@@ -125,7 +129,7 @@ private static Object close(VirtualFrame frame, PBuffered self,
125129
}
126130
return res;
127131
} finally {
128-
BufferedIONodes.EnterBufferedNode.leave(self);
132+
EnterBufferedNode.leave(self);
129133
}
130134
}
131135

@@ -135,7 +139,7 @@ static Object doit(VirtualFrame frame, PBuffered self,
135139
@Cached PyObjectCallMethodObjArgs callMethodFlush,
136140
@Cached PyObjectCallMethodObjArgs callMethodClose,
137141
@Cached PyObjectCallMethodObjArgs callMethodDeallocWarn,
138-
@Cached BufferedIONodes.EnterBufferedNode lock,
142+
@Cached EnterBufferedNode lock,
139143
@Cached ConditionProfile profile) {
140144
try {
141145
lock.enter(self);
@@ -148,7 +152,7 @@ static Object doit(VirtualFrame frame, PBuffered self,
148152
}
149153
}
150154
} finally {
151-
BufferedIONodes.EnterBufferedNode.leave(self);
155+
EnterBufferedNode.leave(self);
152156
}
153157
/* flush() will most probably re-take the lock, so drop it first */
154158
try {
@@ -245,7 +249,7 @@ protected static boolean isSupportedWhence(int whence) {
245249

246250
@Specialization(guards = {"self.isOK()", "isSupportedWhence(whence)"})
247251
static long doit(VirtualFrame frame, PBuffered self, Object off, int whence,
248-
@Cached("create(SEEK)") BufferedIONodes.CheckIsClosedNode checkIsClosedNode,
252+
@Cached("create(SEEK)") CheckIsClosedNode checkIsClosedNode,
249253
@Cached BufferedIONodes.CheckIsSeekabledNode checkIsSeekabledNode,
250254
@Cached BufferedIONodes.AsOffNumberNode asOffNumberNode,
251255
@Cached BufferedIONodes.SeekNode seekNode) {
@@ -275,7 +279,7 @@ Object initError(PBuffered self, @SuppressWarnings("unused") int off, @SuppressW
275279
abstract static class TellNode extends PythonUnaryWithInitErrorBuiltinNode {
276280
@Specialization(guards = "self.isOK()")
277281
static long doit(VirtualFrame frame, PBuffered self,
278-
@Cached BufferedIONodes.RawTellNode rawTellNode) {
282+
@Cached RawTellNode rawTellNode) {
279283
long pos = rawTellNode.execute(frame, self);
280284
pos -= rawOffset(self);
281285
/* TODO: sanity check (pos >= 0) */
@@ -295,10 +299,10 @@ protected ArgumentClinicProvider getArgumentClinic() {
295299

296300
@Specialization(guards = {"self.isOK()", "self.isWritable()"})
297301
static Object doit(VirtualFrame frame, PBuffered self, Object pos,
298-
@Cached BufferedIONodes.EnterBufferedNode lock,
299-
@Cached("create(TRUNCATE)") BufferedIONodes.CheckIsClosedNode checkIsClosedNode,
300-
@Cached BufferedIONodes.RawTellNode rawTellNode,
301-
@Cached BufferedIONodes.FlushAndRewindUnlockedNode flushAndRewindUnlockedNode,
302+
@Cached EnterBufferedNode lock,
303+
@Cached("create(TRUNCATE)") CheckIsClosedNode checkIsClosedNode,
304+
@Cached RawTellNode rawTellNode,
305+
@Cached FlushAndRewindUnlockedNode flushAndRewindUnlockedNode,
302306
@Cached PyObjectCallMethodObjArgs callMethodTruncate) {
303307
checkIsClosedNode.execute(frame, self);
304308
try {
@@ -309,7 +313,7 @@ static Object doit(VirtualFrame frame, PBuffered self, Object pos,
309313
rawTellNode.execute(frame, self);
310314
return res;
311315
} finally {
312-
BufferedIONodes.EnterBufferedNode.leave(self);
316+
EnterBufferedNode.leave(self);
313317
}
314318
}
315319

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedRandomBuiltins.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
import com.oracle.truffle.api.nodes.Node;
5959

6060
@CoreFunctions(extendClasses = PBufferedRandom)
61-
public class BufferedRandomBuiltins extends AbstractBufferedIOBuiltins {
61+
public final class BufferedRandomBuiltins extends AbstractBufferedIOBuiltins {
6262
@Override
6363
protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFactories() {
6464
return BufferedRandomBuiltinsFactory.getFactories();
@@ -96,7 +96,7 @@ static void doInit(VirtualFrame frame, PBuffered self, Object raw, int bufferSiz
9696
@GenerateNodeFactory
9797
public abstract static class InitNode extends BaseInitNode {
9898

99-
@Child BufferedRandomInit init = BufferedRandomBuiltinsFactory.BufferedRandomInitNodeGen.create();
99+
@Child private BufferedRandomInit init = BufferedRandomBuiltinsFactory.BufferedRandomInitNodeGen.create();
100100

101101
@Override
102102
protected final void init(VirtualFrame frame, PBuffered self, Object raw, int bufferSize) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedReaderBuiltins.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848

4949
import com.oracle.graal.python.builtins.Builtin;
5050
import com.oracle.graal.python.builtins.CoreFunctions;
51+
import com.oracle.graal.python.builtins.modules.io.BufferedReaderBuiltinsFactory.BufferedReaderInitNodeGen;
5152
import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs;
5253
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
5354
import com.oracle.graal.python.nodes.object.GetClassNode;
@@ -61,7 +62,7 @@
6162
import com.oracle.truffle.api.nodes.Node;
6263

6364
@CoreFunctions(extendClasses = PBufferedReader)
64-
public class BufferedReaderBuiltins extends AbstractBufferedIOBuiltins {
65+
public final class BufferedReaderBuiltins extends AbstractBufferedIOBuiltins {
6566
@Override
6667
protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFactories() {
6768
return BufferedReaderBuiltinsFactory.getFactories();
@@ -94,7 +95,6 @@ public static void internalInit(PBuffered self, PFileIO raw, int bufferSize, Pyt
9495
BufferedInitNode.internalInit(self, bufferSize, factory, posixSupport, posixLib);
9596
self.resetRead();
9697
self.setOK(true);
97-
9898
}
9999
}
100100

@@ -103,7 +103,7 @@ public static void internalInit(PBuffered self, PFileIO raw, int bufferSize, Pyt
103103
@GenerateNodeFactory
104104
public abstract static class InitNode extends BaseInitNode {
105105

106-
@Child BufferedReaderInit init = BufferedReaderBuiltinsFactory.BufferedReaderInitNodeGen.create();
106+
@Child private BufferedReaderInit init = BufferedReaderInitNodeGen.create();
107107

108108
@Override
109109
protected final void init(VirtualFrame frame, PBuffered self, Object raw, int bufferSize) {

0 commit comments

Comments
 (0)