1 /* 2 * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.tools.jdi; 27 28 import com.sun.jdi.*; 29 import com.sun.jdi.connect.*; 30 import com.sun.jdi.connect.spi.*; 31 32 import java.io.IOException; 33 34 class SharedMemoryConnection extends Connection { 35 private long id; 36 private Object receiveLock = new Object(); 37 private Object sendLock = new Object(); 38 private Object closeLock = new Object(); 39 private boolean closed = false; 40 receiveByte0(long id)41 private native byte receiveByte0(long id) throws IOException; sendByte0(long id, byte b)42 private native void sendByte0(long id, byte b) throws IOException; close0(long id)43 private native void close0(long id); receivePacket0(long id)44 private native byte[] receivePacket0(long id)throws IOException; sendPacket0(long id, byte b[])45 private native void sendPacket0(long id, byte b[]) throws IOException; 46 47 // handshake with the target VM handshake(long handshakeTimeout)48 void handshake(long handshakeTimeout) throws IOException { 49 byte[] hello = "JDWP-Handshake".getBytes("UTF-8"); 50 51 for (int i=0; i<hello.length; i++) { 52 sendByte0(id, hello[i]); 53 } 54 for (int i=0; i<hello.length; i++) { 55 byte b = receiveByte0(id); 56 if (b != hello[i]) { 57 throw new IOException("handshake failed - unrecognized message from target VM"); 58 } 59 } 60 } 61 62 SharedMemoryConnection(long id)63 SharedMemoryConnection(long id) throws IOException { 64 this.id = id; 65 } 66 close()67 public void close() { 68 synchronized (closeLock) { 69 if (!closed) { 70 close0(id); 71 closed = true; 72 } 73 } 74 } 75 isOpen()76 public boolean isOpen() { 77 synchronized (closeLock) { 78 return !closed; 79 } 80 } 81 readPacket()82 public byte[] readPacket() throws IOException { 83 if (!isOpen()) { 84 throw new ClosedConnectionException("Connection closed"); 85 } 86 byte b[]; 87 try { 88 // only one thread may be reading at a time 89 synchronized (receiveLock) { 90 b = receivePacket0(id); 91 } 92 } catch (IOException ioe) { 93 if (!isOpen()) { 94 throw new ClosedConnectionException("Connection closed"); 95 } else { 96 throw ioe; 97 } 98 } 99 return b; 100 } 101 writePacket(byte b[])102 public void writePacket(byte b[]) throws IOException { 103 if (!isOpen()) { 104 throw new ClosedConnectionException("Connection closed"); 105 } 106 107 /* 108 * Check the packet size 109 */ 110 if (b.length < 11) { 111 throw new IllegalArgumentException("packet is insufficient size"); 112 } 113 int b0 = b[0] & 0xff; 114 int b1 = b[1] & 0xff; 115 int b2 = b[2] & 0xff; 116 int b3 = b[3] & 0xff; 117 int len = ((b0 << 24) | (b1 << 16) | (b2 << 8) | (b3 << 0)); 118 if (len < 11) { 119 throw new IllegalArgumentException("packet is insufficient size"); 120 } 121 122 /* 123 * Check that the byte array contains the complete packet 124 */ 125 if (len > b.length) { 126 throw new IllegalArgumentException("length mis-match"); 127 } 128 129 try { 130 // only one thread may be writing at a time 131 synchronized(sendLock) { 132 sendPacket0(id, b); 133 } 134 } catch (IOException ioe) { 135 if (!isOpen()) { 136 throw new ClosedConnectionException("Connection closed"); 137 } else { 138 throw ioe; 139 } 140 } 141 } 142 } 143 144