summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libusbmuxd/CMakeLists.txt2
-rw-r--r--libusbmuxd/libusbmuxd.c98
-rw-r--r--libusbmuxd/thread.c108
-rw-r--r--libusbmuxd/thread.h55
4 files changed, 208 insertions, 55 deletions
diff --git a/libusbmuxd/CMakeLists.txt b/libusbmuxd/CMakeLists.txt
index 737eb02..238d6c3 100644
--- a/libusbmuxd/CMakeLists.txt
+++ b/libusbmuxd/CMakeLists.txt
@@ -10,7 +10,7 @@ if (INOTIFY_FOUND)
endif()
endif(WANT_INOTIFY)
-add_library (libusbmuxd SHARED libusbmuxd.c sock_stuff.c ${CMAKE_SOURCE_DIR}/common/utils.c)
+add_library (libusbmuxd SHARED libusbmuxd.c sock_stuff.c thread.c ${CMAKE_SOURCE_DIR}/common/utils.c)
find_library (PTHREAD pthread)
if (HAVE_PLIST)
diff --git a/libusbmuxd/libusbmuxd.c b/libusbmuxd/libusbmuxd.c
index 952e680..904f1ed 100644
--- a/libusbmuxd/libusbmuxd.c
+++ b/libusbmuxd/libusbmuxd.c
@@ -35,7 +35,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#else
#include <sys/socket.h>
#include <arpa/inet.h>
-#include <pthread.h>
#endif
#ifdef HAVE_INOTIFY
@@ -62,6 +61,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#include "usbmuxd-proto.h"
// socket utility functions
#include "sock_stuff.h"
+// threads and mutexes
+#include "thread.h"
// misc utility functions
#include "utils.h"
@@ -75,23 +76,25 @@ static int handle_events = 0;
static usbmuxd_event_cb_t event_cb = NULL;
static void* event_user_data = NULL;
-#ifdef WIN32
-HANDLE devmon = NULL;
-CRITICAL_SECTION mutex;
-static int mutex_initialized = 0;
-#define LOCK if (!mutex_initialized) { InitializeCriticalSection(&mutex); mutex_initialized = 1; } EnterCriticalSection(&mutex);
-#define UNLOCK LeaveCriticalSection(&mutex);
-#else
-pthread_t devmon = 0;
-pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-#define LOCK pthread_mutex_lock(&mutex)
-#define UNLOCK pthread_mutex_unlock(&mutex)
-#endif
+
+static thread_t devmon = NULL;
+static mutex_t mutex;
+
static int listenfd = -1;
static int use_tag = 0;
static int proto_version = 0;
+static __attribute__((constructor)) void libusbmuxd_library_init()
+{
+ mutex_init(&mutex);
+}
+
+static __attribute__((destructor)) void libusbmuxd_library_deinit()
+{
+ mutex_destroy(&mutex);
+}
+
/**
* Finds a device info record by its handle.
* if the record is not found, NULL is returned.
@@ -510,15 +513,15 @@ retry:
}
use_tag++;
- LOCK;
+ mutex_lock(&mutex);
if (send_listen_packet(sfd, use_tag) <= 0) {
- UNLOCK;
+ mutex_unlock(&mutex);
DEBUG(1, "%s: ERROR: could not send listen packet\n", __func__);
close_socket(sfd);
return -1;
}
if (usbmuxd_get_result(sfd, use_tag, &res) && (res != 0)) {
- UNLOCK;
+ mutex_unlock(&mutex);
close_socket(sfd);
#ifdef HAVE_PLIST
if ((res == RESULT_BADVERSION) && (proto_version != 1)) {
@@ -529,7 +532,7 @@ retry:
DEBUG(1, "%s: ERROR: did not get OK but %d\n", __func__, res);
return -1;
}
- UNLOCK;
+ mutex_unlock(&mutex);
return sfd;
}
@@ -621,8 +624,8 @@ static void *device_monitor(void *data)
{
collection_init(&devices);
-#ifndef WIN32
- pthread_cleanup_push(device_monitor_cleanup, NULL);
+#ifdef THREAD_CLEANUP_SUPPORTED
+ thread_cleanup_push(device_monitor_cleanup, NULL);
#endif
while (handle_events) {
@@ -639,8 +642,8 @@ static void *device_monitor(void *data)
}
}
-#ifndef WIN32
- pthread_cleanup_pop(1);
+#ifdef THREAD_CLEANUP_SUPPORTED
+ thread_cleanup_pop(1);
#else
device_monitor_cleanup(NULL);
#endif
@@ -650,48 +653,35 @@ static void *device_monitor(void *data)
int usbmuxd_init()
{
int res = 0;
- LOCK;
+ mutex_lock(&mutex);
handle_events = 1;
-#ifdef WIN32
- devmon = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)device_monitor, NULL, 0, NULL);
- if (devmon == NULL) {
- res = GetLastError();
- }
-#else
- res = pthread_create(&devmon, NULL, device_monitor, NULL);
-#endif
+ res = thread_create(&devmon, device_monitor, NULL);
if (res != 0) {
DEBUG(1, "%s: ERROR: Could not start device watcher thread!\n", __func__);
handle_events = 0;
- UNLOCK;
+ mutex_unlock(&mutex);
return res;
}
struct timespec ts = {0, 250000000};
nanosleep(&ts, NULL);
libusbmuxd_initialized = 1;
- UNLOCK;
+ mutex_unlock(&mutex);
return 0;
}
int usbmuxd_deinit()
{
- LOCK;
+ mutex_lock(&mutex);
handle_events = 0;
shutdown_socket(listenfd, SHUT_RDWR);
-#ifdef WIN32
- if (devmon != NULL) {
- WaitForSingleObject(devmon, INFINITE);
- }
-#else
- if (pthread_kill(devmon, 0) == 0) {
- pthread_cancel(devmon);
- pthread_join(devmon, NULL);
+ if (thread_valid(devmon)) {
+ thread_cancel(devmon);
+ thread_join(devmon);
}
-#endif
libusbmuxd_initialized = 0;
- UNLOCK;
+ mutex_unlock(&mutex);
return 0;
}
@@ -704,9 +694,9 @@ int usbmuxd_subscribe(usbmuxd_event_cb_t callback, void *user_data)
event_user_data = user_data;
int is_initialized = 0;
- LOCK;
+ mutex_lock(&mutex);
is_initialized = libusbmuxd_initialized;
- UNLOCK;
+ mutex_unlock(&mutex);
if (!is_initialized) {
usbmuxd_init();
@@ -751,14 +741,14 @@ retry:
}
use_tag++;
- //LOCK;
+ //mutex_lock(&mutex);
if (send_listen_packet(sfd, use_tag) > 0) {
res = -1;
// get response
if (usbmuxd_get_result(sfd, use_tag, &res) && (res == 0)) {
listen_success = 1;
} else {
- //UNLOCK;
+ //mutex_unlock(&mutex);
close_socket(sfd);
#ifdef HAVE_PLIST
if ((res == RESULT_BADVERSION) && (proto_version != 1)) {
@@ -766,13 +756,13 @@ retry:
goto retry;
}
#endif
- DEBUG(1, "%s: Did not get response to scan request (with result=0)...\n", __func__);
- return res;
+ DEBUG(1, "%s: Did not get response to scan request with result 0, instead got result %d ...\n", __func__, res);
+ return -1;
}
}
if (!listen_success) {
- //UNLOCK;
+ //mutex_unlock(&mutex);
DEBUG(1, "%s: Could not send listen request!\n", __func__);
return -1;
}
@@ -786,7 +776,7 @@ retry:
dev = payload;
usbmuxd_device_info_t *devinfo = (usbmuxd_device_info_t*)malloc(sizeof(usbmuxd_device_info_t));
if (!devinfo) {
- //UNLOCK;
+ //mutex_unlock(&mutex);
DEBUG(1, "%s: Out of memory!\n", __func__);
free(payload);
return -1;
@@ -830,7 +820,7 @@ retry:
break;
}
}
- //UNLOCK;
+ //mutex_unlock(&mutex);
// explicitly close connection
close_socket(sfd);
@@ -871,9 +861,9 @@ int usbmuxd_get_device_by_udid(const char *udid, usbmuxd_device_info_t *device)
}
int is_initialized = 0;
- LOCK;
+ mutex_lock(&mutex);
is_initialized = libusbmuxd_initialized;
- UNLOCK;
+ mutex_unlock(&mutex);
if (!is_initialized) {
usbmuxd_init();
diff --git a/libusbmuxd/thread.c b/libusbmuxd/thread.c
new file mode 100644
index 0000000..d25a4cf
--- /dev/null
+++ b/libusbmuxd/thread.c
@@ -0,0 +1,108 @@
+/*
+ * thread.c
+ *
+ * Copyright (c) 2012 Martin Szulecki All Rights Reserved.
+ * Copyright (c) 2012 Nikias Bassen All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "thread.h"
+
+int thread_create(thread_t *thread, thread_func_t thread_func, void* data)
+{
+#ifdef WIN32
+ HANDLE th = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)thread_func, data, 0, NULL);
+ if (th == NULL) {
+ return -1;
+ }
+ *thread = th;
+ return 0;
+#else
+ int res = pthread_create(thread, NULL, thread_func, data);
+ return res;
+#endif
+}
+
+void thread_join(thread_t thread)
+{
+ /* wait for thread to complete */
+#ifdef WIN32
+ WaitForSingleObject(thread, INFINITE);
+#else
+ pthread_join(thread, NULL);
+#endif
+}
+
+int thread_valid(thread_t thread)
+{
+#ifdef WIN32
+ if (!thread) {
+ return 0;
+ }
+ if (WaitForSingleObject(thread, 0) == WAIT_OBJECT_0) {
+ return 0;
+ } else {
+ return 1;
+ }
+#else
+ return (pthread_kill(thread, 0) == 0);
+#endif
+}
+
+void thread_cancel(thread_t thread)
+{
+#ifdef WIN32
+ // FIXME?
+#else
+ pthread_cancel(thread);
+#endif
+}
+
+void mutex_init(mutex_t* mutex)
+{
+#ifdef WIN32
+ InitializeCriticalSection(mutex);
+#else
+ pthread_mutex_init(mutex, NULL);
+#endif
+}
+
+void mutex_destroy(mutex_t* mutex)
+{
+#ifdef WIN32
+ DeleteCriticalSection(mutex);
+#else
+ pthread_mutex_destroy(mutex);
+#endif
+}
+
+void mutex_lock(mutex_t* mutex)
+{
+#ifdef WIN32
+ EnterCriticalSection(mutex);
+#else
+ pthread_mutex_lock(mutex);
+#endif
+}
+
+void mutex_unlock(mutex_t* mutex)
+{
+#ifdef WIN32
+ LeaveCriticalSection(mutex);
+#else
+ pthread_mutex_unlock(mutex);
+#endif
+}
diff --git a/libusbmuxd/thread.h b/libusbmuxd/thread.h
new file mode 100644
index 0000000..af0436b
--- /dev/null
+++ b/libusbmuxd/thread.h
@@ -0,0 +1,55 @@
+/*
+ * thread.h
+ *
+ * Copyright (c) 2012 Martin Szulecki All Rights Reserved.
+ * Copyright (c) 2012 Nikias Bassen All Rights Reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __THREAD_H
+#define __THREAD_H
+
+#ifdef WIN32
+#include <windows.h>
+typedef HANDLE thread_t;
+typedef CRITICAL_SECTION mutex_t;
+#else
+#include <pthread.h>
+typedef pthread_t thread_t;
+typedef pthread_mutex_t mutex_t;
+#endif
+
+typedef void* (*thread_func_t)(void* data);
+
+int thread_create(thread_t* thread, thread_func_t thread_func, void* data);
+void thread_join(thread_t thread);
+int thread_valid(thread_t thread);
+void thread_cancel(thread_t thread);
+
+#ifdef WIN32
+#undef THREAD_CLEANUP_SUPPORTED
+#else
+#define THREAD_CLEANUP_SUPPORTED 1
+#define thread_cleanup_push(r, a) pthread_cleanup_push(r, a)
+#define thread_cleanup_pop(e) pthread_cleanup_pop(e)
+#endif
+
+void mutex_init(mutex_t* mutex);
+void mutex_destroy(mutex_t* mutex);
+void mutex_lock(mutex_t* mutex);
+void mutex_unlock(mutex_t* mutex);
+
+#endif