Skip to content

Commit 1139971

Browse files
aamCommit Queue
authored andcommitted
[ffi/samples] Fix samples/ffi/http so it passes under tsan.
Before this fix running under tsan produces following warning: ``` 00:00 +0: httpGet 00:03 +1: httpServe 00:04 +2: All tests passed! /usr/bin/addr2line: DWARF error: mangled line number section (bad file number) /usr/bin/addr2line: DWARF error: mangled line number section (bad file number) /usr/bin/addr2line: DWARF error: mangled line number section (bad file number) /usr/bin/addr2line: DWARF error: mangled line number section (bad file number) /usr/bin/addr2line: DWARF error: mangled line number section (bad file number) ================== WARNING: ThreadSanitizer: signal-unsafe call inside of a signal (pid=145964) #0 malloc ../../../../../../llvm-llvm-project/../../../../../../llvm-llvm-project/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp:676 (dartvm+0x21c9330) (BuildId: d195bc5e9885ab144039c676e433289217750aec) #1 __dcigettext intl/./intl/dcigettext.c:621 (libc.so.6+0x39f23) (BuildId: 4a95b54430cb5a2c68c1812f1738222660dec6d1) #2 __tsan::CallUserSignalHandler(__tsan::ThreadState*, bool, bool, int, __sanitizer::__sanitizer_siginfo*, void*) ../../../../../../llvm-llvm-project/../../../../../../llvm-llvm-project/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp:2149 (dartvm+0x21d34af) (BuildId: d195bc5e9885ab144039c676e433289217750aec) SUMMARY: ThreadSanitizer: signal-unsafe call inside of a signal intl/./intl/dcigettext.c:621 in __dcigettext ================== ThreadSanitizer: reported 1 warnings ``` TEST=samples/ffi/http Change-Id: I4cd1b62d30cde3ff0d4cd5f6a23c33e36491884a Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/445284 Commit-Queue: Alexander Aprelev <[email protected]> Reviewed-by: Liam Appelbe <[email protected]>
1 parent aa4d235 commit 1139971

File tree

3 files changed

+38
-16
lines changed

3 files changed

+38
-16
lines changed

samples/ffi/http/lib/fake_http.cc

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,23 @@ DART_EXPORT void http_get(const char* uri, void (*onResponse)(const char*)) {
3838
}).detach();
3939
}
4040

41-
DART_EXPORT void http_serve(void (*onRequest)(const char*)) {
42-
std::thread([onRequest]() {
43-
while (true) {
41+
std::atomic<bool> stop_requested = false;
42+
std::thread* server = nullptr;
43+
44+
DART_EXPORT void http_start_serving(void (*onRequest)(const char*)) {
45+
server = new std::thread([onRequest]() {
46+
while (!stop_requested) {
4447
std::this_thread::sleep_for(std::chrono::seconds(1));
4548
onRequest(kExampleRequest);
4649
}
47-
}).detach();
50+
});
4851
}
52+
53+
DART_EXPORT void http_stop_serving() {
54+
if (server != nullptr) {
55+
stop_requested = true;
56+
server->join();
57+
delete server;
58+
server = nullptr;
59+
}
60+
}

samples/ffi/http/lib/http.dart

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ Future<String> httpGet(String uri) async {
3939
}
4040

4141
// Start a HTTP server on a background thread.
42-
void httpServe(void Function(String) onRequest) {
42+
// Returns a function that should be called to stop the server.
43+
Function httpServe(void Function(String) onRequest) {
4344
// Create the NativeCallable.listener.
4445
void onNativeRequest(Pointer<Utf8> requestPointer) {
4546
onRequest(requestPointer.toDartString());
@@ -50,13 +51,12 @@ void httpServe(void Function(String) onRequest) {
5051
// Invoke the native function to start the HTTP server. Our example
5152
// HTTP library will start a server on a background thread, and pass
5253
// any requests it receives to out callback.
53-
nativeHttpServe(callback.nativeFunction);
54+
nativeHttpStartServing(callback.nativeFunction);
5455

55-
// The server will run indefinitely, and the callback needs to stay
56-
// alive for that whole time, so we can't close the callback here.
57-
// But we also don't want the callback to keep the isolate alive
58-
// forever, so we set keepIsolateAlive to false.
59-
callback.keepIsolateAlive = false;
56+
return () {
57+
nativeHttpStopServing();
58+
callback.close();
59+
};
6060
}
6161

6262
// Load the native functions from a DynamicLibrary.
@@ -73,12 +73,21 @@ typedef HttpGetNativeFunction = Void Function(
7373
final nativeHttpGet =
7474
dylib.lookupFunction<HttpGetNativeFunction, HttpGetFunction>('http_get');
7575

76-
typedef HttpServeFunction = void Function(
76+
typedef HttpStartServingFunction = bool Function(
7777
Pointer<NativeFunction<HttpCallback>>);
78-
typedef HttpServeNativeFunction = Void Function(
78+
typedef HttpStartServingNativeFunction = Bool Function(
7979
Pointer<NativeFunction<HttpCallback>>);
80-
final nativeHttpServe = dylib
81-
.lookupFunction<HttpServeNativeFunction, HttpServeFunction>('http_serve');
80+
final nativeHttpStartServing = dylib
81+
.lookupFunction<HttpStartServingNativeFunction, HttpStartServingFunction>(
82+
'http_start_serving',
83+
);
84+
85+
typedef HttpStopServingFunction = void Function();
86+
typedef HttpStopServingNativeFunction = Void Function();
87+
final nativeHttpStopServing = dylib
88+
.lookupFunction<HttpStopServingNativeFunction, HttpStopServingFunction>(
89+
'http_stop_serving',
90+
);
8291

8392
Future<void> main() async {
8493
print('Sending GET request...');

samples/ffi/http/test/http_test.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@ Future<void> main() async {
1616

1717
test('httpServe', () async {
1818
final completer = Completer<String>();
19-
httpServe((request) {
19+
final callWhenDone = httpServe((request) {
2020
if (!completer.isCompleted) {
2121
completer.complete(request);
2222
}
2323
});
2424
final request = await completer.future;
2525
expect(request, contains('www.example.com'));
26+
callWhenDone();
2627
});
2728
}

0 commit comments

Comments
 (0)