XQuartz: use a condition variable to signal when darwinEvents is ready rather than polling
This commit is contained in:
parent
c3558bb8cd
commit
ff1c443cad
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user