• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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