OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [classpath/] [jdwp/] [transport/] [JdwpConnection.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* JdwpConnection.java -- A JDWP-speaking connection
2
   Copyright (C) 2005, 2006, 2007 Free Software Foundation
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
terms of your choice, provided that you also meet, for each linked
32
independent module, the terms and conditions of the license of that
33
module.  An independent module is a module which is not derived from
34
or based on this library.  If you modify this library, you may extend
35
this exception to your version of the library, but you are not
36
obligated to do so.  If you do not wish to do so, delete this
37
exception statement from your version. */
38
 
39
 
40
package gnu.classpath.jdwp.transport;
41
 
42
import gnu.classpath.jdwp.Jdwp;
43
import gnu.classpath.jdwp.event.Event;
44
import gnu.classpath.jdwp.event.EventRequest;
45
 
46
import java.io.ByteArrayOutputStream;
47
import java.io.DataInputStream;
48
import java.io.DataOutputStream;
49
import java.io.IOException;
50
import java.util.ArrayList;
51
import java.util.Arrays;
52
 
53
/**
54
 * A connection via some transport to some JDWP-speaking entity.
55
 * This is also a thread which handles all communications to/from
56
 * the debugger. While access to the transport layer may be accessed by
57
 * several threads, start-up and initialization should not be allowed
58
 * to occur more than once.
59
 *
60
 * <p>This class is also a thread that is responsible for pulling
61
 * packets off the wire and sticking them in a queue for packet
62
 * processing threads.
63
 *
64
 * @author Keith Seitz (keiths@redhat.com)
65
 */
66
public class JdwpConnection
67
  extends Thread
68
{
69
  // The JDWP handshake
70
  private static final byte[] _HANDSHAKE = {'J', 'D', 'W', 'P', '-', 'H', 'a',
71
                                            'n', 'd', 's', 'h', 'a', 'k', 'e'};
72
 
73
  // Transport method
74
  private ITransport _transport;
75
 
76
  // Command queue
77
  private ArrayList _commandQueue;
78
 
79
  // Shutdown flag
80
  private boolean _shutdown;
81
 
82
  // Input stream from transport
83
  private DataInputStream _inStream;
84
 
85
  // Output stream from transprot
86
  private DataOutputStream _outStream;
87
 
88
  // A buffer used to construct the packet data
89
  private ByteArrayOutputStream _bytes;
90
 
91
  // A DataOutputStream for the byte buffer
92
  private DataOutputStream _doStream;
93
 
94
  /**
95
   * Creates a new <code>JdwpConnection</code> instance
96
   *
97
   * @param transport  the transport to use for communications
98
   */
99
  public JdwpConnection (ThreadGroup group, ITransport transport)
100
  {
101
    super (group, "JDWP connection thread");
102
    _transport = transport;
103
    _commandQueue = new ArrayList ();
104
    _shutdown = false;
105
    _bytes = new ByteArrayOutputStream ();
106
    _doStream = new DataOutputStream (_bytes);
107
  }
108
 
109
  /**
110
   * Initializes the connection, including connecting
111
   * to socket or shared memory endpoint
112
   *
113
   * @throws TransportException if initialization fails
114
   */
115
  public void initialize ()
116
    throws TransportException
117
  {
118
    // Initialize transport (connect socket, e.g.)
119
    _transport.initialize ();
120
 
121
    // Do handshake
122
    try
123
      {
124
        _inStream = new DataInputStream (_transport.getInputStream ());
125
        _outStream = new DataOutputStream (_transport.getOutputStream ());
126
        _doHandshake ();
127
      }
128
    catch (IOException ioe)
129
      {
130
        throw new TransportException (ioe);
131
      }
132
  }
133
 
134
  /* Does the JDWP handshake -- this should not need synchronization
135
     because this is called by VM startup code, i.e., no packet
136
     processing threads have started yet. */
137
  private void _doHandshake ()
138
    throws IOException
139
  {
140
    // According to the spec, the handshake is always initiated by
141
    // the debugger, regardless of whether the JVM is in client mode or
142
    // server mode.
143
 
144
    // Wait for handshake from debugger
145
    byte[] hshake = new byte[_HANDSHAKE.length];
146
    _inStream.readFully (hshake, 0, _HANDSHAKE.length);
147
 
148
    if (Arrays.equals (hshake, _HANDSHAKE))
149
      {
150
        // Send reply handshake
151
        _outStream.write (_HANDSHAKE, 0, _HANDSHAKE.length);
152
        return;
153
      }
154
    else
155
      {
156
        throw new IOException ("invalid JDWP handshake (\"" + hshake + "\")");
157
      }
158
  }
159
 
160
  /**
161
   * Main run method for the thread. This thread loops waiting for
162
   * packets to be read via the connection. When a packet is complete
163
   * and ready for processing, it places the packet in a queue that can
164
   * be accessed via <code>getPacket</code>
165
   */
166
  public void run ()
167
  {
168
    // Notify initialization thread (gnu.classpath.jdwp.Jdwp) that
169
    // the JdwpConnection thread is ready.
170
    Jdwp.getDefault().subcomponentInitialized ();
171
 
172
    while (!_shutdown)
173
      {
174
        try
175
          {
176
            _readOnePacket ();
177
          }
178
        catch (IOException ioe)
179
          {
180
            /* IOException can occur for two reasons:
181
               1. Lost connection with the other side
182
               2. Transport was shutdown
183
               In either case, we make sure that all of the
184
               back-end gets shutdown. */
185
            Jdwp.getDefault().shutdown ();
186
          }
187
        catch (Throwable t)
188
          {
189
            System.out.println ("JdwpConnection.run: caught an exception: "
190
                                + t);
191
            // Just keep going
192
          }
193
      }
194
  }
195
 
196
  // Reads a single packet from the connection, adding it to the packet
197
  // queue when a complete packet is ready.
198
  private void _readOnePacket ()
199
    throws IOException
200
  {
201
    byte[] data = null;
202
 
203
    // Read in the packet
204
    int length = _inStream.readInt ();
205
    if (length < 11)
206
      {
207
        throw new IOException ("JDWP packet length < 11 ("
208
                               + length + ")");
209
      }
210
 
211
    data = new byte[length];
212
    data[0] = (byte) (length >>> 24);
213
    data[1] = (byte) (length >>> 16);
214
    data[2] = (byte) (length >>> 8);
215
    data[3] = (byte) length;
216
    _inStream.readFully (data, 4, length - 4);
217
 
218
    JdwpPacket packet = JdwpPacket.fromBytes (data);
219
    if (packet != null)
220
      {
221
        synchronized (_commandQueue)
222
          {
223
            _commandQueue.add (packet);
224
            _commandQueue.notifyAll ();
225
          }
226
      }
227
  }
228
 
229
  /**
230
   * Returns a packet from the queue of ready packets
231
   *
232
   * @returns  a <code>JdwpPacket</code> ready for processing
233
   *           <code>null</code> when shutting down
234
   */
235
  public JdwpPacket getPacket ()
236
  {
237
    synchronized (_commandQueue)
238
      {
239
        while (_commandQueue.isEmpty ())
240
          {
241
            try
242
              {
243
                _commandQueue.wait ();
244
              }
245
            catch (InterruptedException ie)
246
              {
247
                /* PacketProcessor is interrupted
248
                   when shutting down */
249
                return null;
250
              }
251
          }
252
 
253
        return (JdwpPacket) _commandQueue.remove (0);
254
      }
255
  }
256
 
257
  /**
258
   * Send a packet to the debugger
259
   *
260
   * @param pkt a <code>JdwpPacket</code> to send
261
   * @throws IOException
262
   */
263
  public void sendPacket (JdwpPacket pkt)
264
    throws IOException
265
  {
266
    pkt.write (_outStream);
267
  }
268
 
269
  /**
270
   * Send an event notification to the debugger. Note that this
271
   * method will only send out one notification: all the events
272
   * are passed in a single Event.COMPOSITE packet.
273
   *
274
   * @param requests  debugger requests for events
275
   * @param events    the events to send
276
   * @param suspendPolicy  the suspend policy enforced by the VM
277
   * @throws IOException
278
   */
279
  public void sendEvents(EventRequest[] requests, Event[] events,
280
                         byte suspendPolicy)
281
    throws IOException
282
  {
283
    JdwpPacket pkt;
284
 
285
    synchronized (_bytes)
286
      {
287
        _bytes.reset ();
288
        pkt = Event.toPacket (_doStream, events, requests, suspendPolicy);
289
        pkt.setData (_bytes.toByteArray ());
290
      }
291
 
292
    sendPacket (pkt);
293
  }
294
 
295
  /**
296
   * Shutdown the connection
297
   */
298
  public void shutdown ()
299
  {
300
    if (!_shutdown)
301
      {
302
        _transport.shutdown ();
303
        _shutdown = true;
304
        interrupt ();
305
      }
306
  }
307
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.