ProcessState学习笔记

 * Copyright (C) 2005 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 ANDROID_HARDWARE_PROCESS_STATE_H
18  #define ANDROID_HARDWARE_PROCESS_STATE_H
19  
20  #include <hwbinder/IBinder.h>
21  #include <utils/KeyedVector.h>
22  #include <utils/String8.h>
23  #include <utils/String16.h>
24  
25  #include <utils/threads.h>
26  
27  #include <pthread.h>
28  
29  // ---------------------------------------------------------------------------
30  namespace android {
31  namespace hardware {
32  
33  class IPCThreadState;
34  
35  class ProcessState : public virtual RefBase
36  {
37  public:
38      static  sp<ProcessState>    self();
39      static  sp<ProcessState>    selfOrNull();
40      // Note: don't call self() or selfOrNull() before initWithMmapSize()
41      static  sp<ProcessState>    initWithMmapSize(size_t mmapSize); // size in bytes
42  
43              void                setContextObject(const sp<IBinder>& object);
44              sp<IBinder>         getContextObject(const sp<IBinder>& caller);
45  
46              void                setContextObject(const sp<IBinder>& object,
47                                                   const String16& name);
48              sp<IBinder>         getContextObject(const String16& name,
49                                                   const sp<IBinder>& caller);
50  
51              void                startThreadPool();
52  
53      typedef bool (*context_check_func)(const String16& name,
54                                         const sp<IBinder>& caller,
55                                         void* userData);
56  
57              bool                isContextManager(void) const;
58              bool                becomeContextManager(
59                                      context_check_func checkFunc,
60                                      void* userData);
61  
62              sp<IBinder>         getStrongProxyForHandle(int32_t handle);
63              wp<IBinder>         getWeakProxyForHandle(int32_t handle);
64              void                expungeHandle(int32_t handle, IBinder* binder);
65  
66              void                spawnPooledThread(bool isMain);
67  
68              status_t            setThreadPoolConfiguration(size_t maxThreads, bool callerJoinsPool);
69              size_t              getMaxThreads();
70              void                giveThreadPoolName();
71  
72              ssize_t             getKernelReferences(size_t count, uintptr_t* buf);
73                                  // This refcount includes:
74                                  // 1. Strong references to the node by this  and other processes
75                                  // 2. Temporary strong references held by the kernel during a
76                                  //    transaction on the node.
77                                  // It does NOT include local strong references to the node
78              ssize_t             getStrongRefCountForNodeByHandle(int32_t handle);
79              size_t              getMmapSize();
80  
81              enum class CallRestriction {
82                  // all calls okay
83                  NONE,
84                  // log when calls are blocking
85                  ERROR_IF_NOT_ONEWAY,
86                  // abort process on blocking calls
87                  FATAL_IF_NOT_ONEWAY,
88              };
89              // Sets calling restrictions for all transactions in this process. This must be called
90              // before any threads are spawned.
91              void setCallRestriction(CallRestriction restriction);
92  
93  private:
94      friend class IPCThreadState;
95              explicit            ProcessState(size_t mmap_size);
96                                  ~ProcessState();
97  
98                                  ProcessState(const ProcessState& o);
99              ProcessState&       operator=(const ProcessState& o);
100              String8             makeBinderThreadName();
101  
102              struct handle_entry {
103                  IBinder* binder;
104                  RefBase::weakref_type* refs;
105              };
106  
107              handle_entry*       lookupHandleLocked(int32_t handle);
108  
109              int                 mDriverFD;
110              void*               mVMStart;
111  
112              // Protects thread count variable below.
113              pthread_mutex_t     mThreadCountLock;
114              pthread_cond_t      mThreadCountDecrement;
115              // Number of binder threads current executing a command.
116              size_t              mExecutingThreadsCount;
117              // Maximum number for binder threads allowed for this process.
118              size_t              mMaxThreads;
119              // Time when thread pool was emptied
120              int64_t             mStarvationStartTimeMs;
121  
122      mutable Mutex               mLock;  // protects everything below.
123  
124              Vector<handle_entry>mHandleToObject;
125  
126              bool                mManagesContexts;
127              context_check_func  mBinderContextCheckFunc;
128              void*               mBinderContextUserData;
129  
130              KeyedVector<String16, sp<IBinder> >
131                                  mContexts;
132  
133  
134              String8             mRootDir;
135              bool                mThreadPoolStarted;
136              bool                mSpawnThreadOnStart;
137      volatile int32_t            mThreadPoolSeq;
138              const size_t        mMmapSize;
139  
140              CallRestriction     mCallRestriction;
141  };
142  
143  } // namespace hardware
144  } // namespace android
145  
146  // ---------------------------------------------------------------------------
147  
148  #endif // ANDROID_HARDWARE_PROCESS_STATE_H
149  

 来源:ProcessState.h - OpenGrok cross reference for /system/libhwbinder/include/hwbinder/ProcessState.h (aospxref.com)

  * Copyright (C) 2005 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  #define LOG_TAG "hw-ProcessState"
