Skip to content

Commit 17a37d2

Browse files
rmacnak-googleCommit Queue
authored andcommitted
[test] Avoid data race checking for isolate cleanup callback.
Remove manual MSAN unpoisoning that should happen automatically for Pointer/TypedData writes. TEST=tsan, msan Bug: #61503 Bug: #61772 Change-Id: I7c3af7ad769f36a869de7f4d8125d0ced47c9ec7 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/458069 Reviewed-by: Alexander Aprelev <[email protected]> Commit-Queue: Ryan Macnak <[email protected]>
1 parent 5feffef commit 17a37d2

File tree

2 files changed

+46
-26
lines changed

2 files changed

+46
-26
lines changed

runtime/bin/ffi_test/ffi_test_functions_vmspecific.cc

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -331,21 +331,48 @@ DART_EXPORT void RestoreSIGPIPEHandler() {
331331
#endif
332332
}
333333

334-
DART_EXPORT void IGH_MsanUnpoison(void* start, intptr_t length) {
335-
MSAN_UNPOISON(start, length);
334+
struct IGH_Peer {
335+
bool shutdown = false;
336+
bool cleanup = false;
337+
std::mutex mutex;
338+
std::condition_variable cvar;
339+
};
340+
341+
DART_EXPORT void* IGH_CreatePeer() {
342+
return new IGH_Peer();
343+
}
344+
345+
DART_EXPORT void IGH_CheckPeerShutdown(void* peer_in) {
346+
IGH_Peer* peer = reinterpret_cast<IGH_Peer*>(peer_in);
347+
ENSURE(peer->shutdown);
348+
349+
{
350+
std::unique_lock<std::mutex> lock(peer->mutex);
351+
while (!peer->cleanup) {
352+
peer->cvar.wait(lock);
353+
}
354+
}
355+
ENSURE(peer->cleanup);
356+
357+
delete peer;
336358
}
337359

338360
DART_EXPORT Dart_Isolate IGH_CreateIsolate(const char* name, void* peer) {
339361
struct Helper {
340362
static void ShutdownCallback(void* ig_data, void* isolate_data) {
341-
char* string = reinterpret_cast<char*>(isolate_data);
342-
ENSURE(string[0] == 'a');
343-
string[0] = 'x';
363+
IGH_Peer* peer = reinterpret_cast<IGH_Peer*>(isolate_data);
364+
ENSURE(!peer->shutdown);
365+
peer->shutdown = true;
344366
}
345367
static void CleanupCallback(void* ig_data, void* isolate_data) {
346-
char* string = reinterpret_cast<char*>(isolate_data);
347-
ENSURE(string[2] == 'c');
348-
string[2] = 'z';
368+
IGH_Peer* peer = reinterpret_cast<IGH_Peer*>(isolate_data);
369+
ENSURE(!peer->cleanup);
370+
371+
{
372+
std::unique_lock<std::mutex> lock(peer->mutex);
373+
peer->cleanup = true;
374+
peer->cvar.notify_one();
375+
}
349376
}
350377
};
351378

runtime/tests/vm/dart/isolates/dart_api_create_lightweight_isolate_test.dart

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,16 @@ final class Isolate extends Opaque {}
2727
abstract class FfiBindings {
2828
static final ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions");
2929

30-
static final IGH_MsanUnpoison = ffiTestFunctions
30+
static final IGH_CreatePeer = ffiTestFunctions
31+
.lookupFunction<Pointer<Void> Function(), Pointer<Void> Function()>(
32+
'IGH_CreatePeer',
33+
);
34+
35+
static final IGH_CheckPeerShutdown = ffiTestFunctions
3136
.lookupFunction<
32-
Pointer<Isolate> Function(Pointer<Void>, IntPtr),
33-
Pointer<Isolate> Function(Pointer<Void>, int)
34-
>('IGH_MsanUnpoison');
37+
Void Function(Pointer<Void>),
38+
void Function(Pointer<Void>)
39+
>('IGH_CheckPeerShutdown');
3540

3641
static final IGH_CreateIsolate = ffiTestFunctions
3742
.lookupFunction<
@@ -82,7 +87,6 @@ abstract class FfiBindings {
8287
Pointer<Void> peer,
8388
) {
8489
final cname = name.toNativeUtf8();
85-
IGH_MsanUnpoison(cname.cast(), name.length + 10);
8690
try {
8791
final isolate = IGH_CreateIsolate(cname, peer);
8892
Expect.isTrue(isolate.address != 0);
@@ -105,9 +109,7 @@ abstract class FfiBindings {
105109
);
106110
final dartScript = dartScriptUri.toString();
107111
final libraryUri = dartScript.toNativeUtf8();
108-
IGH_MsanUnpoison(libraryUri.cast(), dartScript.length + 1);
109112
final functionName = name.toNativeUtf8();
110-
IGH_MsanUnpoison(functionName.cast(), name.length + 1);
111113

112114
IGH_StartIsolate(
113115
isolate,
@@ -137,23 +139,14 @@ void scheduleAsyncInvocation(void fun()) {
137139
}
138140

139141
Future withPeerPointer(fun(Pointer<Void> peer)) async {
140-
final Pointer<Void> peer = 'abc'.toNativeUtf8().cast();
141-
FfiBindings.IGH_MsanUnpoison(peer.cast(), 'abc'.length + 1);
142+
final Pointer<Void> peer = FfiBindings.IGH_CreatePeer();
142143
try {
143144
await fun(peer);
144145
} catch (e, s) {
145146
print('Exception: $e\nStack:$s');
146147
rethrow;
147148
} finally {
148-
// The shutdown callback is called before the exit listeners are notified, so
149-
// we can validate that a->x has been changed.
150-
Expect.isTrue(peer.cast<Utf8>().toDartString().startsWith('xb'));
151-
152-
// The cleanup callback is called after notifying exit listeners. So we
153-
// wait a little here to ensure the write of the callback has arrived.
154-
await Future.delayed(const Duration(milliseconds: 100));
155-
Expect.equals('xbz', peer.cast<Utf8>().toDartString());
156-
calloc.free(peer);
149+
FfiBindings.IGH_CheckPeerShutdown(peer);
157150
}
158151
}
159152

0 commit comments

Comments
 (0)