1 #if FALSE 2 using System; 3 using System.Collections; 4 using System.Collections.Generic; 5 using System.IO; 6 using System.Threading; 7 using Mono.Debugger; 8 using Mono.Debugger.Requests; 9 using Mono.Debugger.Events; 10 11 namespace Mono.Debugger.Soft 12 { 13 class EventQueueImpl : MirrorImpl, EventQueue 14 { 15 bool disconnected; 16 Dictionary<int, byte[]> reply_packets; 17 Thread receiver_thread; 18 Queue queue; 19 object queue_monitor; 20 object reply_packets_monitor; 21 EventQueueImpl(VirtualMachineImpl vm)22 public EventQueueImpl (VirtualMachineImpl vm) : base (vm) { 23 reply_packets = new Dictionary<int, byte[]> (); 24 reply_packets_monitor = new Object (); 25 26 queue = new Queue (); 27 queue_monitor = new Object (); 28 receiver_thread = new Thread (new ThreadStart (receiver_thread_main)); 29 receiver_thread.Start (); 30 } 31 Remove()32 public EventSet Remove () { 33 if (disconnected) 34 // FIXME: VMDisconnectedException 35 throw new IOException (); 36 37 lock (queue_monitor) { 38 if (queue.Count == 0) 39 Monitor.Wait (queue_monitor); 40 return (EventSet)queue.Dequeue (); 41 } 42 } 43 Remove(int timeout)44 public EventSet Remove (int timeout) { 45 throw new NotImplementedException (); 46 } 47 DecodeEventInfo(WireProtocol.EventInfo info)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)); 61 } else { 62 throw new NotImplementedException (); 63 } 64 } 65 FindRequest(int requestId)66 EventRequest FindRequest (int requestId) { 67 if (requestId == 0) 68 return null; 69 else 70 return ((EventRequestManagerImpl)vm.EventRequestManager).FindRequest (requestId); 71 } 72 73 // Wait for the reply for a command packet WaitForReply(int packetId)74 public byte[] WaitForReply (int packetId) { 75 while (true) { 76 lock (reply_packets_monitor) { 77 if (reply_packets.ContainsKey (packetId)) { 78 byte[] reply = reply_packets [packetId]; 79 reply_packets.Remove (packetId); 80 return reply; 81 } else { 82 Monitor.Wait (reply_packets_monitor); 83 } 84 } 85 } 86 } 87 add_event_set(EventSet set)88 void add_event_set (EventSet set) { 89 lock (queue_monitor) { 90 queue.Enqueue (set); 91 Monitor.Pulse (queue_monitor); 92 } 93 } 94 receiver_thread_main()95 void receiver_thread_main () { 96 97 Connection conn = vm.Connection; 98 99 while (true) { 100 byte[] packet = conn.ReadPacket (); 101 102 if (packet.Length == 0) { 103 disconnected = true; 104 105 VMDisconnectEventImpl ev = new VMDisconnectEventImpl (vm, null); 106 add_event_set (new EventSetImpl (vm, new Event [] { ev }, SuspendPolicy.SuspendNone)); 107 break; 108 } 109 110 if (WireProtocol.IsReplyPacket (packet)) { 111 /* Reply packet */ 112 int id = WireProtocol.GetPacketId (packet); 113 lock (reply_packets_monitor) { 114 reply_packets [id] = packet; 115 Monitor.PulseAll (reply_packets_monitor); 116 } 117 } else { 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]); 124 } 125 126 add_event_set (new EventSetImpl (vm, events, p.suspendPolicy)); 127 } 128 } 129 } 130 } 131 } 132 } 133 #endif 134