removed poll/sleep code to improve performance.

This commit is contained in:
crs 2002-06-02 21:03:38 +00:00
parent 869617a34a
commit a541ebc557
3 changed files with 49 additions and 23 deletions

View File

@ -1,8 +1,8 @@
#include "CXWindowsClipboard.h" #include "CXWindowsClipboard.h"
#include "CXWindowsUtil.h" #include "CXWindowsUtil.h"
#include "CLog.h" #include "CLog.h"
#include "CStopwatch.h"
#include "CThread.h" #include "CThread.h"
#include "TMethodJob.h"
#include <stdio.h> #include <stdio.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
@ -1099,6 +1099,9 @@ bool CXWindowsClipboard::CICCCMGetClipboard::readClipboard(
*m_actualTarget = None; *m_actualTarget = None;
*m_data = ""; *m_data = "";
// get timeout atom
m_timeout = XInternAtom(display, "SYNERGY_TIMEOUT", False);
// delete target property // delete target property
XDeleteProperty(display, m_requestor, m_property); XDeleteProperty(display, m_requestor, m_property);
@ -1112,26 +1115,21 @@ bool CXWindowsClipboard::CICCCMGetClipboard::readClipboard(
XConvertSelection(display, selection, target, XConvertSelection(display, selection, target,
m_property, m_requestor, m_time); m_property, m_requestor, m_time);
// process selection events. use a timeout so we don't get // process selection events. have a separate thread send us an
// screwed by a bad selection owner. // event after a timeout so we don't get locked up by badly
CStopwatch timer(true); // behaved selection owners.
CThread timer(new TMethodJob<CXWindowsClipboard::CICCCMGetClipboard>(
this,
&CXWindowsClipboard::CICCCMGetClipboard::timeout,
display));
XEvent xevent; XEvent xevent;
while (!m_done && !m_failed) { while (!m_done && !m_failed) {
// return false if we've timed-out
if (timer.getTime() >= 0.2) {
log((CLOG_DEBUG1 "request timed out"));
XSelectInput(display, m_requestor, attr.your_event_mask);
return false;
}
// process events // process events
if (!XCheckIfEvent(display, &xevent, XIfEvent(display, &xevent,
&CXWindowsClipboard::CICCCMGetClipboard::eventPredicate, &CXWindowsClipboard::CICCCMGetClipboard::eventPredicate,
reinterpret_cast<XPointer>(this))) { reinterpret_cast<XPointer>(this));
// wait a bit to avoid spinning
CThread::sleep(0.05);
}
} }
timer.cancel();
// restore mask // restore mask
XSelectInput(display, m_requestor, attr.your_event_mask); XSelectInput(display, m_requestor, attr.your_event_mask);
@ -1188,6 +1186,16 @@ bool CXWindowsClipboard::CICCCMGetClipboard::doEventPredicate(
// otherwise not interested // otherwise not interested
return false; return false;
case ClientMessage:
// done if this is the timeout message
if (xevent->xclient.window == m_requestor &&
xevent->xclient.message_type == m_timeout) {
return true;
}
// otherwise not interested
return false;
default: default:
// not interested // not interested
return false; return false;
@ -1200,7 +1208,7 @@ bool CXWindowsClipboard::CICCCMGetClipboard::doEventPredicate(
m_property, m_data, &target, NULL, True)) { m_property, m_data, &target, NULL, True)) {
// unable to read property // unable to read property
m_failed = true; m_failed = true;
return True; return true;
} }
// note if incremental. if we're already incremental then the // note if incremental. if we're already incremental then the
@ -1276,6 +1284,24 @@ Bool CXWindowsClipboard::CICCCMGetClipboard::eventPredicate(
return self->doEventPredicate(display, xevent) ? True : False; return self->doEventPredicate(display, xevent) ? True : False;
} }
void CXWindowsClipboard::CICCCMGetClipboard::timeout(
void* vdisplay)
{
// wait
CThread::sleep(0.2); // FIXME -- is this too short?
// send wake up
Display* display = reinterpret_cast<Display*>(vdisplay);
XEvent event;
event.xclient.type = ClientMessage;
event.xclient.display = display;
event.xclient.window = m_requestor;
event.xclient.message_type = m_timeout;
event.xclient.format = 8;
CXWindowsUtil::CErrorLock lock;
XSendEvent(display, m_requestor, False, 0, &event);
}
// //
// CXWindowsClipboard::CReply // CXWindowsClipboard::CReply

View File

@ -106,6 +106,7 @@ private:
static Bool eventPredicate(Display* display, static Bool eventPredicate(Display* display,
XEvent* event, XEvent* event,
XPointer arg); XPointer arg);
void timeout(void*);
private: private:
Window m_requestor; Window m_requestor;
@ -125,6 +126,9 @@ private:
// selection owner cannot convert to the requested type. // selection owner cannot convert to the requested type.
Atom* m_actualTarget; Atom* m_actualTarget;
// property used in event to wake up event loop
Atom m_timeout;
public: public:
// true iff the selection owner didn't follow ICCCM conventions // true iff the selection owner didn't follow ICCCM conventions
bool m_error; bool m_error;

View File

@ -150,12 +150,8 @@ Time CXWindowsUtil::getCurrentTime(
// wait for reply // wait for reply
XEvent xevent; XEvent xevent;
while (XCheckIfEvent(display, &xevent, XIfEvent(display, &xevent, &CXWindowsUtil::propertyNotifyPredicate,
&CXWindowsUtil::propertyNotifyPredicate, (XPointer)&filter);
(XPointer)&filter) != True) {
// wait a bit
CThread::sleep(0.05);
}
assert(xevent.type == PropertyNotify); assert(xevent.type == PropertyNotify);
assert(xevent.xproperty.window == window); assert(xevent.xproperty.window == window);
assert(xevent.xproperty.atom == atom); assert(xevent.xproperty.atom == atom);