summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcus Fritzsch <marcus.fritzsch@xse.de>2014-08-01 08:55:27 +0200
committerNobuhiko Tanibata <NOBUHIKO_TANIBATA@denso.co.jp>2014-08-12 22:15:16 +0900
commit82f778b3475740a20af06ef7025dee25f1f9f067 (patch)
treef532b3243fed9cf6947f1d13e2578873e8d4843a
parent64ed958e3324947a86a129b3232117dbd37139aa (diff)
downloadwayland-ivi-extension-82f778b3475740a20af06ef7025dee25f1f9f067.tar.gz
ilmControl: control_thread uses eventfd for shutdown signal
Do not use pthread_cancel to shutdown control_thread. This could cause stale locks in libwayland-client when the cancel was received when the display lock (according to the current 1.3 implementation) is held. To alleviate this, one could disable thread_cancellation in control_thread during wl_* calls, this however is one more hack to the cancel-to-shutdown hack. Instead, use a clean interface to send an event to the control_thread when it's time to shutdown. Signed-off-by: Marcus Fritzsch <marcus.fritzsch@xse.de>
-rw-r--r--ivi-layermanagement-api/ilmControl/src/ilm_control_wayland_platform.c56
1 files changed, 38 insertions, 18 deletions
diff --git a/ivi-layermanagement-api/ilmControl/src/ilm_control_wayland_platform.c b/ivi-layermanagement-api/ilmControl/src/ilm_control_wayland_platform.c
index d3f6a2a..e39fdea 100644
--- a/ivi-layermanagement-api/ilmControl/src/ilm_control_wayland_platform.c
+++ b/ivi-layermanagement-api/ilmControl/src/ilm_control_wayland_platform.c
@@ -19,6 +19,7 @@
#include <stdlib.h>
#include <string.h>
#include <memory.h>
+#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <stdbool.h>
@@ -26,6 +27,8 @@
#include <unistd.h>
#include <poll.h>
+#include <sys/eventfd.h>
+
#include "ilm_common.h"
#include "ilm_control_platform.h"
#include "wayland-util.h"
@@ -118,6 +121,7 @@ struct ilm_control_context {
pthread_t thread;
pthread_mutex_t mutex;
+ int shutdown_fd;
uint32_t internal_id_surface;
};
@@ -997,15 +1001,28 @@ static void destroy_control_resources(void)
}
}
+static void send_shutdown_event(struct ilm_control_context *ctx)
+{
+ uint64_t buf = 1;
+ while (write(ctx->shutdown_fd, &buf, sizeof buf) == -1 && errno == EINTR)
+ ;
+}
+
ILM_EXPORT void
ilmControl_destroy(void)
{
struct ilm_control_context *ctx = &ilm_context;
- pthread_cancel(ctx->thread);
+
+ send_shutdown_event(ctx);
+
if (0 != pthread_join(ctx->thread, NULL)) {
fprintf(stderr, "failed to join control thread\n");
}
+
destroy_control_resources();
+
+ close(ctx->shutdown_fd);
+
memset(ctx, 0, sizeof *ctx);
}
@@ -1055,12 +1072,15 @@ ilmControl_init(t_ilm_nativedisplay nativedisplay)
pthread_mutexattr_destroy(&a);
}
- return init_control() == 0 ? ILM_SUCCESS : ILM_FAILED;
-}
+ ctx->shutdown_fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
-static void cancel_read(void *d)
-{
- wl_display_cancel_read(d);
+ if (ctx->shutdown_fd == -1)
+ {
+ fprintf(stderr, "Could not setup shutdown-fd: %s\n", strerror(errno));
+ return ILM_FAILED;
+ }
+
+ return init_control() == 0 ? ILM_SUCCESS : ILM_FAILED;
}
static void*
@@ -1071,6 +1091,7 @@ control_thread(void *p_ret)
struct wl_display *const display = wl->display;
struct wl_event_queue *const queue = wl->queue;
int const fd = wl_display_get_fd(display);
+ int const shutdown_fd = ctx->shutdown_fd;
(void) p_ret;
while (1)
@@ -1087,19 +1108,13 @@ control_thread(void *p_ret)
break;
}
- struct pollfd pfd;
-
- pfd.fd = fd;
- pfd.events = POLLIN;
- pfd.revents = 0;
+ struct pollfd pfd[2] = {
+ { .fd = fd, .events = POLLIN },
+ { .fd = shutdown_fd, .events = POLLIN }
+ };
- int pollret = -1;
-
- pthread_cleanup_push(cancel_read, display);
- pollret = poll(&pfd, 1, -1);
- pthread_cleanup_pop(0);
-
- if (pollret != -1 && (pfd.revents & POLLIN))
+ int pollret = poll(pfd, 2, -1);
+ if (pollret != -1 && (pfd[0].revents & POLLIN))
{
wl_display_read_events(display);
@@ -1115,6 +1130,11 @@ control_thread(void *p_ret)
else
{
wl_display_cancel_read(display);
+
+ if (pollret == -1 || (pfd[1].revents & POLLIN))
+ {
+ break;
+ }
}
}