Skip to content

Commit 61ba73f

Browse files
committed
Deal with sem_getvalue not working on Darwin
1 parent 7aa06c7 commit 61ba73f

File tree

4 files changed

+59
-22
lines changed

4 files changed

+59
-22
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/multiprocessing/MultiprocessingModuleBuiltins.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
7979
return MultiprocessingModuleBuiltinsFactory.getFactories();
8080
}
8181

82-
@Builtin(name = "SemLock", minNumOfPositionalArgs = 1, parameterNames = {"$cls", "kind", "value", "maxvalue", "name", "unlink"}, constructsClass = PythonBuiltinClassType.PSemLock)
82+
@Builtin(name = "SemLock", parameterNames = {"$cls", "kind", "value", "maxvalue", "name", "unlink"}, constructsClass = PythonBuiltinClassType.PSemLock)
8383
@ArgumentClinic(name = "kind", conversion = ArgumentClinic.ClinicConversion.Int)
8484
@ArgumentClinic(name = "value", conversion = ArgumentClinic.ClinicConversion.Int)
8585
@ArgumentClinic(name = "maxvalue", conversion = ArgumentClinic.ClinicConversion.Int)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/multiprocessing/SemLockBuiltins.java

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
*/
4141
package com.oracle.graal.python.builtins.modules.multiprocessing;
4242

