# HG changeset patch # User Shinji KONO # Date 1312513697 -32400 # Node ID 3f73ebf918bd9ccf5bbcdf815b7e36ee73d0e3d9 # Parent 4199efcc4260beb95b25509cd99e8a04c85b2ed4 add time out to avoid memory overlow caused by suspended clients. diff -r 4199efcc4260 -r 3f73ebf918bd src/myVncProxy/MulticastQueue.java --- 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 next = null; - T item; + T item = null; do { try { next = node.next(); }catch(InterruptedException _e){ - _e.printStackTrace(); + continue; } item = node.getItem(); node = next; diff -r 4199efcc4260 -r 3f73ebf918bd src/myVncProxy/MyRfbProto.java --- 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 { LinkedListbufs = new LinkedList(); ByteBuffer header = ByteBuffer.allocate(16); @@ -626,7 +641,25 @@ // rfb.addSockTmp(newCli); // addSock(newCli); final Client > 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 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) {