(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / Novell.Directory.Ldap / Novell.Directory.Ldap / MessageAgent.cs
blob55ec2994ad5fb631b4a2f1b36a6de2e5954318c7
1 /******************************************************************************
2 * The MIT License
3 * Copyright (c) 2003 Novell Inc. www.novell.com
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the Software), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *******************************************************************************/
24 // Novell.Directory.Ldap.MessageAgent.cs
26 // Author:
27 // Sunil Kumar (Sunilk@novell.com)
29 // (C) 2003 Novell, Inc (http://www.novell.com)
32 using System;
33 using Novell.Directory.Ldap.Utilclass;
35 namespace Novell.Directory.Ldap
38 /* package */
39 class MessageAgent
41 private void InitBlock()
43 messages = new MessageVector(5, 5);
45 /// <summary> empty and return all messages owned by this agent
46 ///
47 ///
48 /// </summary>
49 virtual internal System.Object[] MessageArray
51 /* package */
53 get
55 return messages.ObjectArray;
59 /// <summary> Get a list of message ids controlled by this agent
60 ///
61 /// </summary>
62 /// <returns> an array of integers representing the message ids
63 /// </returns>
64 virtual internal int[] MessageIDs
66 /* package */
68 get
70 int size = messages.Count;
71 int[] ids = new int[size];
72 Message info;
74 for (int i = 0; i < size; i++)
76 info = (Message) messages[i];
77 ids[i] = info.MessageID;
79 return ids;
83 /// <summary> Get the maessage agent number for debugging
84 ///
85 /// </summary>
86 /// <returns> the agent number
87 /// </returns>
88 virtual internal System.String AgentName
90 /*packge*/
92 get
94 return name;
98 /// <summary> Get a count of all messages queued</summary>
99 virtual internal int Count
101 /* package */
105 int count = 0;
106 System.Object[] msgs = messages.ToArray();
107 for (int i = 0; i < msgs.Length; i++)
109 Message m = (Message) msgs[i];
110 count += m.Count;
112 return count;
116 private MessageVector messages;
117 private int indexLastRead = 0;
118 private static System.Object nameLock; // protect agentNum
119 private static int agentNum = 0; // Debug, agent number
120 private System.String name; // String name for debug
122 /* package */
123 internal MessageAgent()
125 InitBlock();
126 // Get a unique agent id for debug
129 /// <summary> merges two message agents
130 ///
131 /// </summary>
132 /// <param name="fromAgent">the agent to be merged into this one
133 /// </param>
134 /* package */
135 internal void merge(MessageAgent fromAgent)
137 System.Object[] msgs = fromAgent.MessageArray;
138 for (int i = 0; i < msgs.Length; i++)
140 messages.Add(msgs[i]);
141 ((Message) (msgs[i])).Agent = this;
143 lock (messages)
145 if (msgs.Length > 1)
147 System.Threading.Monitor.PulseAll(messages); // wake all threads waiting for messages
149 else if (msgs.Length == 1)
151 System.Threading.Monitor.Pulse(messages); // only wake one thread
154 return ;
158 /// <summary> Wakes up any threads waiting for messages in the message agent
159 ///
160 /// </summary>
161 /* package */
162 internal void sleepersAwake(bool all)
164 lock (messages)
166 if (all)
167 System.Threading.Monitor.PulseAll(messages);
168 else
169 System.Threading.Monitor.Pulse(messages);
171 return ;
174 /// <summary> Returns true if any responses are queued for any of the agent's messages
175 ///
176 /// return false if no responses are queued, otherwise true
177 /// </summary>
178 /* package */
179 internal bool isResponseReceived()
181 int size = messages.Count;
182 int next = indexLastRead + 1;
183 Message info;
184 for (int i = 0; i < size; i++)
186 if (next == size)
188 next = 0;
190 info = (Message) messages[next];
191 if (info.hasReplies())
193 return true;
196 return false;
199 /// <summary> Returns true if any responses are queued for the specified msgId
200 ///
201 /// return false if no responses are queued, otherwise true
202 /// </summary>
203 /* package */
204 internal bool isResponseReceived(int msgId)
208 Message info = messages.findMessageById(msgId);
209 return info.hasReplies();
211 catch (System.FieldAccessException ex)
213 return false;
217 /// <summary> Abandon the request associated with MsgId
218 ///
219 /// </summary>
220 /// <param name="msgId">the message id to abandon
221 ///
222 /// </param>
223 /// <param name="cons">constraints associated with this request
224 /// </param>
225 /* package */
226 internal void Abandon(int msgId, LdapConstraints cons)
227 //, boolean informUser)
229 Message info = null;
232 // Send abandon request and remove from connection list
233 info = messages.findMessageById(msgId);
234 SupportClass.VectorRemoveElement(messages, info); // This message is now dead
235 info.Abandon(cons, null);
237 return ;
239 catch (System.FieldAccessException ex)
242 return ;
245 /// <summary> Abandon all requests on this MessageAgent</summary>
246 /* package */
247 internal void AbandonAll()
249 int size = messages.Count;
250 Message info;
252 for (int i = 0; i < size; i++)
254 info = (Message) messages[i];
255 // Message complete and no more replies, remove from id list
256 SupportClass.VectorRemoveElement(messages, info);
257 info.Abandon(null, null);
259 return ;
262 /// <summary> Indicates whether a specific operation is complete
263 ///
264 /// </summary>
265 /// <returns> true if a specific operation is complete
266 /// </returns>
267 /* package */
268 internal bool isComplete(int msgid)
272 Message info = messages.findMessageById(msgid);
273 if (!info.Complete)
275 return false;
278 catch (System.FieldAccessException ex)
280 ; // return true, if no message, it must be complete
282 return true;
285 /// <summary> Returns the Message object for a given messageID
286 ///
287 /// </summary>
288 /// <param name="msgid">the message ID.
289 /// </param>
290 /* package */
291 internal Message getMessage(int msgid)
293 return messages.findMessageById(msgid);
296 /// <summary> Send a request to the server. A Message class is created
297 /// for the specified request which causes the message to be sent.
298 /// The request is added to the list of messages being managed by
299 /// this agent.
300 ///
301 /// </summary>
302 /// <param name="conn">the connection that identifies the server.
303 ///
304 /// </param>
305 /// <param name="msg">the LdapMessage to send
306 ///
307 /// </param>
308 /// <param name="timeOut">the interval to wait for the message to complete or
309 /// <code>null</code> if infinite.
310 /// </param>
311 /// <param name="queue">the LdapMessageQueue associated with this request.
312 /// </param>
313 /* package */
314 internal void sendMessage(Connection conn, LdapMessage msg, int timeOut, LdapMessageQueue queue, BindProperties bindProps)
316 // creating a messageInfo causes the message to be sent
317 // and a timer to be started if needed.
318 Message message = new Message(msg, timeOut, conn, this, queue, bindProps);
319 messages.Add(message);
320 message.sendMessage(); // Now send message to server
321 return ;
324 /// <summary> Returns a response queued, or waits if none queued
325 ///
326 /// </summary>
327 /* package */
328 // internal System.Object getLdapMessage(System.Int32 msgId)
329 internal System.Object getLdapMessage(System.Int32 msgId)
331 return (getLdapMessage(new Integer32(msgId)));
334 internal System.Object getLdapMessage(Integer32 msgId)
336 System.Object rfcMsg;
337 // If no messages for this agent, just return null
338 if (messages.Count == 0)
340 return null;
342 if ( msgId != null)
344 // Request messages for a specific ID
347 // Get message for this ID
348 // Message info = messages.findMessageById(msgId);
349 Message info = messages.findMessageById(msgId.intValue);
350 rfcMsg = info.waitForReply(); // blocks for a response
351 if (!info.acceptsReplies() && !info.hasReplies())
353 // Message complete and no more replies, remove from id list
354 SupportClass.VectorRemoveElement(messages, info);
355 info.Abandon(null, null); // Get rid of resources
357 else
360 return rfcMsg;
362 catch (System.FieldAccessException ex)
364 // no such message id
365 return null;
368 else
370 // A msgId was NOT specified, any message will do
371 lock (messages)
373 while (true)
375 int next = indexLastRead + 1;
376 Message info;
377 for (int i = 0; i < messages.Count; i++)
379 if (next >= messages.Count)
381 next = 0;
383 info = (Message) messages[next];
384 indexLastRead = next++;
385 rfcMsg = info.Reply;
386 // Check this request is complete
387 if (!info.acceptsReplies() && !info.hasReplies())
389 // Message complete & no more replies, remove from id list
390 SupportClass.VectorRemoveElement(messages, info); // remove from list
391 info.Abandon(null, null); // Get rid of resources
392 // Start loop at next message that is now moved
393 // to the current position in the Vector.
394 i -= 1;
396 if (rfcMsg != null)
398 // We got a reply
399 return rfcMsg;
401 else
403 // We found no reply here
405 } // end for loop */
406 // Messages can be removed in this loop, we we must
407 // check if any messages left for this agent
408 if (messages.Count == 0)
410 return null;
413 // No data, wait for something to come in.
416 System.Threading.Monitor.Wait(messages);
418 catch (System.Threading.ThreadInterruptedException ex)
421 } /* end while */
422 } /* end synchronized */
426 /// <summary> Debug code to print messages in message vector</summary>
427 private void debugDisplayMessages()
429 return ;
431 static MessageAgent()
433 nameLock = new System.Object();