Browse Source

Move socket write event handling in to the RFB core

What to do when a socket is writeable should be handled in the
RFB core code as there may be other events we want to fire off
when this happens.
tags/v1.6.90
Pierre Ossman 8 years ago
parent
commit
d408ca5146

+ 7
- 2
common/network/Socket.h View File

@@ -125,12 +125,17 @@ namespace network {
// resources to be freed.
virtual void removeSocket(network::Socket* sock) = 0;

// processSocketEvent() tells the server there is a Socket read event.
// processSocketReadEvent() tells the server there is a Socket read event.
// The implementation can indicate that the Socket is no longer active
// by calling shutdown() on it. The caller will then call removeSocket()
// soon after processSocketEvent returns, to allow any pre-Socket
// resources to be tidied up.
virtual void processSocketEvent(network::Socket* sock) = 0;
virtual void processSocketReadEvent(network::Socket* sock) = 0;

// processSocketReadEvent() tells the server there is a Socket write event.
// This is only necessary if the Socket has been put in non-blocking
// mode and needs this callback to flush the buffer.
virtual void processSocketWriteEvent(network::Socket* sock) = 0;

// checkTimeouts() allows the server to check socket timeouts, etc. The
// return value is the number of milliseconds to wait before

+ 18
- 1
common/rfb/HTTPServer.cxx View File

@@ -337,7 +337,7 @@ HTTPServer::removeSocket(network::Socket* sock) {
}

void
HTTPServer::processSocketEvent(network::Socket* sock) {
HTTPServer::processSocketReadEvent(network::Socket* sock) {
std::list<Session*>::iterator i;
for (i=sessions.begin(); i!=sessions.end(); i++) {
if ((*i)->getSock() == sock) {
@@ -356,6 +356,23 @@ HTTPServer::processSocketEvent(network::Socket* sock) {
throw rdr::Exception("invalid Socket in HTTPServer");
}

void
HTTPServer::processSocketWriteEvent(network::Socket* sock) {
std::list<Session*>::iterator i;
for (i=sessions.begin(); i!=sessions.end(); i++) {
if ((*i)->getSock() == sock) {
try {
sock->outStream().flush();
} catch (rdr::Exception& e) {
vlog.error("untrapped: %s", e.str());
sock->shutdown();
}
return;
}
}
throw rdr::Exception("invalid Socket in HTTPServer");
}

void HTTPServer::getSockets(std::list<network::Socket*>* sockets)
{
sockets->clear();

+ 7
- 2
common/rfb/HTTPServer.h View File

@@ -58,11 +58,16 @@ namespace rfb {
// Could clean up socket-specific resources here.
virtual void removeSocket(network::Socket* sock);

// processSocketEvent()
// processSocketReadEvent()
// The platform-specific side of the server implementation calls
// this method whenever data arrives on one of the active
// network sockets.
virtual void processSocketEvent(network::Socket* sock);
virtual void processSocketReadEvent(network::Socket* sock);

// processSocketWriteEvent()
// Similar to processSocketReadEvent(), but called when it is
// possible to write more data to a socket.
virtual void processSocketWriteEvent(network::Socket* sock);

// Check for socket timeouts
virtual int checkTimeouts();

+ 11
- 0
common/rfb/VNCSConnectionST.cxx View File

@@ -190,6 +190,17 @@ void VNCSConnectionST::processMessages()
}
}

void VNCSConnectionST::flushSocket()
{
if (state() == RFBSTATE_CLOSING) return;
try {
setSocketTimeouts();
sock->outStream().flush();
} catch (rdr::Exception &e) {
close(e.str());
}
}

void VNCSConnectionST::pixelBufferChange()
{
try {

+ 3
- 0
common/rfb/VNCSConnectionST.h View File

@@ -65,6 +65,9 @@ namespace rfb {
// Socket if an error occurs, via the close() call.
void processMessages();

// flushSocket() pushes any unwritten data on to the network.
void flushSocket();

// Called when the underlying pixelbuffer is resized or replaced.
void pixelBufferChange();


+ 14
- 1
common/rfb/VNCServerST.cxx View File

@@ -163,7 +163,7 @@ void VNCServerST::removeSocket(network::Socket* sock) {
closingSockets.remove(sock);
}

void VNCServerST::processSocketEvent(network::Socket* sock)
void VNCServerST::processSocketReadEvent(network::Socket* sock)
{
// - Find the appropriate VNCSConnectionST and process the event
std::list<VNCSConnectionST*>::iterator ci;
@@ -176,6 +176,19 @@ void VNCServerST::processSocketEvent(network::Socket* sock)
throw rdr::Exception("invalid Socket in VNCServerST");
}

void VNCServerST::processSocketWriteEvent(network::Socket* sock)
{
// - Find the appropriate VNCSConnectionST and process the event
std::list<VNCSConnectionST*>::iterator ci;
for (ci = clients.begin(); ci != clients.end(); ci++) {
if ((*ci)->getSock() == sock) {
(*ci)->flushSocket();
return;
}
}
throw rdr::Exception("invalid Socket in VNCServerST");
}

int VNCServerST::checkTimeouts()
{
int timeout = 0;

+ 6
- 2
common/rfb/VNCServerST.h View File

@@ -67,11 +67,15 @@ namespace rfb {
// Clean up any resources associated with the Socket
virtual void removeSocket(network::Socket* sock);

// processSocketEvent
// processSocketReadEvent
// Read more RFB data from the Socket. If an error occurs during
// processing then shutdown() is called on the Socket, causing
// removeSocket() to be called by the caller at a later time.
virtual void processSocketEvent(network::Socket* sock);
virtual void processSocketReadEvent(network::Socket* sock);

// processSocketWriteEvent
// Flush pending data from the Socket on to the network.
virtual void processSocketWriteEvent(network::Socket* sock);

// checkTimeouts
// Returns the number of milliseconds left until the next idle timeout

+ 1
- 1
unix/x0vncserver/x0vncserver.cxx View File

@@ -593,7 +593,7 @@ int main(int argc, char** argv)
// Process events on existing VNC connections
for (i = sockets.begin(); i != sockets.end(); i++) {
if (FD_ISSET((*i)->getFd(), &rfds))
server.processSocketEvent(*i);
server.processSocketReadEvent(*i);
}

if (desktop.isRunning() && sched.goodTimeToPoll()) {

+ 4
- 4
unix/xserver/hw/vnc/XserverDesktop.cc View File

@@ -495,7 +495,7 @@ void XserverDesktop::readWakeupHandler(fd_set* fds, int nfds)
int fd = (*i)->getFd();
if (FD_ISSET(fd, fds)) {
FD_CLR(fd, fds);
server->processSocketEvent(*i);
server->processSocketReadEvent(*i);
}
}

@@ -505,7 +505,7 @@ void XserverDesktop::readWakeupHandler(fd_set* fds, int nfds)
int fd = (*i)->getFd();
if (FD_ISSET(fd, fds)) {
FD_CLR(fd, fds);
httpServer->processSocketEvent(*i);
httpServer->processSocketReadEvent(*i);
}
}
}
@@ -581,7 +581,7 @@ void XserverDesktop::writeWakeupHandler(fd_set* fds, int nfds)
int fd = (*i)->getFd();
if (FD_ISSET(fd, fds)) {
FD_CLR(fd, fds);
(*i)->outStream().flush();
server->processSocketWriteEvent(*i);
}
}

@@ -591,7 +591,7 @@ void XserverDesktop::writeWakeupHandler(fd_set* fds, int nfds)
int fd = (*i)->getFd();
if (FD_ISSET(fd, fds)) {
FD_CLR(fd, fds);
(*i)->outStream().flush();
httpServer->processSocketWriteEvent(*i);
}
}
}

+ 1
- 1
win/rfb_win32/SocketManager.cxx View File

@@ -193,7 +193,7 @@ void SocketManager::processEvent(HANDLE event) {
WSAResetEvent(event);

// Call the socket server to process the event
ci.server->processSocketEvent(ci.sock);
ci.server->processSocketReadEvent(ci.sock);
if (ci.sock->isShutdown()) {
remSocket(ci.sock);
return;

Loading…
Cancel
Save