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