18  
19  #include <hwbinder/ProcessState.h>
20  
21  #include <cutils/atomic.h>
22  #include <hwbinder/BpHwBinder.h>
23  #include <hwbinder/IPCThreadState.h>
24  #include <utils/Log.h>
25  #include <utils/String8.h>
26  #include <utils/threads.h>
27  
28  #include "binder_kernel.h"
29  #include <hwbinder/Static.h>
30  
31  #include <errno.h>
32  #include <fcntl.h>
33  #include <stdio.h>
34  #include <stdlib.h>
35  #include <unistd.h>
36  #include <sys/ioctl.h>
37  #include <sys/mman.h>
38  #include <sys/stat.h>
39  #include <sys/types.h>
40  
41  #define DEFAULT_BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2)
42  #define DEFAULT_MAX_BINDER_THREADS 0
43  
44  // -------------------------------------------------------------------------
45  
46  namespace android {
47  namespace hardware {
48  
49  class PoolThread : public Thread
50  {
51  public:
52      explicit PoolThread(bool isMain)
53          : mIsMain(isMain)
54      {
55      }
56  
57  protected:
58      virtual bool threadLoop()
59      {
60          IPCThreadState::self()->joinThreadPool(mIsMain);
61          return false;
62      }
63  
64      const bool mIsMain;
65  };
66  
67  sp<ProcessState> ProcessState::self()
68  {
69      Mutex::Autolock _l(gProcessMutex);
70      if (gProcess != nullptr) {
71          return gProcess;
72      }
73      gProcess = new ProcessState(DEFAULT_BINDER_VM_SIZE);
74      return gProcess;
75  }
76  
77  sp<ProcessState> ProcessState::selfOrNull() {
78      Mutex::Autolock _l(gProcessMutex);
79      return gProcess;
80  }
81  
82  sp<ProcessState> ProcessState::initWithMmapSize(size_t mmap_size) {
83      Mutex::Autolock _l(gProcessMutex);
84      if (gProcess != nullptr) {
85          LOG_ALWAYS_FATAL_IF(mmap_size != gProcess->getMmapSize(),
86                  "ProcessState already initialized with a different mmap size.");
87          return gProcess;
88      }
89  
90      gProcess = new ProcessState(mmap_size);
91      return gProcess;
92  }
93  
94  void ProcessState::setContextObject(const sp<IBinder>& object)
95  {
96      setContextObject(object, String16("default"));
97  }
98  
99  sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
100  {
101      return getStrongProxyForHandle(0);
102  }
103  
104  void ProcessState::setContextObject(const sp<IBinder>& object, const String16& name)
105  {
106      AutoMutex _l(mLock);
107      mContexts.add(name, object);
108  }
109  
110  sp<IBinder> ProcessState::getContextObject(const String16& name, const sp<IBinder>& caller)
111  {
112      mLock.lock();
113      sp<IBinder> object(
114          mContexts.indexOfKey(name) >= 0 ? mContexts.valueFor(name) : nullptr);
115      mLock.unlock();
116  
117      //printf("Getting context object %s for %p\n", String8(name).string(), caller.get());
118  
119      if (object != nullptr) return object;
120  
121      // Don't attempt to retrieve contexts if we manage them
122      if (mManagesContexts) {
123          ALOGE("getContextObject(%s) failed, but we manage the contexts!\n",
124              String8(name).string());
125          return nullptr;
126      }
127  
128      IPCThreadState* ipc = IPCThreadState::self();
129      {
130          Parcel data, reply;
131          // no interface token on this magic transaction
132          data.writeString16(name);
133          data.writeStrongBinder(caller);
134          status_t result = ipc->transact(0 /*magic*/, 0, data, &reply, 0);
135          if (result == NO_ERROR) {
136              object = reply.readStrongBinder();
137          }
138      }
139  
140      ipc->flushCommands();
141  
142      if (object != nullptr) setContextObject(object, name);
143      return object;
144  }
145  
146  void ProcessState::startThreadPool()
147  {
148      AutoMutex _l(mLock);
149      if (!mThreadPoolStarted) {
150          mThreadPoolStarted = true;
151          if (mSpawnThreadOnStart) {
152              spawnPooledThread(true);
153          }
154      }
155  }
156  
157  bool ProcessState::isContextManager(void) const
158  {
159      return mManagesContexts;
160  }
161  
162  bool ProcessState::becomeContextManager(context_check_func checkFunc, void* userData)
163  {
164      if (!mManagesContexts) {
165          AutoMutex _l(mLock);
166          mBinderContextCheckFunc = checkFunc;
167          mBinderContextUserData = userData;
168  
169          flat_binder_object obj {
170              .flags = FLAT_BINDER_FLAG_TXN_SECURITY_CTX,
171          };
172  
173          status_t result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR_EXT, &obj);
174  
175          // fallback to original method
176          if (result != 0) {
177              android_errorWriteLog(0x534e4554, "121035042");
178  
179              int dummy = 0;
180              result = ioctl(mDriverFD, BINDER_SET_CONTEXT_MGR, &dummy);
181          }
182  
183          if (result == 0) {
184              mManagesContexts = true;
185          } else if (result == -1) {
186              mBinderContextCheckFunc = nullptr;
187              mBinderContextUserData = nullptr;
188              ALOGE("Binder ioctl to become context manager failed: %s\n", strerror(errno));
189          }
190      }
191      return mManagesContexts;
192  }
193  
194  // Get references to userspace objects held by the kernel binder driver
195  // Writes up to count elements into buf, and returns the total number
196  // of references the kernel has, which may be larger than count.
197  // buf may be NULL if count is 0.  The pointers returned by this method
198  // should only be used for debugging and not dereferenced, they may
199  // already be invalid.
200  ssize_t ProcessState::getKernelReferences(size_t buf_count, uintptr_t* buf) {
201      binder_node_debug_info info = {};
202  
203      uintptr_t* end = buf ? buf + buf_count : nullptr;
204      size_t count = 0;
205  
206      do {
207          status_t result = ioctl(mDriverFD, BINDER_GET_NODE_DEBUG_INFO, &info);
208          if (result < 0) {
209              return -1;
210          }
211          if (info.ptr != 0) {
212              if (buf && buf < end) *buf++ = info.ptr;
213              count++;
214              if (buf && buf < end) *buf++ = info.cookie;
215              count++;
216          }
217      } while (info.ptr != 0);
218  
219      return count;
220  }
221  
222  // Queries the driver for the current strong reference count of the node
223  // that the handle points to. Can only be used by the servicemanager.
224  //
225  // Returns -1 in case of failure, otherwise the strong reference count.
226  ssize_t ProcessState::getStrongRefCountForNodeByHandle(int32_t handle) {
227      binder_node_info_for_ref info;
228      memset(&info, 0, sizeof(binder_node_info_for_ref));
229  
230      info.handle = handle;
231  
232      status_t result = ioctl(mDriverFD, BINDER_GET_NODE_INFO_FOR_REF, &info);
233  
234      if (result != OK) {
235          static bool logged = false;
236          if (!logged) {
237            ALOGW("Kernel does not support BINDER_GET_NODE_INFO_FOR_REF.");
238            logged = true;
239          }
240          return -1;
241      }
242  
243      return info.strong_count;
244  }
245  
246  size_t ProcessState::getMmapSize() {
247      return mMmapSize;
248  }
249  
250  void ProcessState::setCallRestriction(CallRestriction restriction) {
251      LOG_ALWAYS_FATAL_IF(IPCThreadState::selfOrNull() != nullptr,
252          "Call restrictions must be set before the threadpool is started.");
253  
254      mCallRestriction = restriction;
255  }
256  
257  ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
258  {
259      const size_t N=mHandleToObject.size();
260      if (N <= (size_t)handle) {
261          handle_entry e;
262          e.binder = nullptr;
263          e.refs = nullptr;
264          status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
265          if (err < NO_ERROR) return nullptr;
266      }
267      return &mHandleToObject.editItemAt(handle);
268  }
269  
270  sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
271  {
272      sp<IBinder> result;
273  
274      AutoMutex _l(mLock);
275  
276      handle_entry* e = lookupHandleLocked(handle);
277  
278      if (e != nullptr) {
279          // We need to create a new BpHwBinder if there isn't currently one, OR we
280          // are unable to acquire a weak reference on this current one.  See comment
281          // in getWeakProxyForHandle() for more info about this.
282          IBinder* b = e->binder;
283          if (b == nullptr || !e->refs->attemptIncWeak(this)) {
284              b = new BpHwBinder(handle);
285              e->binder = b;
286              if (b) e->refs = b->getWeakRefs();
287              result = b;
288          } else {
289              // This little bit of nastyness is to allow us to add a primary
290              // reference to the remote proxy when this team doesn't have one
291              // but another team is sending the handle to us.
292              result.force_set(b);
293              e->refs->decWeak(this);
294          }
295      }
296  
297      return result;
298  }
299  
300  wp<IBinder> ProcessState::getWeakProxyForHandle(int32_t handle)
301  {
302      wp<IBinder> result;
303  
304      AutoMutex _l(mLock);
305  
306      handle_entry* e = lookupHandleLocked(handle);
307  
308      if (e != nullptr) {
309          // We need to create a new BpHwBinder if there isn't currently one, OR we
310          // are unable to acquire a weak reference on this current one.  The
311          // attemptIncWeak() is safe because we know the BpHwBinder destructor will always
312          // call expungeHandle(), which acquires the same lock we are holding now.
313          // We need to do this because there is a race condition between someone
314          // releasing a reference on this BpHwBinder, and a new reference on its handle
315          // arriving from the driver.
316          IBinder* b = e->binder;
317          if (b == nullptr || !e->refs->attemptIncWeak(this)) {
318              b = new BpHwBinder(handle);
319              result = b;
320              e->binder = b;
321              if (b) e->refs = b->getWeakRefs();
322          } else {
323              result = b;
324              e->refs->decWeak(this);
325          }
326      }
327  
328      return result;
329  }
330  
331  void ProcessState::expungeHandle(int32_t handle, IBinder* binder)
332  {
333      AutoMutex _l(mLock);
334  
335      handle_entry* e = lookupHandleLocked(handle);
336  
337      // This handle may have already been replaced with a new BpHwBinder
338      // (if someone failed the AttemptIncWeak() above); we don't want
339      // to overwrite it.
340      if (e && e->binder == binder) e->binder = nullptr;
341  }
342  
343  String8 ProcessState::makeBinderThreadName() {
344      int32_t s = android_atomic_add(1, &mThreadPoolSeq);
345      pid_t pid = getpid();
346      String8 name;
347      name.appendFormat("HwBinder:%d_%X", pid, s);
348      return name;
349  }
350  
351  void ProcessState::spawnPooledThread(bool isMain)
352  {
353      if (mThreadPoolStarted) {
354          String8 name = makeBinderThreadName();
355          ALOGV("Spawning new pooled thread, name=%s\n", name.string());
356          sp<Thread> t = new PoolThread(isMain);
357          t->run(name.string());
358      }
359  }
360  
361  status_t ProcessState::setThreadPoolConfiguration(size_t maxThreads, bool callerJoinsPool) {
362      // if the caller joins the pool, then there will be one thread which is impossible.
363      LOG_ALWAYS_FATAL_IF(maxThreads == 0 && callerJoinsPool,
364             "Binder threadpool must have a minimum of one thread if caller joins pool.");
365  
366      size_t threadsToAllocate = maxThreads;
367  
368      // If the caller is going to join the pool it will contribute one thread to the threadpool.
369      // This is part of the API's contract.
370      if (callerJoinsPool) threadsToAllocate--;
371  
372      // If we can, spawn one thread from userspace when the threadpool is started. This ensures
373      // that there is always a thread available to start more threads as soon as the threadpool
374      // is started.
375      bool spawnThreadOnStart = threadsToAllocate > 0;
376      if (spawnThreadOnStart) threadsToAllocate--;
377  
378      // the BINDER_SET_MAX_THREADS ioctl really tells the kernel how many threads
379      // it's allowed to spawn, *in addition* to any threads we may have already
380      // spawned locally.
381      size_t kernelMaxThreads = threadsToAllocate;
382  
383      AutoMutex _l(mLock);
384      if (ioctl(mDriverFD, BINDER_SET_MAX_THREADS, &kernelMaxThreads) == -1) {
385          ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
386          return -errno;
387      }
388  
389      mMaxThreads = maxThreads;
390      mSpawnThreadOnStart = spawnThreadOnStart;
391  
392      return NO_ERROR;
393  }
394  
395  size_t ProcessState::getMaxThreads() {
396      return mMaxThreads;
397  }
398  
399  void ProcessState::giveThreadPoolName() {
400      androidSetThreadName( makeBinderThreadName().string() );
401  }
402  
403  static int open_driver()
404  {
405      int fd = open("/dev/hwbinder", O_RDWR | O_CLOEXEC);
406      if (fd >= 0) {
407          int vers = 0;
408          status_t result = ioctl(fd, BINDER_VERSION, &vers);
409          if (result == -1) {
410              ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
411              close(fd);
412              fd = -1;
413          }
414          if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
415            ALOGE("Binder driver protocol(%d) does not match user space protocol(%d)!", vers, BINDER_CURRENT_PROTOCOL_VERSION);
416              close(fd);
417              fd = -1;
418          }
419          size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
420          result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
421          if (result == -1) {
422              ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
423          }
424      } else {
425          ALOGW("Opening '/dev/hwbinder' failed: %s\n", strerror(errno));
426      }
427      return fd;
428  }
429  
430  ProcessState::ProcessState(size_t mmap_size)
431      : mDriverFD(open_driver())
432      , mVMStart(MAP_FAILED)
433      , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
434      , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
435      , mExecutingThreadsCount(0)
436      , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
437      , mStarvationStartTimeMs(0)
438      , mManagesContexts(false)
439      , mBinderContextCheckFunc(nullptr)
440      , mBinderContextUserData(nullptr)
441      , mThreadPoolStarted(false)
442      , mSpawnThreadOnStart(true)
443      , mThreadPoolSeq(1)
444      , mMmapSize(mmap_size)
445      , mCallRestriction(CallRestriction::NONE)
446  {
447      if (mDriverFD >= 0) {
448          // mmap the binder, providing a chunk of virtual address space to receive transactions.
449          mVMStart = mmap(nullptr, mMmapSize, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
450          if (mVMStart == MAP_FAILED) {
451              // *sigh*
452              ALOGE("Mmapping /dev/hwbinder failed: %s\n", strerror(errno));
453              close(mDriverFD);
454              mDriverFD = -1;
455          }
456      }
457  
458  #ifdef __ANDROID__
459      LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened. Terminating.");
460  #endif
461  }
462  
463  ProcessState::~ProcessState()
464  {
465      if (mDriverFD >= 0) {
466          if (mVMStart != MAP_FAILED) {
467              munmap(mVMStart, mMmapSize);
468          }
469          close(mDriverFD);
470      }
471      mDriverFD = -1;
472  }
473  
474  } // namespace hardware
475  } // namespace android
476  

 关于AutoLock,请参考Mutex::AutoLock介绍_southcamel的专栏-CSDN博客_mutex::autolock,我觉得这个里面讲的挺好

关于inline,请参考C++ 中的 inline 用法 | 菜鸟教程 (runoob.com)

关于explicit,请参考C++ explicit 关键字 - 知乎 (zhihu.com)

 

posted @ 2021-09-09 14:33  zhougong12  阅读(248)  评论(0)    收藏  举报