diff options
author | Pierre Langlois <pierre.langlois@arm.com> | 2015-01-14 18:55:29 +0000 |
---|---|---|
committer | Pierre Langlois <pierre.langlois@arm.com> | 2016-03-04 17:51:00 +0000 |
commit | 26bc1aefec6d048996b5f1f7d0dbcf01bd743815 (patch) | |
tree | 49eca53576969c4a03046b3e7ab2c04ff583c205 | |
parent | 8b80c2bd6822ccf515ae0f02d2d48b47cee4c6fe (diff) | |
download | kdbinder-26bc1aefec6d048996b5f1f7d0dbcf01bd743815.tar.gz |
libkdbinder: import ProcessState and IPCThreadState
ProcessState and IPCThreadState are respectively per process and per
thread objects. The ProcessState object is a singleton and
IPCThreadState is stored in thread local storage.
ProcessState is responsible for managing a thread pool for servers.
IPCThreadState represents a thread that can either wait for incoming
transactions or issue one to another thread connected to the bus.
This brings the following (partially implemented) API:
- static ProcessState::self()
Get the ProcessState object for the current process, create it if it
does not exist.
- ProcessState::startThreadPool()
- ProcessState::spawnPooledThread()
- ProcessState::getStrongProxyForHandle(int32_t handle)
Return a binder proxy object (BpBinder) corresponding to the given
handle. Contrary to Binder, handle 0 is be invalid and does not
represent the service manager.
- ProcessState::setThreadPoolMaxThreadCount(size_t maxThreads)
- static IPCThreadState::self()
Get the IPCThreadState object for the current thread, create it if it
does not exist.
- IPCThreadState::getCallingPid()
- IPCThreadState::getCallingUid()
- IPCThreadState::flushCommands();
This call makes sure that all pending commands to binder are done. We
do not need this.
- IPCThreadState::joinThreadPool()
Add the current thread to the process's thread pool. This call is
blocking as each thread in the pool awaits for incoming transactions.
- IPCThreadState::stopProcess()
- IPCThreadState::transact(int32_t handle,
uint32_t code,
// const Parcel& data,
// Parcel *reply,
uint32_t flags = 0)
Issue a transaction to the BpBinder object refered to by handle on the
bus.
- IPCThreadState::requestDeathNotification(int32_t handle,
BpBinder *proxy);
- IPCThreadState::clearDeathNotification(int32_t handle,
BpBinder *proxy);
Get the current thread to call proxy when the given handle dies.
Change-Id: I40e6972dfdc6df1d28f043c88fd442b0e13b5d01
-rw-r--r-- | include/kdbinder/binder/IPCThreadState.h | 62 | ||||
-rw-r--r-- | include/kdbinder/binder/ProcessState.h | 55 | ||||
-rw-r--r-- | include/kdbinder/private/binder/Static.h | 34 | ||||
-rw-r--r-- | libs/kdbinder/Android.mk | 3 | ||||
-rw-r--r-- | libs/kdbinder/binder/IPCThreadState.cpp | 131 | ||||
-rw-r--r-- | libs/kdbinder/binder/ProcessState.cpp | 59 | ||||
-rw-r--r-- | libs/kdbinder/binder/Static.cpp | 27 |
7 files changed, 371 insertions, 0 deletions
diff --git a/include/kdbinder/binder/IPCThreadState.h b/include/kdbinder/binder/IPCThreadState.h new file mode 100644 index 0000000..776eefa --- /dev/null +++ b/include/kdbinder/binder/IPCThreadState.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDE_KDBINDER_BINDER_IPCTHREADSTATE_H_ +#define INCLUDE_KDBINDER_BINDER_IPCTHREADSTATE_H_ + +#include <binder/BpBinder.h> + +#include <utils/RefBase.h> +#include <utils/Errors.h> + +namespace android { + +class IPCThreadState : public virtual RefBase { + public: + static IPCThreadState* self(); + + pid_t getCallingPid() const; + uid_t getCallingUid() const; + + void flushCommands(); + + void joinThreadPool(bool isMain = true); + + void stopProcess(bool immediate = true); + + status_t transact(int32_t handle, + uint32_t code, + const Parcel& data, + Parcel* reply, + uint32_t flags = 0); + + status_t requestDeathNotification(int32_t handle, + BpBinder *proxy); + status_t clearDeathNotification(int32_t handle, + BpBinder *proxy); + + private: + IPCThreadState(); + ~IPCThreadState() {} + + static void threadDestructor(void *st); + + const pid_t mMyThreadId; +}; + +} // namespace android + +#endif // INCLUDE_KDBINDER_BINDER_IPCTHREADSTATE_H_ diff --git a/include/kdbinder/binder/ProcessState.h b/include/kdbinder/binder/ProcessState.h new file mode 100644 index 0000000..e2fe43d --- /dev/null +++ b/include/kdbinder/binder/ProcessState.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INCLUDE_KDBINDER_BINDER_PROCESSSTATE_H_ +#define INCLUDE_KDBINDER_BINDER_PROCESSSTATE_H_ + +#include <binder/IBinder.h> + +#include <utils/RefBase.h> +#include <utils/Mutex.h> + +namespace android { + +class ProcessState : public virtual RefBase { + public: + static sp<ProcessState> self(); + + void startThreadPool(); + + void spawnPooledThread(bool isMain); + + sp<IBinder> getStrongProxyForHandle(int32_t handle); + + status_t setThreadPoolMaxThreadCount(size_t maxThreads); + + private: + friend class IPCThreadState; + + ProcessState(); + ~ProcessState() = default; + + ProcessState(const ProcessState& o); + ProcessState& operator=(const ProcessState& o); + + mutable Mutex mLock; // protects everything below. + bool mThreadPoolStarted; + volatile int32_t mThreadPoolSeq; +}; + +} // namespace android + +#endif // INCLUDE_KDBINDER_BINDER_PROCESSSTATE_H_ diff --git a/include/kdbinder/private/binder/Static.h b/include/kdbinder/private/binder/Static.h new file mode 100644 index 0000000..fb5743d --- /dev/null +++ b/include/kdbinder/private/binder/Static.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// All static variables go here, to control initialization and +// destruction order in the library. + +#ifndef INCLUDE_PRIVATE_KDBINDER_STATIC_H_ +#define INCLUDE_PRIVATE_KDBINDER_STATIC_H_ + +#include <binder/ProcessState.h> + +#include <utils/Mutex.h> + +namespace android { + +extern Mutex gProcessMutex; +extern sp<ProcessState> gProcess; + +} // namespace android + +#endif // INCLUDE_PRIVATE_KDBINDER_STATIC_H_ diff --git a/libs/kdbinder/Android.mk b/libs/kdbinder/Android.mk index 3546d13..3e94fd2 100644 --- a/libs/kdbinder/Android.mk +++ b/libs/kdbinder/Android.mk @@ -16,6 +16,9 @@ kdbinder_sources := \ binder/Binder.cpp \ binder/BpBinder.cpp \ binder/IInterface.cpp \ + binder/ProcessState.cpp \ + binder/IPCThreadState.cpp \ + binder/Static.cpp \ kdbus/bus.cpp \ kdbus/connection.cpp \ kdbus/iterable.cpp \ diff --git a/libs/kdbinder/binder/IPCThreadState.cpp b/libs/kdbinder/binder/IPCThreadState.cpp new file mode 100644 index 0000000..3b6969c --- /dev/null +++ b/libs/kdbinder/binder/IPCThreadState.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if LOG_NDEBUG +#define LOG_THREADPOOL(...) +#else +#define LOG_THREADPOOL(...) ALOG(LOG_DEBUG, "threadpool", __VA_ARGS__) +#endif + +#include <binder/IPCThreadState.h> + +#include <log/log.h> + +#include <cutils/sched_policy.h> +#include <pthread.h> + +#include <string> + +namespace android { + +static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER; +static bool gHaveTLS = false; +static pthread_key_t gTLS = 0; + +thread_local IPCThreadState* TLS; + +IPCThreadState::IPCThreadState() + : mMyThreadId(gettid()) { + pthread_setspecific(gTLS, this); +} + +void IPCThreadState::threadDestructor(void *st) { + IPCThreadState* const self = static_cast<IPCThreadState*>(st); + delete self; +} + +IPCThreadState* IPCThreadState::self() { + if (gHaveTLS) { +restart: + const pthread_key_t k = gTLS; + IPCThreadState* st = static_cast<IPCThreadState *>(pthread_getspecific(k)); + if (st != nullptr) { + return st; + } + return new IPCThreadState; + } + + pthread_mutex_lock(&gTLSMutex); + if (!gHaveTLS) { + if (pthread_key_create(&gTLS, threadDestructor) != 0) { + pthread_mutex_unlock(&gTLSMutex); + return nullptr; + } + gHaveTLS = true; + } + pthread_mutex_unlock(&gTLSMutex); + goto restart; +} + +pid_t IPCThreadState::getCallingPid() const { + // TODO: unimplemented. + return 0; +} + +uid_t IPCThreadState::getCallingUid() const { + // TODO: unimplemented. + return 0; +} + +void IPCThreadState::flushCommands() { + // TODO: unimplemented. +} + +void IPCThreadState::joinThreadPool(bool /*isMain*/) { + LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", + (void*)pthread_self(), getpid()); + + // This thread may have been spawned by a thread that was in the background + // scheduling group, so first we will make sure it is in the foreground + // one to avoid performing an initial transaction in the background. + set_sched_policy(mMyThreadId, SP_FOREGROUND); + + int result = 0; + + do { + // TODO: Handle incoming messages. + } while (result == 0); + + LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%u\n", + (void*)pthread_self(), getpid(), result); +} + +void IPCThreadState::stopProcess(bool /*immediate*/) { + // TODO: unimplemented. +} + +status_t IPCThreadState::transact(int32_t /*handle*/, + uint32_t /*code*/, + const Parcel& /*data*/, + Parcel* /*reply*/, + uint32_t /*flags*/) { + // TODO: Send a message. + return UNKNOWN_TRANSACTION; +} + +status_t IPCThreadState::requestDeathNotification(int32_t /*handle*/, + BpBinder * /*proxy*/) { + // TODO: unimplemented. + return UNKNOWN_TRANSACTION; +} + +status_t IPCThreadState::clearDeathNotification(int32_t /*handle*/, + BpBinder * /*proxy*/) { + // TODO: unimplemented. + return UNKNOWN_TRANSACTION; +} + +} // namespace android diff --git a/libs/kdbinder/binder/ProcessState.cpp b/libs/kdbinder/binder/ProcessState.cpp new file mode 100644 index 0000000..225fb01 --- /dev/null +++ b/libs/kdbinder/binder/ProcessState.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define LOG_TAG "kdbinder.ProcessState" + +#include <private/binder/Static.h> +#include <binder/ProcessState.h> +#include <binder/IPCThreadState.h> + +namespace android { + +ProcessState::ProcessState() : mThreadPoolStarted(false) { + // TODO: unimplemented. +} + +sp<ProcessState> ProcessState::self() { + Mutex::Autolock _l(gProcessMutex); + if (gProcess != NULL) { + return gProcess; + } + gProcess = new ProcessState; + return gProcess; +} + +void ProcessState::startThreadPool() { + AutoMutex _l(mLock); + if (!mThreadPoolStarted) { + mThreadPoolStarted = true; + spawnPooledThread(true); + } +} + +void ProcessState::spawnPooledThread(bool /*isMain*/) { + // TODO: unimplemented. +} + +sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t /*handle*/) { + // TODO: unimplemented. + return NULL; +} + +status_t ProcessState::setThreadPoolMaxThreadCount(size_t /*maxThreads*/) { + // TODO: unimplemented. + return NO_ERROR; +} + +} // namespace android diff --git a/libs/kdbinder/binder/Static.cpp b/libs/kdbinder/binder/Static.cpp new file mode 100644 index 0000000..7c87a69 --- /dev/null +++ b/libs/kdbinder/binder/Static.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// All static variables go here, to control initialization and +// destruction order in the library. + +#include <private/binder/Static.h> + +namespace android { + +Mutex gProcessMutex; +sp<ProcessState> gProcess; + +} // namespace android |