Log pthread_create() errors in MDNS listener
Test: as follows
- built (bullhead)
- flashed
- booted
- runtest -x netd_integration_test.cpp passed
Bug: 35909721
Change-Id: I09cc05955f88337901ec42f01ccfbd7c27677928
diff --git a/server/DnsProxyListener.cpp b/server/DnsProxyListener.cpp
index 59a85f0..b101d24 100644
--- a/server/DnsProxyListener.cpp
+++ b/server/DnsProxyListener.cpp
@@ -46,6 +46,7 @@
#include "NetworkController.h"
#include "ResponseCode.h"
#include "Stopwatch.h"
+#include "thread_util.h"
#include "android/net/metrics/INetdEventListener.h"
using android::String16;
@@ -57,43 +58,6 @@
namespace {
template<typename T>
-void* threadMain(void* obj) {
- std::unique_ptr<T> handler(reinterpret_cast<T*>(obj));
- handler->run();
- return nullptr;
-}
-
-struct scoped_pthread_attr {
- scoped_pthread_attr() { pthread_attr_init(&attr); }
- ~scoped_pthread_attr() { pthread_attr_destroy(&attr); }
-
- int detach() {
- return pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- }
-
- pthread_attr_t attr;
-};
-
-template<typename T>
-int threadLaunch(T* self) {
- if (self == nullptr) { return -EINVAL;}
-
- scoped_pthread_attr scoped_attr;
-
- int rval = scoped_attr.detach();
- if (rval != 0) { return -errno; }
-
- pthread_t thread;
- rval = pthread_create(&thread, &scoped_attr.attr, &threadMain<T>, self);
- if (rval != 0) {
- ALOGW("pthread_create failed: %d", errno);
- return -errno;
- }
-
- return rval;
-}
-
-template<typename T>
void tryThreadOrError(SocketClient* cli, T* handler) {
cli->incRef();
diff --git a/server/MDnsSdListener.cpp b/server/MDnsSdListener.cpp
index 883fe81..9551d45 100644
--- a/server/MDnsSdListener.cpp
+++ b/server/MDnsSdListener.cpp
@@ -38,6 +38,7 @@
#include "MDnsSdListener.h"
#include "ResponseCode.h"
+#include "thread_util.h"
#define MDNS_SERVICE_NAME "mdnsd"
#define MDNS_SERVICE_STATUS "init.svc.mdnsd"
@@ -524,17 +525,10 @@
socketpair(AF_LOCAL, SOCK_STREAM, 0, mCtrlSocketPair);
pthread_mutex_init(&mHeadMutex, NULL);
- pthread_create(&mThread, NULL, MDnsSdListener::Monitor::threadStart, this);
- pthread_detach(mThread);
-}
-
-void *MDnsSdListener::Monitor::threadStart(void *obj) {
- Monitor *monitor = reinterpret_cast<Monitor *>(obj);
-
- monitor->run();
- delete monitor;
- pthread_exit(NULL);
- return NULL;
+ const int rval = ::android::net::threadLaunch(this);
+ if (rval != 0) {
+ ALOGW("Error spawning monitor thread: %s (%d)", strerror(-rval), -rval);
+ }
}
#define NAP_TIME 200 // 200 ms between polls
diff --git a/server/MDnsSdListener.h b/server/MDnsSdListener.h
index e9c6066..3833ad6 100644
--- a/server/MDnsSdListener.h
+++ b/server/MDnsSdListener.h
@@ -65,6 +65,7 @@
}
};
+private:
class Monitor {
public:
Monitor();
@@ -73,11 +74,11 @@
void startMonitoring(int id);
DNSServiceRef *lookupServiceRef(int id);
void freeServiceRef(int id);
- static void *threadStart(void *handler);
int startService();
int stopService();
- private:
void run();
+
+ private:
int rescan(); // returns the number of elements in the poll
class Element {
public:
@@ -95,7 +96,6 @@
struct pollfd *mPollFds;
DNSServiceRef **mPollRefs;
int mPollSize;
- pthread_t mThread;
int mCtrlSocketPair[2];
pthread_mutex_t mHeadMutex;
};
diff --git a/server/thread_util.h b/server/thread_util.h
new file mode 100644
index 0000000..8a7ea6f
--- /dev/null
+++ b/server/thread_util.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2017 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 NETD_SERVER_THREAD_UTIL_H
+#define NETD_SERVER_THREAD_UTIL_H
+
+#include <pthread.h>
+#include <memory>
+
+namespace android {
+namespace net {
+
+struct scoped_pthread_attr {
+ scoped_pthread_attr() { pthread_attr_init(&attr); }
+ ~scoped_pthread_attr() { pthread_attr_destroy(&attr); }
+
+ int detach() {
+ return pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ }
+
+ pthread_attr_t attr;
+};
+
+template<typename T>
+inline void* runAndDelete(void* obj) {
+ std::unique_ptr<T> handler(reinterpret_cast<T*>(obj));
+ handler->run();
+ return nullptr;
+}
+
+template<typename T>
+inline int threadLaunch(T* obj) {
+ if (obj == nullptr) { return -EINVAL;}
+
+ scoped_pthread_attr scoped_attr;
+
+ int rval = scoped_attr.detach();
+ if (rval != 0) { return -errno; }
+
+ pthread_t thread;
+ rval = pthread_create(&thread, &scoped_attr.attr, &runAndDelete<T>, obj);
+ if (rval != 0) {
+ ALOGW("pthread_create failed: %d", errno);
+ return -errno;
+ }
+
+ return rval;
+}
+
+} // namespace net
+} // namespace android
+
+#endif // NETD_SERVER_THREAD_UTIL_H