Mercurial > hg > Members > nobuyasu > tightVNCProxy
changeset 109:3f73ebf918bd
add time out to avoid memory overlow caused by suspended clients.
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 05 Aug 2011 12:08:17 +0900 |
parents | 4199efcc4260 |
children | 6f95e5efa799 |
files | src/myVncProxy/MulticastQueue.java src/myVncProxy/MyRfbProto.java |
diffstat | 2 files changed, 37 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/src/myVncProxy/MulticastQueue.java Fri Aug 05 10:57:05 2011 +0900 +++ b/src/myVncProxy/MulticastQueue.java Fri Aug 05 12:08:17 2011 +0900 @@ -36,12 +36,12 @@ public T poll() { Node<T> next = null; - T item; + T item = null; do { try { next = node.next(); }catch(InterruptedException _e){ - _e.printStackTrace(); + continue; } item = node.getItem(); node = next;
--- a/src/myVncProxy/MyRfbProto.java Fri Aug 05 10:57:05 2011 +0900 +++ b/src/myVncProxy/MyRfbProto.java Fri Aug 05 12:08:17 2011 +0900 @@ -26,6 +26,7 @@ import myVncProxy.MulticastQueue.Client; import java.util.concurrent.ExecutorService; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.zip.DataFormatException; import java.util.zip.Deflater; import java.util.zip.Inflater; @@ -575,6 +576,20 @@ return len; } + /** + * send data to clients + * @param dataLen + * @throws IOException + * @throws DataFormatException + * + * Zlibed packet is compressed in context dependent way, that is, it have to send from the beginning. But this is + * impossible. So we have to compress it again for each clients. Separate deflater for each clients is necessary. + * + * Java's deflater does not support flush. This means to get the result, we have to finish the compression. Reseting + * start new compression, but it is not accepted well in zlib continuous reading. So we need new Encoding ZRLEE + * which reset decoder for each packet. ZRLEE can be invisible from user, but it have to be implemented in the clients. + * ZRLEE compression is not context dependent, so no recompression is necessary. + */ void readSendData(int dataLen) throws IOException, DataFormatException { LinkedList<ByteBuffer>bufs = new LinkedList<ByteBuffer>(); ByteBuffer header = ByteBuffer.allocate(16); @@ -626,7 +641,25 @@ // rfb.addSockTmp(newCli); // addSock(newCli); final Client <LinkedList<ByteBuffer>> c = multicastqueue.newClient(); - + final AtomicBoolean writerRunning = new AtomicBoolean(); + final Runnable timer = new Runnable() { + public void run() { + for(;;) { + long timeout = 30000; + try { + synchronized(this) { + wait(timeout); + while (!writerRunning.get()) { + c.poll(); // discard, should be timeout + wait(10); + } + } + } catch (InterruptedException e) { + } + } + } + }; + new Thread(timer).start(); final Runnable reader = new Runnable() { public void run() { byte b[] = new byte[4096]; @@ -664,12 +697,11 @@ for (;;) { LinkedList<ByteBuffer> bufs = c.poll(); int inputIndex = 0; - ByteBuffer header = bufs.get(inputIndex++); + ByteBuffer header = bufs.get(inputIndex); if (header==null) continue; if (header.get(0)==RfbProto.FramebufferUpdate) { System.out.println("client "+ myId); } - os.write(header.array(),header.position(),header.limit()); writeToClient(os, bufs, inputIndex); } } catch (IOException e) {