43+
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.NotImplementedError;
4344
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError;
4445
import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ENTER__;
4546
import static com.oracle.graal.python.nodes.SpecialMethodNames.J___EXIT__;
@@ -69,6 +70,7 @@
6970
import com.oracle.graal.python.runtime.PosixSupport;
7071
import com.oracle.graal.python.runtime.PosixSupportLibrary;
7172
import com.oracle.graal.python.runtime.PosixSupportLibrary.PosixException;
73+
import com.oracle.graal.python.runtime.PosixSupportLibrary.UnsupportedPosixFeatureException;
7274
import com.oracle.graal.python.runtime.object.PythonObjectFactory;
7375
import com.oracle.truffle.api.dsl.Bind;
7476
import com.oracle.truffle.api.dsl.Cached;
@@ -97,7 +99,7 @@ public void initialize(Python3Core core) {
9799
@GenerateNodeFactory
98100
abstract static class HandleNode extends PythonUnaryBuiltinNode {
99101
@Specialization
100-
Object get(PSemLock self) {
102+
static Object get(PSemLock self) {
101103
return self.getHandle();
102104
}
103105
}
@@ -106,7 +108,7 @@ Object get(PSemLock self) {
106108
@GenerateNodeFactory
107109
abstract static class KindNode extends PythonUnaryBuiltinNode {
108110
@Specialization
109-
Object get(PSemLock self) {
111+
static Object get(PSemLock self) {
110112
return self.getKind();
111113
}
112114
}
@@ -115,7 +117,7 @@ Object get(PSemLock self) {
115117
@GenerateNodeFactory
116118
abstract static class NameNode extends PythonUnaryBuiltinNode {
117119
@Specialization
118-
Object get(PSemLock self) {
120+
static Object get(PSemLock self) {
119121
return self.getName();
120122
}
121123
}
@@ -124,7 +126,7 @@ Object get(PSemLock self) {
124126
@GenerateNodeFactory
125127
abstract static class MaxValueNode extends PythonUnaryBuiltinNode {
126128
@Specialization
127-
Object get(PSemLock self) {
129+
static Object get(PSemLock self) {
128130
return self.getMaxValue();
129131
}
130132
}
@@ -199,7 +201,7 @@ protected ArgumentClinicProvider getArgumentClinic() {
199201
@GenerateNodeFactory
200202
abstract static class ReleaseNode extends PythonUnaryBuiltinNode {
201203
@Specialization
202-
PNone release(VirtualFrame frame, PSemLock self,
204+
static PNone release(VirtualFrame frame, PSemLock self,
203205
@Bind("this") Node inliningTarget,
204206
@Bind("getPosixSupport()") PosixSupport posixSupport,
205207
@CachedLibrary("posixSupport") PosixSupportLibrary posixLib,
@@ -216,13 +218,22 @@ PNone release(VirtualFrame frame, PSemLock self,
216218
} else {
217219
int sval;
218220
try {
219-
sval = posixLib.semGetValue(posixSupport, self.getHandle());
221+
try {
222+
sval = posixLib.semGetValue(posixSupport, self.getHandle());
223+
if (sval >= self.getMaxValue()) {
224+
throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.SEMAPHORE_RELEASED_TOO_MANY_TIMES);
225+
}
226+
} catch (UnsupportedPosixFeatureException e) {
227+
/* We will only check properly the maxvalue == 1 case */
228+
if (posixLib.semTryWait(posixSupport, self.getHandle())) {
229+
/* it was not locked so undo wait and raise */
230+
posixLib.semPost(posixSupport, self.getHandle());
231+
throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.SEMAPHORE_RELEASED_TOO_MANY_TIMES);
232+
}
233+
}
220234
} catch (PosixException e) {
221235
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
222236
}
223-
if (sval >= self.getMaxValue()) {
224-
throw raiseNode.get(inliningTarget).raise(ValueError, ErrorMessages.SEMAPHORE_RELEASED_TOO_MANY_TIMES);
225-
}
226237
}
227238
try {
228239
posixLib.semPost(posixSupport, self.getHandle());
@@ -238,7 +249,7 @@ PNone release(VirtualFrame frame, PSemLock self,
238249
@GenerateNodeFactory
239250
abstract static class EnterNode extends PythonUnaryBuiltinNode {
240251
@Specialization
241-
Object enter(VirtualFrame frame, PSemLock self,
252+
static Object enter(VirtualFrame frame, PSemLock self,
242253
@Cached AcquireNode acquireNode) {
243254
return acquireNode.execute(frame, self, true, PNone.NO_VALUE);
244255
}
@@ -248,7 +259,7 @@ Object enter(VirtualFrame frame, PSemLock self,
248259
@GenerateNodeFactory
249260
abstract static class ExitNode extends PythonQuaternaryBuiltinNode {
250261
@Specialization
251-
Object exit(VirtualFrame frame, PSemLock self, @SuppressWarnings("unused") Object type, @SuppressWarnings("unused") Object value, @SuppressWarnings("unused") Object traceback,
262+
static Object exit(VirtualFrame frame, PSemLock self, @SuppressWarnings("unused") Object type, @SuppressWarnings("unused") Object value, @SuppressWarnings("unused") Object traceback,
252263
@Cached ReleaseNode releaseNode) {
253264
return releaseNode.execute(frame, self);
254265
}
@@ -258,7 +269,7 @@ Object exit(VirtualFrame frame, PSemLock self, @SuppressWarnings("unused") Objec
258269
@GenerateNodeFactory
259270
abstract static class CountNode extends PythonUnaryBuiltinNode {
260271
@Specialization
261-
Object get(PSemLock self) {
272+
static Object get(PSemLock self) {
262273
return self.getCount();
263274
}
264275
}
@@ -267,7 +278,7 @@ Object get(PSemLock self) {
267278
@GenerateNodeFactory
268279
abstract static class IsMineNode extends PythonUnaryBuiltinNode {
269280
@Specialization
270-
boolean get(PSemLock self) {
281+
static boolean get(PSemLock self) {
271282
return self.isMine();
272283
}
273284
}
@@ -280,7 +291,8 @@ int get(VirtualFrame frame, PSemLock self,
280291
@Bind("this") Node inliningTarget,
281292
@Bind("getPosixSupport()") PosixSupport posixSupport,
282293
@CachedLibrary("posixSupport") PosixSupportLibrary posixLib,
283-
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
294+
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode,
295+
@Cached PRaiseNode.Lazy raiseNode) {
284296
try {
285297
int sval = posixLib.semGetValue(posixSupport, self.getHandle());
286298
/*
@@ -293,6 +305,9 @@ int get(VirtualFrame frame, PSemLock self,
293305
return sval;
294306
} catch (PosixException e) {
295307
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
308+
} catch (UnsupportedPosixFeatureException e) {
309+
// Not available on Darwin
310+
throw raiseNode.get(inliningTarget).raise(NotImplementedError);
296311
}
297312
}
298313
}
@@ -301,14 +316,22 @@ int get(VirtualFrame frame, PSemLock self,
301316
@GenerateNodeFactory
302317
abstract static class IsZeroNode extends PythonUnaryBuiltinNode {
303318
@Specialization
304-
boolean get(VirtualFrame frame, PSemLock self,
319+
static boolean get(VirtualFrame frame, PSemLock self,
305320
@Bind("this") Node inliningTarget,
306321
@Bind("getPosixSupport()") PosixSupport posixSupport,
307322
@CachedLibrary("posixSupport") PosixSupportLibrary posixLib,
308323
@Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) {
309324
try {
310-
int sval = posixLib.semGetValue(posixSupport, self.getHandle());
311-
return sval == 0;
325+
try {
326+
return posixLib.semGetValue(posixSupport, self.getHandle()) == 0;
327+
} catch (UnsupportedPosixFeatureException e) {
328+
if (posixLib.semTryWait(posixSupport, self.getHandle())) {
329+
posixLib.semPost(posixSupport, self.getHandle());
330+
return false;
331+
} else {
332+
return true;
333+
}
334+
}
312335
} catch (PosixException e) {
313336
throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e);
314337
}
@@ -319,7 +342,7 @@ boolean get(VirtualFrame frame, PSemLock self,
319342
@GenerateNodeFactory
320343
abstract static class AfterForkNode extends PythonUnaryBuiltinNode {
321344
@Specialization
322-
Object afterFork(PSemLock self) {
345+
static Object afterFork(PSemLock self) {
323346
self.setCount(0);
324347
return PNone.NONE;
325348
}
@@ -333,7 +356,7 @@ Object afterFork(PSemLock self) {
333356
@GenerateNodeFactory
334357
abstract static class RebuildNode extends PythonClinicBuiltinNode {
335358
@Specialization
336-
Object rebuild(VirtualFrame frame, Object cls, @SuppressWarnings("unused") long origHandle, int kind, int maxValue, TruffleString name,
359+
static Object rebuild(VirtualFrame frame, Object cls, @SuppressWarnings("unused") long origHandle, int kind, int maxValue, TruffleString name,
337360
@Bind("this") Node inliningTarget,
338361
@Bind("getPosixSupport()") PosixSupport posixSupport,
339362
@CachedLibrary("posixSupport") PosixSupportLibrary posixLib,

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/NFIPosixSupport.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@
7373
import static com.oracle.graal.python.runtime.PosixConstants.PATH_MAX;
7474
import static com.oracle.graal.python.runtime.PosixConstants.WNOHANG;
7575
import static com.oracle.graal.python.runtime.PosixConstants._POSIX_HOST_NAME_MAX;
76+
import static com.oracle.graal.python.runtime.PosixSupportLibrary.POSIX_FILENAME_SEPARATOR;
77+
import static com.oracle.graal.python.runtime.PosixSupportLibrary.UnsupportedPosixFeatureException;
7678
import static com.oracle.graal.python.util.PythonUtils.ARRAY_ACCESSOR;
7779
import static com.oracle.graal.python.util.PythonUtils.ARRAY_ACCESSOR_BE;
7880
import static com.oracle.graal.python.util.PythonUtils.EMPTY_LONG_ARRAY;
@@ -89,6 +91,7 @@
8991
import org.graalvm.nativeimage.ImageInfo;
9092

9193
import com.oracle.graal.python.PythonLanguage;
94+
import com.oracle.graal.python.builtins.PythonOS;
9295
import com.oracle.graal.python.builtins.objects.exception.OSErrorEnum;
9396
import com.oracle.graal.python.runtime.PosixSupportLibrary.AcceptResult;
9497
import com.oracle.graal.python.runtime.PosixSupportLibrary.AddrInfoCursor;
@@ -942,14 +945,14 @@ static Buffer withoutSlash(@SuppressWarnings("unused") NFIPosixSupport receiver,
942945
int nameLen = (int) dirEntry.name.length;
943946
byte[] buf = new byte[pathLen + 1 + nameLen];
944947
PythonUtils.arraycopy(scandirPathBuffer.data, 0, buf, 0, pathLen);
945-
buf[pathLen] = PosixSupportLibrary.POSIX_FILENAME_SEPARATOR;
948+
buf[pathLen] = POSIX_FILENAME_SEPARATOR;
946949
PythonUtils.arraycopy(dirEntry.name.data, 0, buf, pathLen + 1, nameLen);
947950
return Buffer.wrap(buf);
948951
}
949952

950953
protected static boolean endsWithSlash(Object path) {
951954
Buffer b = (Buffer) path;
952-
return b.data[b.data.length - 1] == PosixSupportLibrary.POSIX_FILENAME_SEPARATOR;
955+
return b.data[b.data.length - 1] == POSIX_FILENAME_SEPARATOR;
953956
}
954957
}
955958

@@ -2219,9 +2222,18 @@ void semUnlink(Object name,
22192222
}
22202223
}
22212224

2225+
private static final UnsupportedPosixFeatureException NO_SEM_GETVALUE_EXCEPTION = new UnsupportedPosixFeatureException("sem_getvalue is not available on the current platform");
2226+
22222227
@ExportMessage
22232228
int semGetValue(long handle,
22242229
@Shared("invoke") @Cached InvokeNativeFunction invokeNode) throws PosixException {
2230+
/*
2231+
* msimacek: It works on Linux, and it doesn't work on Darwin. It might work on some other
2232+
* Unix-likes, but it's hard to check, so let's assume it only works on Linux for now
2233+
*/
2234+
if (PythonOS.getPythonOS() != PythonOS.PLATFORM_LINUX) {
2235+
throw NO_SEM_GETVALUE_EXCEPTION;
2236+
}
22252237
int[] value = new int[1];
22262238
int res = invokeNode.callInt(this, PosixNativeFunction.call_sem_getvalue, handle, wrap(value));
22272239
if (res < 0) {

graalpython/python-libposix/src/posix.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -917,12 +917,14 @@ int32_t call_sem_unlink(const char *name) {
917917
return sem_unlink(name);
918918
}
919919

920+
#ifdef __linux__
920921
int32_t call_sem_getvalue(int64_t handle, int32_t *value) {
921922
int valueInt;
922923
int res = sem_getvalue((sem_t*)(uintptr_t)handle, &valueInt);
923924
*value = valueInt;
924925
return res;
925926
}
927+
#endif
926928

927929
int32_t call_sem_post(int64_t handle) {
928930
return sem_post((sem_t*)(uintptr_t)handle);

0 commit comments

Comments
 (0)