3 using System.Collections;
4 using System.Collections.Generic;
6 using System.Threading;
8 using Mono.Debugger.Requests;
9 using Mono.Debugger.Events;
11 namespace Mono.Debugger.Soft
13 class EventQueueImpl : MirrorImpl, EventQueue
16 Dictionary<int, byte[]> reply_packets;
17 Thread receiver_thread;
20 object reply_packets_monitor;
22 public EventQueueImpl (VirtualMachineImpl vm) : base (vm) {
23 reply_packets = new Dictionary<int, byte[]> ();
24 reply_packets_monitor = new Object ();
27 queue_monitor = new Object ();
28 receiver_thread = new Thread (new ThreadStart (receiver_thread_main));
29 receiver_thread.Start ();
32 public EventSet Remove () {
34 // FIXME: VMDisconnectedException
35 throw new IOException ();
37 lock (queue_monitor) {
39 Monitor.Wait (queue_monitor);
40 return (EventSet)queue.Dequeue ();
44 public EventSet Remove (int timeout) {
45 throw new NotImplementedException ();
48 Event DecodeEventInfo (WireProtocol.EventInfo info) {
49 EventRequest req = FindRequest (info.requestId);
50 if (info.eventKind == WireProtocol.EVENT_VM_START) {
51 WireProtocol.VMStartEventInfo einfo = (WireProtocol.VMStartEventInfo)info;
52 return new VMStartEventImpl (vm, req, new ThreadReferenceImpl (vm, einfo.thread), new AppDomainMirrorImpl (vm, einfo.domain));
53 } else if (info.eventKind == WireProtocol.EVENT_VM_DEATH) {
54 return new VMDeathEventImpl (vm, req);
55 } else if (info.eventKind == WireProtocol.EVENT_THREAD_START) {
56 WireProtocol.ThreadStartEventInfo einfo = (WireProtocol.ThreadStartEventInfo)info;
57 return new ThreadStartEventImpl (vm, req, new ThreadReferenceImpl (vm, einfo.thread));
58 } else if (info.eventKind == WireProtocol.EVENT_THREAD_DEATH) {
59 WireProtocol.ThreadDeathEventInfo einfo = (WireProtocol.ThreadDeathEventInfo)info;
60 return new ThreadDeathEventImpl (vm, req, new ThreadReferenceImpl (vm, einfo.thread));
62 throw new NotImplementedException ();
66 EventRequest FindRequest (int requestId) {
70 return ((EventRequestManagerImpl)vm.EventRequestManager).FindRequest (requestId);
73 // Wait for the reply for a command packet
74 public byte[] WaitForReply (int packetId) {
76 lock (reply_packets_monitor) {
77 if (reply_packets.ContainsKey (packetId)) {
78 byte[] reply = reply_packets [packetId];
79 reply_packets.Remove (packetId);
82 Monitor.Wait (reply_packets_monitor);
88 void add_event_set (EventSet set) {
89 lock (queue_monitor) {
91 Monitor.Pulse (queue_monitor);
95 void receiver_thread_main () {
97 Connection conn = vm.Connection;
100 byte[] packet = conn.ReadPacket ();
102 if (packet.Length == 0) {
105 VMDisconnectEventImpl ev = new VMDisconnectEventImpl (vm, null);
106 add_event_set (new EventSetImpl (vm, new Event [] { ev }, SuspendPolicy.SuspendNone));
110 if (WireProtocol.IsReplyPacket (packet)) {
112 int id = WireProtocol.GetPacketId (packet);
113 lock (reply_packets_monitor) {
114 reply_packets [id] = packet;
115 Monitor.PulseAll (reply_packets_monitor);
118 WireProtocol.Packet decoded = WireProtocol.DecodePacket (packet);
119 if (decoded is WireProtocol.Event.CompositePacket) {
120 WireProtocol.Event.CompositePacket p = (WireProtocol.Event.CompositePacket)decoded;
121 Event[] events = new Event [p.events.Length];
122 for (int i = 0; i < p.events.Length; ++i) {
123 events [i] = DecodeEventInfo (p.events [i]);
126 add_event_set (new EventSetImpl (vm, events, p.suspendPolicy));