aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre Langlois <pierre.langlois@arm.com>2015-01-14 18:55:29 +0000
committerPierre Langlois <pierre.langlois@arm.com>2016-03-04 17:51:00 +0000
commit26bc1aefec6d048996b5f1f7d0dbcf01bd743815 (patch)
tree49eca53576969c4a03046b3e7ab2c04ff583c205
parent8b80c2bd6822ccf515ae0f02d2d48b47cee4c6fe (diff)
downloadkdbinder-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.h62
-rw-r--r--include/kdbinder/binder/ProcessState.h55
-rw-r--r--include/kdbinder/private/binder/Static.h34
-rw-r--r--libs/kdbinder/Android.mk3
-rw-r--r--libs/kdbinder/binder/IPCThreadState.cpp131
-rw-r--r--libs/kdbinder/binder/ProcessState.cpp59
-rw-r--r--libs/kdbinder/binder/Static.cpp27
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