Skip to content

Commit 17fb2bb

Browse files
author
Matthias Radestock
committed
merge bug20349 into v1_5
2 parents fbdd632 + 6f35041 commit 17fb2bb

File tree

8 files changed

+50
-7
lines changed

8 files changed

+50
-7
lines changed

src/client/impl/AbstractProtocolBase.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ public abstract void CreateChannelClose(ushort reasonCode,
8989
out Command request,
9090
out int replyClassId,
9191
out int replyMethodId);
92+
93+
///<summary>Used in the quiescing session to determine if the command
94+
///is allowed to be sent.</summary>
95+
public abstract bool CanSendWhileClosed(Command cmd);
9296

9397
public AmqpVersion Version {
9498
get {

src/client/impl/ConnectionBase.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,6 @@ void IDisposable.Dispose()
348348
if (entry.Exception != null)
349349
throw entry.Exception;
350350
}
351-
352351
throw new OperationInterruptedException(null);
353352
}
354353
}

src/client/impl/ISession.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,13 @@ public interface ISession {
6969
event SessionShutdownEventHandler SessionShutdown;
7070

7171
int ChannelNumber { get; }
72-
IConnection Connection { get; }
73-
ShutdownEventArgs CloseReason { get; }
72+
IConnection Connection { get; }
73+
ShutdownEventArgs CloseReason { get; }
7474
bool IsOpen { get; }
7575
void HandleFrame(Frame frame);
7676
void Transmit(Command cmd);
7777
void Close(ShutdownEventArgs reason);
78+
void Close(ShutdownEventArgs reason, bool notify);
79+
void Notify();
7880
}
7981
}

src/client/impl/ModelBase.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -467,8 +467,13 @@ public void HandleChannelClose(ushort replyCode,
467467
replyText,
468468
classId,
469469
methodId));
470-
FinishClose();
471-
_Private_ChannelCloseOk();
470+
471+
m_session.Close(m_closeReason, false);
472+
try {
473+
_Private_ChannelCloseOk();
474+
} finally {
475+
m_session.Notify();
476+
}
472477
}
473478

474479
public void FinishClose()

src/client/impl/SessionBase.cs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,8 @@ public virtual void Transmit(Command cmd)
171171
{
172172
if (m_closeReason != null)
173173
{
174-
throw new AlreadyClosedException(m_closeReason);
174+
if (!m_connection.Protocol.CanSendWhileClosed(cmd))
175+
throw new AlreadyClosedException(m_closeReason);
175176
}
176177
// We transmit *inside* the lock to avoid interleaving
177178
// of frames within a channel.
@@ -180,6 +181,11 @@ public virtual void Transmit(Command cmd)
180181
}
181182

182183
public void Close(ShutdownEventArgs reason)
184+
{
185+
Close(reason, true);
186+
}
187+
188+
public void Close(ShutdownEventArgs reason, bool notify)
183189
{
184190
lock (m_shutdownLock)
185191
{
@@ -188,7 +194,19 @@ public void Close(ShutdownEventArgs reason)
188194
m_closeReason = reason;
189195
}
190196
}
191-
197+
if (notify)
198+
OnSessionShutdown(m_closeReason);
199+
}
200+
201+
public void Notify()
202+
{
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)
206+
{
207+
if (m_closeReason == null)
208+
throw new Exception("Internal Error in Session.Close");
209+
}
192210
OnSessionShutdown(m_closeReason);
193211
}
194212
}

src/client/impl/v0_8/ProtocolBase.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,5 +101,10 @@ public override void CreateChannelClose(ushort reasonCode,
101101
replyClassId = RabbitMQ.Client.Framing.Impl.v0_8.ChannelCloseOk.ClassId;
102102
replyMethodId = RabbitMQ.Client.Framing.Impl.v0_8.ChannelCloseOk.MethodId;
103103
}
104+
105+
public override bool CanSendWhileClosed(Command cmd)
106+
{
107+
return cmd.m_method is RabbitMQ.Client.Framing.Impl.v0_8.ChannelCloseOk;
108+
}
104109
}
105110
}

src/client/impl/v0_8qpid/ProtocolBase.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,5 +101,10 @@ public override void CreateChannelClose(ushort reasonCode,
101101
replyClassId = RabbitMQ.Client.Framing.Impl.v0_8qpid.ChannelCloseOk.ClassId;
102102
replyMethodId = RabbitMQ.Client.Framing.Impl.v0_8qpid.ChannelCloseOk.MethodId;
103103
}
104+
105+
public override bool CanSendWhileClosed(Command cmd)
106+
{
107+
return cmd.m_method is RabbitMQ.Client.Framing.Impl.v0_8qpid.ChannelCloseOk;
108+
}
104109
}
105110
}

src/client/impl/v0_9/ProtocolBase.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,5 +101,10 @@ public override void CreateChannelClose(ushort reasonCode,
101101
replyClassId = RabbitMQ.Client.Framing.Impl.v0_9.ChannelCloseOk.ClassId;
102102
replyMethodId = RabbitMQ.Client.Framing.Impl.v0_9.ChannelCloseOk.MethodId;
103103
}
104+
105+
public override bool CanSendWhileClosed(Command cmd)
106+
{
107+
return cmd.m_method is RabbitMQ.Client.Framing.Impl.v0_9.ChannelCloseOk;
108+
}
104109
}
105110
}

0 commit comments

Comments
 (0)