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