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 26package com.sun.tools.jdi; 27 28import com.sun.jdi.*; 29import com.sun.jdi.connect.*; 30import com.sun.jdi.connect.spi.*; 31 32import java.io.IOException; 33import java.util.Map; 34import java.util.ResourceBundle; 35 36class SharedMemoryTransportService extends TransportService { 37 private ResourceBundle messages = null; 38 39 /** 40 * The listener returned by startListening 41 */ 42 static class SharedMemoryListenKey extends ListenKey { 43 long id; 44 String name; 45 46 SharedMemoryListenKey(long id, String name) { 47 this.id = id; 48 this.name = name; 49 } 50 51 long id() { 52 return id; 53 } 54 55 void setId(long id) { 56 this.id = id; 57 } 58 59 public String address() { 60 return name; 61 } 62 63 public String toString() { 64 return address(); 65 } 66 } 67 68 SharedMemoryTransportService() { 69 System.loadLibrary("dt_shmem"); 70 initialize(); 71 } 72 73 public String name() { 74 return "SharedMemory"; 75 } 76 77 public String defaultAddress() { 78 return "javadebug"; 79 } 80 81 /** 82 * Return localized description of this transport service 83 */ 84 public String description() { 85 synchronized (this) { 86 if (messages == null) { 87 messages = ResourceBundle.getBundle("com.sun.tools.jdi.resources.jdi"); 88 } 89 } 90 return messages.getString("memory_transportservice.description"); 91 } 92 93 public Capabilities capabilities() { 94 return new SharedMemoryTransportServiceCapabilities(); 95 } 96 97 private native void initialize(); 98 private native long startListening0(String address) throws IOException; 99 private native long attach0(String address, long attachTimeout) throws IOException; 100 private native void stopListening0(long id) throws IOException; 101 private native long accept0(long id, long acceptTimeout) throws IOException; 102 private native String name(long id) throws IOException; 103 104 public Connection attach(String address, long attachTimeout, long handshakeTimeout) throws IOException { 105 if (address == null) { 106 throw new NullPointerException("address is null"); 107 } 108 long id = attach0(address, attachTimeout); 109 SharedMemoryConnection conn = new SharedMemoryConnection(id); 110 conn.handshake(handshakeTimeout); 111 return conn; 112 } 113 114 public TransportService.ListenKey startListening(String address) throws IOException { 115 if (address == null || address.length() == 0) { 116 address = defaultAddress(); 117 } 118 long id = startListening0(address); 119 return new SharedMemoryListenKey(id, name(id)); 120 } 121 122 public ListenKey startListening() throws IOException { 123 return startListening(null); 124 } 125 126 public void stopListening(ListenKey listener) throws IOException { 127 if (!(listener instanceof SharedMemoryListenKey)) { 128 throw new IllegalArgumentException("Invalid listener"); 129 } 130 131 long id; 132 SharedMemoryListenKey key = (SharedMemoryListenKey)listener; 133 synchronized (key) { 134 id = key.id(); 135 if (id == 0) { 136 throw new IllegalArgumentException("Invalid listener"); 137 } 138 139 // invalidate the id 140 key.setId(0); 141 } 142 stopListening0(id); 143 } 144 145 public Connection accept(ListenKey listener, long acceptTimeout, long handshakeTimeout) throws IOException { 146 if (!(listener instanceof SharedMemoryListenKey)) { 147 throw new IllegalArgumentException("Invalid listener"); 148 } 149 150 long transportId; 151 SharedMemoryListenKey key = (SharedMemoryListenKey)listener; 152 synchronized (key) { 153 transportId = key.id(); 154 if (transportId == 0) { 155 throw new IllegalArgumentException("Invalid listener"); 156 } 157 } 158 159 // in theory another thread could call stopListening before 160 // accept0 is called. In that case accept0 will try to accept 161 // with an invalid "transport id" - this should result in an 162 // IOException. 163 164 long connectId = accept0(transportId, acceptTimeout); 165 SharedMemoryConnection conn = new SharedMemoryConnection(connectId); 166 conn.handshake(handshakeTimeout); 167 return conn; 168 } 169} 170 171 172class SharedMemoryTransportServiceCapabilities extends TransportService.Capabilities { 173 174 public boolean supportsMultipleConnections() { 175 return false; 176 } 177 178 public boolean supportsAttachTimeout() { 179 return true; 180 } 181 182 public boolean supportsAcceptTimeout() { 183 return true; 184 } 185 186 public boolean supportsHandshakeTimeout() { 187 return false; 188 } 189 190} 191