diff options
| author | Pete Bentley <prb@google.com> | 2019-02-06 06:43:55 -0800 |
|---|---|---|
| committer | android-build-merger <android-build-merger@google.com> | 2019-02-06 06:43:55 -0800 |
| commit | 875edfe217f8ea2ef8b2eb7dd4916dfd920eec1e (patch) | |
| tree | 34a50fb455c1c8affcddca831d2da0c86edf4c8d | |
| parent | 44c0a4e51e86535ada216bc82c40bdd44eafbbe6 (diff) | |
| parent | 1833c1c47fa18c44cacf02f22bd09c5fd5b5030f (diff) | |
| download | platform_libnativehelper-875edfe217f8ea2ef8b2eb7dd4916dfd920eec1e.tar.gz platform_libnativehelper-875edfe217f8ea2ef8b2eb7dd4916dfd920eec1e.tar.bz2 platform_libnativehelper-875edfe217f8ea2ef8b2eb7dd4916dfd920eec1e.zip | |
Merge "Move AsynchronousCloseMonitor to libjavacore." am: 033f88713f
am: 1833c1c47f
Change-Id: Ibe933f9edfec93a5d5d76b40c14bccf85f53f7ff
| -rw-r--r-- | Android.bp | 8 | ||||
| -rw-r--r-- | AsynchronousCloseMonitor.cpp | 160 | ||||
| -rw-r--r-- | include/nativehelper/AsynchronousCloseMonitor.h | 83 | ||||
| -rw-r--r-- | libnativehelper.map.txt | 6 | ||||
| -rw-r--r-- | tests/libnativehelper_api_test.c | 1 |
5 files changed, 0 insertions, 258 deletions
@@ -40,14 +40,6 @@ cc_defaults { "JniInvocation.cpp", "toStringArray.cpp", ], - target: { - linux: { - srcs: ["AsynchronousCloseMonitor.cpp"], - }, - fuchsia: { - srcs: ["AsynchronousCloseMonitor.cpp"], - }, - }, shared_libs: [ "liblog", ], diff --git a/AsynchronousCloseMonitor.cpp b/AsynchronousCloseMonitor.cpp deleted file mode 100644 index 2c9f836..0000000 --- a/AsynchronousCloseMonitor.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "AsynchronousCloseMonitor" - -#include <nativehelper/AsynchronousCloseMonitor.h> - -#include <log/log.h> - -#include <errno.h> -#include <signal.h> -#include <string.h> - -#include <mutex> - -namespace { - -class AsynchronousCloseMonitorImpl { -public: - explicit AsynchronousCloseMonitorImpl(int fd); - ~AsynchronousCloseMonitorImpl(); - bool wasSignaled() const; - - static void init(); - - static void signalBlockedThreads(int fd); - -private: - AsynchronousCloseMonitorImpl(const AsynchronousCloseMonitorImpl&) = delete; - AsynchronousCloseMonitorImpl& operator=(const AsynchronousCloseMonitorImpl&) = delete; - - AsynchronousCloseMonitorImpl* mPrev; - AsynchronousCloseMonitorImpl* mNext; - pthread_t mThread; - int mFd; - bool mSignaled; -}; - -/** - * We use an intrusive doubly-linked list to keep track of blocked threads. - * This gives us O(1) insertion and removal, and means we don't need to do any allocation. - * (The objects themselves are stack-allocated.) - * Waking potentially-blocked threads when a file descriptor is closed is O(n) in the total number - * of blocked threads (not the number of threads actually blocked on the file descriptor in - * question). For now at least, this seems like a good compromise for Android. - */ -static std::mutex blockedThreadListMutex; -static AsynchronousCloseMonitorImpl* blockedThreadList = NULL; - -/** - * The specific signal chosen here is arbitrary, but bionic needs to know so that SIGRTMIN - * starts at a higher value. - */ -#if defined(__Fuchsia__) -static const int BLOCKED_THREAD_SIGNAL = SIGRTMIN + 2; -#else -static const int BLOCKED_THREAD_SIGNAL = __SIGRTMIN + 2; -#endif - -static void blockedThreadSignalHandler(int /*signal*/) { - // Do nothing. We only sent this signal for its side-effect of interrupting syscalls. -} - -void AsynchronousCloseMonitorImpl::init() { - // Ensure that the signal we send interrupts system calls but doesn't kill threads. - // Using sigaction(2) lets us ensure that the SA_RESTART flag is not set. - // (The whole reason we're sending this signal is to unblock system calls!) - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = blockedThreadSignalHandler; - sa.sa_flags = 0; - int rc = sigaction(BLOCKED_THREAD_SIGNAL, &sa, NULL); - if (rc == -1) { - ALOGE("setting blocked thread signal handler failed: %s", strerror(errno)); - } -} - -void AsynchronousCloseMonitorImpl::signalBlockedThreads(int fd) { - std::lock_guard<std::mutex> lock(blockedThreadListMutex); - for (AsynchronousCloseMonitorImpl* it = blockedThreadList; it != NULL; it = it->mNext) { - if (it->mFd == fd) { - it->mSignaled = true; - pthread_kill(it->mThread, BLOCKED_THREAD_SIGNAL); - // Keep going, because there may be more than one thread... - } - } -} - -bool AsynchronousCloseMonitorImpl::wasSignaled() const { - return mSignaled; -} - -AsynchronousCloseMonitorImpl::AsynchronousCloseMonitorImpl(int fd) { - std::lock_guard<std::mutex> lock(blockedThreadListMutex); - // Who are we, and what are we waiting for? - mThread = pthread_self(); - mFd = fd; - mSignaled = false; - // Insert ourselves at the head of the intrusive doubly-linked list... - mPrev = NULL; - mNext = blockedThreadList; - if (mNext != NULL) { - mNext->mPrev = this; - } - blockedThreadList = this; -} - -AsynchronousCloseMonitorImpl::~AsynchronousCloseMonitorImpl() { - std::lock_guard<std::mutex> lock(blockedThreadListMutex); - // Unlink ourselves from the intrusive doubly-linked list... - if (mNext != NULL) { - mNext->mPrev = mPrev; - } - if (mPrev == NULL) { - blockedThreadList = mNext; - } else { - mPrev->mNext = mNext; - } -} - -} // namespace - -// -// C ABI and API boundary -// - -MODULE_API void async_close_monitor_static_init() { - AsynchronousCloseMonitorImpl::init(); -} - -MODULE_API void async_close_monitor_signal_blocked_threads(int fd) { - AsynchronousCloseMonitorImpl::signalBlockedThreads(fd); -} - -MODULE_API void* async_close_monitor_create(int fd) { - return new AsynchronousCloseMonitorImpl(fd); -} - -MODULE_API void async_close_monitor_destroy(void* instance) { - auto monitor = reinterpret_cast<AsynchronousCloseMonitorImpl*>(instance); - delete monitor; -} - -MODULE_API int async_close_monitor_was_signalled(const void* instance) { - auto monitor = reinterpret_cast<const AsynchronousCloseMonitorImpl*>(instance); - return monitor->wasSignaled() ? 1 : 0; -} diff --git a/include/nativehelper/AsynchronousCloseMonitor.h b/include/nativehelper/AsynchronousCloseMonitor.h deleted file mode 100644 index e172ac4..0000000 --- a/include/nativehelper/AsynchronousCloseMonitor.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ASYNCHRONOUS_CLOSE_MONITOR_H_included -#define ASYNCHRONOUS_CLOSE_MONITOR_H_included - -#include <pthread.h> - -#include "module_api.h" - -// Public API for library function. -MODULE_API void async_close_monitor_destroy(void* instance); -MODULE_API void async_close_monitor_static_init(); -MODULE_API void async_close_monitor_signal_blocked_threads(int fd); -MODULE_API int async_close_monitor_was_signalled(const void* instance); -MODULE_API void* async_close_monitor_create(int fd); - -#ifdef __cplusplus - -/** - * AsynchronousCloseMonitor helps implement Java's asynchronous close semantics. - * - * AsynchronousCloseMonitor::init must be called before anything else. - * - * Every blocking I/O operation must be surrounded by an AsynchronousCloseMonitor - * instance. For example: - * - * { - * AsynchronousCloseMonitor monitor(fd); - * byteCount = ::read(fd, buf, sizeof(buf)); - * } - * - * To interrupt all threads currently blocked on file descriptor 'fd', call signalBlockedThreads: - * - * AsynchronousCloseMonitor::signalBlockedThreads(fd); - * - * To test to see if the interruption was due to the signalBlockedThreads call: - * - * monitor.wasSignaled(); - */ -class AsynchronousCloseMonitor { -public: - explicit AsynchronousCloseMonitor(int fd) { - instance_ = async_close_monitor_create(fd); - } - ~AsynchronousCloseMonitor() { - async_close_monitor_destroy(instance_); - } - bool wasSignaled() const { - return async_close_monitor_was_signalled(instance_) != 0; - } - - static void init() { - async_close_monitor_static_init(); - } - - static void signalBlockedThreads(int fd) { - async_close_monitor_signal_blocked_threads(fd); - } - -private: - AsynchronousCloseMonitor(const AsynchronousCloseMonitor&) = delete; - AsynchronousCloseMonitor& operator=(const AsynchronousCloseMonitor&) = delete; - - void* instance_; -}; - -#endif // __cplusplus - -#endif // ASYNCHRONOUS_CLOSE_MONITOR_H_included diff --git a/libnativehelper.map.txt b/libnativehelper.map.txt index 9e03268..67c7f02 100644 --- a/libnativehelper.map.txt +++ b/libnativehelper.map.txt @@ -27,12 +27,6 @@ LIBNATIVEHELPER_1 { JniInvocationInit; JniInvocationGetLibrary; - async_close_monitor_static_init; - async_close_monitor_signal_blocked_threads; - async_close_monitor_create; - async_close_monitor_destroy; - async_close_monitor_was_signalled; - newStringArray; toStringArray; diff --git a/tests/libnativehelper_api_test.c b/tests/libnativehelper_api_test.c index cf2930c..fde6356 100644 --- a/tests/libnativehelper_api_test.c +++ b/tests/libnativehelper_api_test.c @@ -15,7 +15,6 @@ */ // All header files with MODULE_API decorated function declarations. -#include "nativehelper/AsynchronousCloseMonitor.h" #include "nativehelper/JNIHelp.h" #include "nativehelper/JniInvocation.h" #include "nativehelper/toStringArray.h" |
