1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ASYNCHRONOUS_CLOSE_MONITOR_H_included 18 #define ASYNCHRONOUS_CLOSE_MONITOR_H_included 19 20 #include <pthread.h> 21 22 // Public API for library function. 23 extern "C" { 24 void async_close_monitor_destroy(void* instance); 25 void async_close_monitor_static_init(); 26 void async_close_monitor_signal_blocked_threads(int fd); 27 int async_close_monitor_was_signalled(const void* instance); 28 void* async_close_monitor_create(int fd); 29 } 30 31 /** 32 * AsynchronousCloseMonitor helps implement Java's asynchronous close semantics. 33 * 34 * AsynchronousCloseMonitor::init must be called before anything else. 35 * 36 * Every blocking I/O operation must be surrounded by an AsynchronousCloseMonitor 37 * instance. For example: 38 * 39 * { 40 * AsynchronousCloseMonitor monitor(fd); 41 * byteCount = ::read(fd, buf, sizeof(buf)); 42 * } 43 * 44 * To interrupt all threads currently blocked on file descriptor 'fd', call signalBlockedThreads: 45 * 46 * AsynchronousCloseMonitor::signalBlockedThreads(fd); 47 * 48 * To test to see if the interruption was due to the signalBlockedThreads call: 49 * 50 * monitor.wasSignaled(); 51 */ 52 class AsynchronousCloseMonitor { 53 public: AsynchronousCloseMonitor(int fd)54 explicit AsynchronousCloseMonitor(int fd) { 55 instance_ = async_close_monitor_create(fd); 56 } ~AsynchronousCloseMonitor()57 ~AsynchronousCloseMonitor() { 58 async_close_monitor_destroy(instance_); 59 } wasSignaled()60 bool wasSignaled() const { 61 return async_close_monitor_was_signalled(instance_) != 0; 62 } 63 init()64 static void init() { 65 async_close_monitor_static_init(); 66 } 67 signalBlockedThreads(int fd)68 static void signalBlockedThreads(int fd) { 69 async_close_monitor_signal_blocked_threads(fd); 70 } 71 72 private: 73 AsynchronousCloseMonitor(const AsynchronousCloseMonitor&) = delete; 74 AsynchronousCloseMonitor& operator=(const AsynchronousCloseMonitor&) = delete; 75 76 void* instance_; 77 }; 78 79 #endif // ASYNCHRONOUS_CLOSE_MONITOR_H_included 80