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