checkpoint. turned off nagle and send buffering. also

added test to skip clipboard conversion if a previous
conversion from that owner failed.
This commit is contained in:
crs 2002-05-01 15:31:47 +00:00
parent 59c5e4bf13
commit f2e83e607d
5 changed files with 54 additions and 2 deletions

View File

@ -13,7 +13,7 @@ RMR = /bin/rm -rf
#
# compiler options
#
GCXXDEFS = -D_XOPEN_SOURCE=600
GCXXDEFS = -D_XOPEN_SOURCE=600 -D_SVID_SOURCE
GCXXINCS = -I$(DEPTH)/include -I/usr/X11R6/include
GCXXOPTS = -Wall -W -fexceptions
CXXOPTIMIZER = -g

View File

@ -9,6 +9,9 @@
# define INCL_WINSOCK_API_TYPEDEFS 0
# include <winsock2.h>
typedef int ssize_t;
# if !defined(SOL_TCP)
# define SOL_TCP IPPROTO_TCP
# endif
#else
# define FAR
# define PASCAL
@ -21,6 +24,9 @@ typedef int ssize_t;
# include <netdb.h>
# include <netinet/in.h>
# include <errno.h>
# if !defined(TCP_NODELAY) || !defined(SOL_TCP)
# include <netinet/tcp.h>
# endif
#endif
// FIXME -- must handle htonl and ilk when defined as macros
@ -31,6 +37,7 @@ public:
typedef SOCKET Socket;
typedef struct sockaddr Address;
typedef int AddressLength;
typedef BOOL TCPNoDelayType;
struct PollEntry {
Socket fd;
short events;
@ -47,6 +54,7 @@ public:
typedef struct sockaddr Address;
typedef socklen_t AddressLength;
typedef struct pollfd PollEntry;
typedef int TCPNoDelayType;
enum {
kPOLLIN = POLLIN,
kPOLLOUT = POLLOUT,

View File

@ -128,6 +128,16 @@ void CTCPSocket::init()
m_output = new CBufferedOutputStream(m_mutex,
new TMethodJob<CTCPSocket>(
this, &CTCPSocket::closeOutput));
// turn off Nagle algorithm. we send lots of very short messages
// that should be sent without (much) delay. for example, the
// mouse motion messages are much less useful if they're delayed.
CNetwork::TCPNoDelayType flag = 1;
CNetwork::setsockopt(m_fd, SOL_TCP, TCP_NODELAY, &flag, sizeof(flag));
// don't buffer sends, we merge messages ourself
int data = 0;
CNetwork::setsockopt(m_fd, SOL_SOCKET, SO_SNDBUF, &data, sizeof(data));
}
void CTCPSocket::ioThread(void*)

View File

@ -261,6 +261,23 @@ void CXWindowsScreen::getDisplayClipboard(
CLock lock(&m_mutex);
Atom selection = m_atomClipboard[id];
// if we're trying to request the clipboard from the same
// unresponsive owner then immediately give up. this is lame
// because we can't be sure the owner won't become responsive;
// we can only ask the X server for the current owner, not the
// owner at time timestamp, allowing a race condition; and we
// don't detect if the owner window is destroyed in order to
// reset the unresponsive flag.
Window owner = XGetSelectionOwner(m_display, selection);
if (m_clipboards[id].m_unresponsive) {
if (owner != None && owner == m_clipboards[id].m_owner) {
clipboard->close();
return;
}
}
CClipboardInfo& clipboardInfo =
const_cast<CClipboardInfo&>(m_clipboards[id]);
// ask the selection for all the formats it has. some owners return
// the TARGETS atom and some the ATOM atom when TARGETS is requested.
Atom format;
@ -268,6 +285,10 @@ void CXWindowsScreen::getDisplayClipboard(
if (getDisplayClipboard(selection, m_atomTargets,
requestor, timestamp, &format, &targets) &&
(format == m_atomTargets || format == XA_ATOM)) {
// save owner info
clipboardInfo.m_owner = owner;
clipboardInfo.m_unresponsive = false;
// get each target (that we can interpret). some owners return
// some targets multiple times in the list so don't try to get
// those multiple times.
@ -330,6 +351,11 @@ void CXWindowsScreen::getDisplayClipboard(
else {
// non-ICCCM conforming selection owner. try TEXT format.
// FIXME
// save owner info
clipboardInfo.m_owner = owner;
clipboardInfo.m_unresponsive = true;
log((CLOG_DEBUG1 "selection doesn't support TARGETS, format is %d", format));
}
@ -1014,7 +1040,9 @@ Time CXWindowsScreen::getCurrentTimeNoLock(
CXWindowsScreen::CClipboardInfo::CClipboardInfo() :
m_clipboard(),
m_lostClipboard(CurrentTime),
m_requests()
m_requests(),
m_owner(None),
m_unresponsive(false)
{
// do nothing
}

View File

@ -161,6 +161,12 @@ private:
// the request queues
CRequestMap m_requests;
// owner of clipboard when we last asked for it
Window m_owner;
// true iff the previous request to m_owner got no reply
bool m_unresponsive;
};
Display* m_display;