XQuartz: use a condition variable to signal when darwinEvents is ready rather than polling
(cherry picked from commit ff1c443cad
)
This commit is contained in:
parent
38da26cd36
commit
ee86b75119
|
@ -80,21 +80,36 @@ void QuartzModeEQInit(void);
|
||||||
static int old_flags = 0; // last known modifier state
|
static int old_flags = 0; // last known modifier state
|
||||||
|
|
||||||
static xEvent *darwinEvents = NULL;
|
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) {
|
static inline void darwinEvents_lock(void) {
|
||||||
int err;
|
int err;
|
||||||
if((err = pthread_mutex_lock(&darwinEvents_mutex))) {
|
if((err = pthread_mutex_lock(&mieq_lock))) {
|
||||||
ErrorF("%s:%s:%d: Failed to lock darwinEvents_mutex: %d\n",
|
ErrorF("%s:%s:%d: Failed to lock mieq_lock: %d\n",
|
||||||
__FILE__, __FUNCTION__, __LINE__, err);
|
__FILE__, __FUNCTION__, __LINE__, err);
|
||||||
spewCallStack();
|
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) {
|
static inline void darwinEvents_unlock(void) {
|
||||||
int err;
|
int err;
|
||||||
if((err = pthread_mutex_unlock(&darwinEvents_mutex))) {
|
if((err = pthread_mutex_unlock(&mieq_lock))) {
|
||||||
ErrorF("%s:%s:%d: Failed to unlock darwinEvents_mutex: %d\n",
|
ErrorF("%s:%s:%d: Failed to unlock mieq_lock: %d\n",
|
||||||
__FILE__, __FUNCTION__, __LINE__, err);
|
__FILE__, __FUNCTION__, __LINE__, err);
|
||||||
spewCallStack();
|
spewCallStack();
|
||||||
}
|
}
|
||||||
|
@ -333,10 +348,16 @@ Bool DarwinEQInit(void) {
|
||||||
|
|
||||||
QuartzModeEQInit();
|
QuartzModeEQInit();
|
||||||
|
|
||||||
if (!darwinEvents)
|
if (!darwinEvents) {
|
||||||
darwinEvents = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum());
|
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;
|
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);
|
POINTER_ABSOLUTE, 0, dev==darwinTablet?5:2, valuators);
|
||||||
for(i=0; i<num_events; i++) mieqEnqueue (dev, &darwinEvents[i]);
|
for(i=0; i<num_events; i++) mieqEnqueue (dev, &darwinEvents[i]);
|
||||||
DarwinPokeEQ();
|
DarwinPokeEQ();
|
||||||
|
|
||||||
} darwinEvents_unlock();
|
} darwinEvents_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -578,13 +598,8 @@ void DarwinSendDDXEvent(int type, int argc, ...) {
|
||||||
va_end (args);
|
va_end (args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we're called from something other than the X server thread, we need
|
darwinEvents_lock(); {
|
||||||
* to wait for the X server to setup darwinEvents.
|
mieqEnqueue(darwinPointer, &xe);
|
||||||
*/
|
DarwinPokeEQ();
|
||||||
while(darwinEvents == NULL) {
|
} darwinEvents_unlock();
|
||||||
usleep(250000);
|
|
||||||
}
|
|
||||||
|
|
||||||
mieqEnqueue(darwinPointer, &xe);
|
|
||||||
DarwinPokeEQ();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -412,11 +412,6 @@ int main(int argc, char **argv, char **envp) {
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void *add_launchd_display_thread(void *data) {
|
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 */
|
/* Start listening on the launchd fd */
|
||||||
int launchd_fd = launchd_display_fd();
|
int launchd_fd = launchd_display_fd();
|
||||||
if(launchd_fd != -1) {
|
if(launchd_fd != -1) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user