summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Huddleston <jeremyhu@freedesktop.org>2008-06-04 12:01:19 -0700
committerJeremy Huddleston <jeremyhu@freedesktop.org>2008-06-04 12:24:12 -0700
commitee86b751192b690973ee2a1446a406bc721ce8eb (patch)
tree17a837e647cd84962f0e3d40c666d017e7b952ed
parent38da26cd36957a45b2a47ef124282f7d863a9fd3 (diff)
XQuartz: use a condition variable to signal when darwinEvents is ready rather than polling
(cherry picked from commit ff1c443cadf11d12a7d939e51194f6105153870e)
-rw-r--r--hw/xquartz/darwinEvents.c53
-rw-r--r--hw/xquartz/mach-startup/bundle-main.c5
2 files changed, 34 insertions, 24 deletions
diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c
index 0ecb064c4..1e79cd3bc 100644
--- a/hw/xquartz/darwinEvents.c
+++ b/hw/xquartz/darwinEvents.c
@@ -80,21 +80,36 @@ void QuartzModeEQInit(void);
static int old_flags = 0; // last known modifier state
static xEvent *darwinEvents = NULL;
-static pthread_mutex_t darwinEvents_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static pthread_mutex_t mieq_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t mieq_ready_cond = PTHREAD_COND_INITIALIZER;
static inline void darwinEvents_lock(void) {
int err;
- if((err = pthread_mutex_lock(&darwinEvents_mutex))) {
- ErrorF("%s:%s:%d: Failed to lock darwinEvents_mutex: %d\n",
+ if((err = pthread_mutex_lock(&mieq_lock))) {
+ ErrorF("%s:%s:%d: Failed to lock mieq_lock: %d\n",
__FILE__, __FUNCTION__, __LINE__, err);
spewCallStack();
}
+ if(darwinEvents == NULL) {
+ pthread_cond_wait(&mieq_ready_cond, &mieq_lock);
+
+ /* We want to give xinit time to finish running xinitrc before we accept
+ * the launchd socket connection.
+ *
+ * Yes, we lock then immediately unlock because the lock does a cond_wait
+ * when darwinEvents == NULL
+ *
+ * TODO: Cleanup this race more elegantly.
+ */
+ sleep(2);
+ }
}
static inline void darwinEvents_unlock(void) {
int err;
- if((err = pthread_mutex_unlock(&darwinEvents_mutex))) {
- ErrorF("%s:%s:%d: Failed to unlock darwinEvents_mutex: %d\n",
+ if((err = pthread_mutex_unlock(&mieq_lock))) {
+ ErrorF("%s:%s:%d: Failed to unlock mieq_lock: %d\n",
__FILE__, __FUNCTION__, __LINE__, err);
spewCallStack();
}
@@ -333,11 +348,17 @@ Bool DarwinEQInit(void) {
QuartzModeEQInit();
- if (!darwinEvents)
+ if (!darwinEvents) {
darwinEvents = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum());
- if (!darwinEvents)
- FatalError("Couldn't allocate event buffer\n");
-
+
+ if (!darwinEvents)
+ FatalError("Couldn't allocate event buffer\n");
+
+ darwinEvents_lock();
+ pthread_cond_broadcast(&mieq_ready_cond);
+ darwinEvents_unlock();
+ }
+
return TRUE;
}
@@ -453,7 +474,6 @@ void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int poin
POINTER_ABSOLUTE, 0, dev==darwinTablet?5:2, valuators);
for(i=0; i<num_events; i++) mieqEnqueue (dev, &darwinEvents[i]);
DarwinPokeEQ();
-
} darwinEvents_unlock();
}
@@ -578,13 +598,8 @@ void DarwinSendDDXEvent(int type, int argc, ...) {
va_end (args);
}
- /* If we're called from something other than the X server thread, we need
- * to wait for the X server to setup darwinEvents.
- */
- while(darwinEvents == NULL) {
- usleep(250000);
- }
-
- mieqEnqueue(darwinPointer, &xe);
- DarwinPokeEQ();
+ darwinEvents_lock(); {
+ mieqEnqueue(darwinPointer, &xe);
+ DarwinPokeEQ();
+ } darwinEvents_unlock();
}
diff --git a/hw/xquartz/mach-startup/bundle-main.c b/hw/xquartz/mach-startup/bundle-main.c
index 9a50668c3..1c325186a 100644
--- a/hw/xquartz/mach-startup/bundle-main.c
+++ b/hw/xquartz/mach-startup/bundle-main.c
@@ -412,11 +412,6 @@ int main(int argc, char **argv, char **envp) {
}
#else
void *add_launchd_display_thread(void *data) {
- /* TODO: Really fix this race... we want xinitrc to finish before connections
- * are accepted on the launchd socket.
- */
- sleep(2);
-
/* Start listening on the launchd fd */
int launchd_fd = launchd_display_fd();
if(launchd_fd != -1) {