1 // This source code is dual-licensed under the Apache License, version
2 // 2.0, and the Mozilla Public License, version 1.1.
6 //---------------------------------------------------------------------------
7 // Copyright (C) 2007-2009 LShift Ltd., Cohesive Financial
8 // Technologies LLC., and Rabbit Technologies Ltd.
10 // Licensed under the Apache License, Version 2.0 (the "License");
11 // you may not use this file except in compliance with the License.
12 // You may obtain a copy of the License at
14 // http://www.apache.org/licenses/LICENSE-2.0
16 // Unless required by applicable law or agreed to in writing, software
17 // distributed under the License is distributed on an "AS IS" BASIS,
18 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 // See the License for the specific language governing permissions and
20 // limitations under the License.
21 //---------------------------------------------------------------------------
25 //---------------------------------------------------------------------------
26 // The contents of this file are subject to the Mozilla Public License
27 // Version 1.1 (the "License"); you may not use this file except in
28 // compliance with the License. You may obtain a copy of the License at
29 // http://www.rabbitmq.com/mpl.html
31 // Software distributed under the License is distributed on an "AS IS"
32 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
33 // License for the specific language governing rights and limitations
36 // The Original Code is The RabbitMQ .NET Client.
38 // The Initial Developers of the Original Code are LShift Ltd,
39 // Cohesive Financial Technologies LLC, and Rabbit Technologies Ltd.
41 // Portions created before 22-Nov-2008 00:00:00 GMT by LShift Ltd,
42 // Cohesive Financial Technologies LLC, or Rabbit Technologies Ltd
43 // are Copyright (C) 2007-2008 LShift Ltd, Cohesive Financial
44 // Technologies LLC, and Rabbit Technologies Ltd.
46 // Portions created by LShift Ltd are Copyright (C) 2007-2009 LShift
47 // Ltd. Portions created by Cohesive Financial Technologies LLC are
48 // Copyright (C) 2007-2009 Cohesive Financial Technologies
49 // LLC. Portions created by Rabbit Technologies Ltd are Copyright
50 // (C) 2007-2009 Rabbit Technologies Ltd.
52 // All Rights Reserved.
54 // Contributor(s): ______________________________________.
56 //---------------------------------------------------------------------------
59 using RabbitMQ.Client;
60 using RabbitMQ.Client.Events;
61 using RabbitMQ.Client.Exceptions;
63 namespace RabbitMQ.Client.Impl
65 public abstract class SessionBase: ISession
67 private CommandHandler m_commandReceived;
69 private readonly object m_shutdownLock = new object();
70 private SessionShutdownEventHandler m_sessionShutdown;
71 public ShutdownEventArgs m_closeReason = null;
73 public readonly ConnectionBase m_connection;
74 public readonly int m_channelNumber;
76 public SessionBase(ConnectionBase connection, int channelNumber)
78 m_connection = connection;
79 m_channelNumber = channelNumber;
80 if (channelNumber != 0)
81 connection.ConnectionShutdown +=
82 new ConnectionShutdownEventHandler(this.OnConnectionShutdown);
85 public virtual void OnCommandReceived(Command cmd)
87 CommandHandler handler = CommandReceived;
94 public virtual void OnConnectionShutdown(IConnection conn, ShutdownEventArgs reason)
99 public virtual void OnSessionShutdown(ShutdownEventArgs reason)
101 //Console.WriteLine("Session shutdown "+ChannelNumber+": "+reason);
102 m_connection.ConnectionShutdown -=
103 new ConnectionShutdownEventHandler(this.OnConnectionShutdown);
104 SessionShutdownEventHandler handler;
105 lock (m_shutdownLock)
107 handler = m_sessionShutdown;
108 m_sessionShutdown = null;
112 handler(this, reason);
116 public override string ToString()
118 return this.GetType().Name+"#" + m_channelNumber + ":" + m_connection;
121 //---------------------------------------------------------------------------
122 // ISession implementation
124 public CommandHandler CommandReceived
126 get { return m_commandReceived; }
127 set { m_commandReceived = value; }
130 public event SessionShutdownEventHandler SessionShutdown
135 lock (m_shutdownLock)
137 if (m_closeReason == null)
139 m_sessionShutdown += value;
145 value(this, m_closeReason);
150 lock (m_shutdownLock)
152 m_sessionShutdown -= value;
157 public int ChannelNumber { get { return m_channelNumber; } }
159 IConnection ISession.Connection { get { return m_connection; } }
160 public ConnectionBase Connection { get { return m_connection; } }
162 public ShutdownEventArgs CloseReason { get { return m_closeReason; } }
164 public bool IsOpen { get { return m_closeReason == null; } }
166 public abstract void HandleFrame(Frame frame);
168 public virtual void Transmit(Command cmd)
170 lock (m_shutdownLock)
172 if (m_closeReason != null)
174 if (!m_connection.Protocol.CanSendWhileClosed(cmd))
175 throw new AlreadyClosedException(m_closeReason);
177 // We transmit *inside* the lock to avoid interleaving
178 // of frames within a channel.
179 cmd.Transmit(m_channelNumber, m_connection);
183 public void Close(ShutdownEventArgs reason)
188 public void Close(ShutdownEventArgs reason, bool notify)
190 lock (m_shutdownLock)
192 if (m_closeReason == null)
194 m_closeReason = reason;
198 OnSessionShutdown(m_closeReason);
203 // Ensure that we notify only when session is already closed
204 // If not, throw exception, since this is a serious bug in the library
205 lock (m_shutdownLock)
207 if (m_closeReason == null)
208 throw new Exception("Internal Error in Session.Close");
210 OnSessionShutdown(m_closeReason);