1 /* 2 * Copyright (C) 2017 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 CONSCRYPT_COMPATIBILITY_CLOSE_MONITOR_H_ 18 #define CONSCRYPT_COMPATIBILITY_CLOSE_MONITOR_H_ 19 20 #include <conscrypt/macros.h> 21 22 namespace conscrypt { 23 24 /* 25 * Where possible, this class hooks into the Android C API for AsynchronousCloseMonitor, 26 * allowing Java thread wakeup semantics during POSIX system calls. It is only used in sslSelect(). 27 * 28 * When unbundled, if the C API methods are not available, this class will fall 29 * back to looking for the C++ API methods which existed on Android P and below. 30 * 31 * On non-Android platforms, this class becomes a no-op as all of the function pointers 32 * to create and destroy AsynchronousCloseMonitor instances will be null. 33 */ 34 class CompatibilityCloseMonitor { 35 public: CompatibilityCloseMonitor(int fd)36 explicit CompatibilityCloseMonitor(int fd) : monitor(nullptr) { 37 if (asyncCloseMonitorCreate != nullptr) { 38 monitor = asyncCloseMonitorCreate(fd); 39 } 40 #ifdef CONSCRYPT_UNBUNDLED 41 else if(asyncCloseMonitorConstructor != nullptr) { 42 asyncCloseMonitorConstructor(objBuffer, fd); 43 } 44 #endif // CONSCRYPT_UNBUNDLED 45 } 46 ~CompatibilityCloseMonitor()47 ~CompatibilityCloseMonitor() { 48 if (asyncCloseMonitorDestroy != nullptr) { 49 if (monitor != nullptr) { 50 asyncCloseMonitorDestroy(monitor); 51 } 52 } 53 #ifdef CONSCRYPT_UNBUNDLED 54 else if (asyncCloseMonitorDestructor != nullptr) { 55 asyncCloseMonitorDestructor(objBuffer); 56 } 57 #endif // CONSCRYPT_UNBUNDLED 58 } 59 60 static void init(); 61 62 private: 63 // C API: Not available on Android P and below. Maintains pointers to the C 64 // create and destroy methods, which will be null on non-Android platforms. 65 // The handle returned by the create method is stored in monitor. 66 typedef void* (*acm_create_func)(int); 67 typedef void (*acm_destroy_func)(void*); 68 69 static acm_create_func asyncCloseMonitorCreate; 70 static acm_destroy_func asyncCloseMonitorDestroy; 71 void* monitor; 72 73 #ifdef CONSCRYPT_UNBUNDLED 74 // C++ API: Only available on Android P and below. Maintains pointers to 75 // the C++ constructor and destructor methods, which will be null on 76 // non-Android platforms. Calls them directly, passing in a pointer to 77 // objBuffer, which is large enough to fit an AsynchronousCloseMonitor object on 78 // Android versions where this class will be using this API. 79 // This is equivalent to placement new and explicit destruction. 80 typedef void (*acm_ctor_func)(void*, int); 81 typedef void (*acm_dtor_func)(void*); 82 83 static acm_ctor_func asyncCloseMonitorConstructor; 84 static acm_dtor_func asyncCloseMonitorDestructor; 85 char objBuffer[256]; 86 #endif // CONSCRYPT_UNBUNDLED 87 }; 88 89 } // namespace conscrypt 90 91 #endif // CONSCRYPT_COMPATIBILITY_CLOSE_MONITOR_H_ 92