* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / FirebirdSql.Data.Firebird / FirebirdSql.Data.Gds / GdsEventManager.cs
1 /*
2  *      Firebird ADO.NET Data provider for .NET and Mono 
3  * 
4  *         The contents of this file are subject to the Initial 
5  *         Developer's Public License Version 1.0 (the "License"); 
6  *         you may not use this file except in compliance with the 
7  *         License. You may obtain a copy of the License at 
8  *         http://www.firebirdsql.org/index.php?op=doc&id=idpl
9  *
10  *         Software distributed under the License is distributed on 
11  *         an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either 
12  *         express or implied. See the License for the specific 
13  *         language governing rights and limitations under the License.
14  * 
15  *      Copyright (c) 2002, 2005 Carlos Guzman Alvarez
16  *      All Rights Reserved.
17  */
18
19 using System;
20 using System.Collections;
21 using System.IO;
22 using System.Threading;
23
24 using FirebirdSql.Data.Common;
25
26 namespace FirebirdSql.Data.Gds
27 {
28         internal class GdsEventManager
29         {
30                 #region Fields
31
32                 private GdsConnection   connection;
33                 private Thread                  thread;
34                 private Hashtable               events;
35                 private int                             handle;
36
37                 #endregion
38
39                 #region Properties
40
41                 public Hashtable EventList
42                 {
43                         get { return this.events; }
44                 }
45
46                 #endregion
47
48                 #region Constructors
49
50                 public GdsEventManager(int handle, string ipAddress, int portNumber)
51                 {
52                         this.events = new Hashtable();
53                         this.events = Hashtable.Synchronized(this.events);
54                         this.handle = handle;
55
56                         // Initialize the connection
57                         if (this.connection == null)
58                         {
59                                 this.connection = new GdsConnection();
60                                 this.connection.Connect(ipAddress, portNumber);
61                         }
62                 }
63
64                 #endregion
65
66                 #region Methods
67
68                 public void QueueEvents(RemoteEvent remoteEvent)
69                 {
70                         lock (this)
71                         {
72                                 lock (this.events.SyncRoot)
73                                 {
74                                         if (!this.events.ContainsKey(remoteEvent.LocalId))
75                                         {
76                                                 this.events.Add(remoteEvent.LocalId, remoteEvent);
77                                         }
78                                 }
79
80 #if     (!NETCF)
81                                 if (this.thread == null ||
82                                         (this.thread.ThreadState != ThreadState.Running && this.thread.ThreadState != ThreadState.Background))
83 #else
84                                 if (this.thread == null)
85 #endif
86                                 {
87                                         this.thread = new Thread(new ThreadStart(ThreadHandler));
88                                         this.thread.Start();
89                                         this.thread.IsBackground = true;
90                                 }
91                         }
92                 }
93
94                 public void CancelEvents(RemoteEvent remoteEvent)
95                 {
96                         lock (this.events.SyncRoot)
97                         {
98                                 this.events.Remove(remoteEvent.LocalId);
99                         }
100                 }
101
102                 public void Close()
103                 {
104                         lock (this)
105                         {
106                                 if (this.connection != null)
107                                 {
108                                         this.connection.Disconnect();
109                                 }
110
111                                 if (this.thread != null)
112                                 {
113                                         this.thread.Abort();
114                                         this.thread.Join();
115
116                                         this.thread = null;
117                                 }
118                         }
119                 }
120
121                 #endregion
122
123                 #region Private Methods
124
125                 private void ThreadHandler()
126                 {
127                         int             operation = -1;
128                         int             dbHandle = 0;
129                         int             eventId = 0;
130                         byte[]  buffer  = null;
131                         byte[]  ast             = null;
132
133                         while (this.events.Count > 0)
134                         {
135                                 try
136                                 {
137                                         operation = this.connection.NextOperation();
138
139                                         switch (operation)
140                                         {
141                                                 case IscCodes.op_response:
142                                                         this.connection.ReadGenericResponse();
143                                                         break;
144
145                                                 case IscCodes.op_exit:
146                                                 case IscCodes.op_disconnect:
147                                                         this.connection.Disconnect();
148                                                         return;
149
150                                                 case IscCodes.op_event:
151                                                         dbHandle        = this.connection.Receive.ReadInt32();
152                                                         buffer          = this.connection.Receive.ReadBuffer();
153                                                         ast                     = this.connection.Receive.ReadBytes(8);
154                                                         eventId         = this.connection.Receive.ReadInt32();
155
156                                                         if (this.events.ContainsKey(eventId))
157                                                         {
158                                                                 RemoteEvent currentEvent = (RemoteEvent)this.events[eventId];
159
160                                                                 lock (this.events.SyncRoot)
161                                                                 {
162                                                                         // Remove event from the list
163                                                                         this.events.Remove(eventId);
164
165                                                                         // Notify new event     counts
166                                                                         currentEvent.EventCounts(buffer);
167
168                                                                         if (this.events.Count == 0)
169                                                                         {
170                                                                                 return;
171                                                                         }
172                                                                 }
173                                                         }
174                                                         break;
175                                         }
176                                 }
177                                 catch (ThreadAbortException)
178                                 {
179                                         return;
180                                 }
181                                 catch (Exception)
182                                 {
183                                         return;
184                                 }
185                         }
186                 }
187
188                 #endregion
189         }
190 }