summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcs/src/Ice/Application.cs10
-rw-r--r--cs/src/Ice/Assert.cs34
-rw-r--r--cs/src/Ice/ConnectionFactory.cs31
-rwxr-xr-xcs/src/Ice/ConnectionI.cs55
-rwxr-xr-xcs/src/Ice/ConnectionMonitor.cs8
-rwxr-xr-xcs/src/Ice/EventHandler.cs15
-rwxr-xr-xcs/src/Ice/Ice.csproj5
-rwxr-xr-xcs/src/Ice/Instance.cs32
-rwxr-xr-xcs/src/Ice/ObjectAdapterFactory.cs12
-rwxr-xr-xcs/src/Ice/ObjectAdapterI.cs12
-rwxr-xr-xcs/src/Ice/ServantManager.cs2
-rwxr-xr-xcs/src/Ice/TcpAcceptor.cs6
-rwxr-xr-xcs/src/Ice/TcpTransceiver.cs6
-rwxr-xr-xcs/src/Ice/ThreadPool.cs6
-rwxr-xr-xcs/src/Ice/UdpTransceiver.cs6
15 files changed, 172 insertions, 68 deletions
diff --git a/cs/src/Ice/Application.cs b/cs/src/Ice/Application.cs
index dfe326967c2..425a3621ae7 100755
--- a/cs/src/Ice/Application.cs
+++ b/cs/src/Ice/Application.cs
@@ -213,7 +213,7 @@ namespace Ice
return rc;
}
-/*
+#if !__MonoCS__
//
// First-level handler
//
@@ -235,7 +235,7 @@ namespace Ice
}
return true;
}
-*/
+#endif
//
// The callbacks to be invoked from the handler.
@@ -310,8 +310,10 @@ namespace Ice
private static bool _nohup;
private delegate Boolean EventHandler(int sig);
- //private static readonly Application.EventHandler _handler
- //= new Application.EventHandler(HandlerRoutine); // First-level handler
+#if !__MonoCS__
+ private static readonly Application.EventHandler _handler
+ = new Application.EventHandler(HandlerRoutine); // First-level handler
+#endif
private delegate void Callback(int sig);
private static readonly Callback _destroyCallback = new Callback(destroyOnInterruptCallback);
diff --git a/cs/src/Ice/Assert.cs b/cs/src/Ice/Assert.cs
new file mode 100644
index 00000000000..d443c394efc
--- /dev/null
+++ b/cs/src/Ice/Assert.cs
@@ -0,0 +1,34 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2005 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+namespace IceUtil
+{
+
+ public sealed class Assert
+ {
+ //
+ // In C#, it's not safe to call *anything* from within a finalizer
+ // because the finalizer may run as part of process shutdown, and
+ // order of finalization is undefined. So, we don't run assertions
+ // once shutdown has started.
+ //
+ public static void
+ FinalizerAssert(bool b)
+ {
+ if(!b && !System.Environment.HasShutdownStarted)
+ {
+ System.Console.Error.WriteLine("Assertion failure:");
+
+ System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace(true);
+ System.Console.Error.WriteLine(st);
+ }
+ }
+ }
+
+}
diff --git a/cs/src/Ice/ConnectionFactory.cs b/cs/src/Ice/ConnectionFactory.cs
index 91714335aaa..ee23575c0c4 100644
--- a/cs/src/Ice/ConnectionFactory.cs
+++ b/cs/src/Ice/ConnectionFactory.cs
@@ -60,8 +60,12 @@ namespace IceInternal
// We want to wait until all connections are finished
// outside the thread synchronization.
//
+ // We set _connections to null rather than to a
+ // new empty list so that our finalizer does not try to invoke any
+ // methods on member objects.
+ //
connections = _connections;
- _connections = new Hashtable();
+ _connections = null;
}
//
@@ -497,15 +501,15 @@ namespace IceInternal
_pending = new Set();
}
+#if DEBUG
~OutgoingConnectionFactory()
{
-#if DEBUG
lock(this)
{
- Debug.Assert(_destroyed);
+ IceUtil.Assert.FinalizerAssert(_destroyed);
}
-#endif DEBUG
}
+#endif
private readonly Instance _instance;
private bool _destroyed;
@@ -531,7 +535,7 @@ namespace IceInternal
}
}
- public void destroy()
+ public override void destroy() // TODO: should up-call here?
{
lock(this)
{
@@ -600,6 +604,16 @@ namespace IceInternal
{
connection.waitUntilFinished();
}
+
+ //
+ // At this point we know that this factory is no longer used, so it is
+ // safe to invoke destroy() on the EventHandler base class to reclaim
+ // resources.
+ //
+ // We call this here instead of in the finalizer because a C# finalizer
+ // cannot invoke methods on other types of objects.
+ //
+ base.destroy();
}
public Endpoint endpoint()
@@ -888,10 +902,11 @@ namespace IceInternal
#if DEBUG
lock(this)
{
- Debug.Assert(_state == StateClosed);
- Debug.Assert(_acceptor == null);
+ IceUtil.Assert.FinalizerAssert(_state == StateClosed);
+ IceUtil.Assert.FinalizerAssert(_acceptor == null);
+ IceUtil.Assert.FinalizerAssert(_connections != null);
}
-#endif DEBUG
+#endif
}
private const int StateActive = 0;
diff --git a/cs/src/Ice/ConnectionI.cs b/cs/src/Ice/ConnectionI.cs
index 43e9cf748c3..6ab61c1563d 100755
--- a/cs/src/Ice/ConnectionI.cs
+++ b/cs/src/Ice/ConnectionI.cs
@@ -262,6 +262,8 @@ namespace Ice
}
}
+ cleanup();
+
return true;
}
else
@@ -356,6 +358,8 @@ namespace Ice
_incomingCache = _incomingCache.next;
}
}
+
+ cleanup();
}
public void monitor()
@@ -465,7 +469,26 @@ namespace Ice
return uncompressed;
}
-
+
+ /*
+ private class MessageInfo
+ {
+ MessageInfo(IceInternal.BasicStream stream)
+ {
+ this.stream = stream;
+ }
+
+ IceInternal.BasicStream stream;
+ bool destroyStream;
+ int invokeNum;
+ int requestId;
+ byte compress;
+ IceInternal.ServantManager servantManager;
+ ObjectAdapter adapter;
+ IceInternal.OutgoingAsync outAsync;
+ }
+ */
+
public void sendRequest(IceInternal.BasicStream os, IceInternal.Outgoing og, bool compress)
{
int requestId = 0;
@@ -576,7 +599,7 @@ namespace Ice
}
finally
{
- if(!Object.ReferenceEquals(os, stream))
+ if(stream != null && !Object.ReferenceEquals(os, stream))
{
stream.destroy();
}
@@ -1557,19 +1580,18 @@ namespace Ice
}
+#if DEBUG
~ConnectionI()
{
-#if DEBUG
lock(this)
{
- Debug.Assert(_state == StateClosed);
- Debug.Assert(_transceiver == null);
- Debug.Assert(_dispatchCount == 0);
+ IceUtil.Assert.FinalizerAssert(_state == StateClosed);
+ IceUtil.Assert.FinalizerAssert(_transceiver == null);
+ IceUtil.Assert.FinalizerAssert(_dispatchCount == 0);
+ IceUtil.Assert.FinalizerAssert(_incomingCache == null);
}
-#endif DEBUG
-
- _batchStream.destroy();
}
+#endif
private const int StateNotValidated = 0;
private const int StateActive = 1;
@@ -1869,6 +1891,21 @@ namespace Ice
_incomingCache = inc;
}
}
+
+ private void cleanup()
+ {
+ //
+ // This should be called when we know that this object is no longer used,
+ // so it is safe to reclaim resources.
+ //
+ // We do this here instead of in a finalizer because a C# finalizer
+ // cannot invoke methods on other types of objects.
+ //
+ _batchStream.destroy();
+ _batchStream = null;
+
+ base.destroy();
+ }
private IceInternal.Transceiver _transceiver;
private string _desc;
diff --git a/cs/src/Ice/ConnectionMonitor.cs b/cs/src/Ice/ConnectionMonitor.cs
index 063def16576..8b19d2af878 100755
--- a/cs/src/Ice/ConnectionMonitor.cs
+++ b/cs/src/Ice/ConnectionMonitor.cs
@@ -75,16 +75,16 @@ namespace IceInternal
_thread.Start();
}
+#if DEBUG
~ConnectionMonitor()
{
-#if DEBUG
lock(this)
{
- Debug.Assert(_instance == null);
- Debug.Assert(_connections != null);
+ IceUtil.Assert.FinalizerAssert(_instance == null);
+ IceUtil.Assert.FinalizerAssert(_connections != null);
}
-#endif DEBUG
}
+#endif
public void Run()
{
diff --git a/cs/src/Ice/EventHandler.cs b/cs/src/Ice/EventHandler.cs
index a5012caae0e..5add620a9da 100755
--- a/cs/src/Ice/EventHandler.cs
+++ b/cs/src/Ice/EventHandler.cs
@@ -57,6 +57,15 @@ namespace IceInternal
return _instance;
}
+ public virtual void destroy()
+ {
+ lock(this)
+ {
+ _stream.destroy();
+ _stream = null;
+ }
+ }
+
protected internal EventHandler(Instance instance)
{
_instance = instance;
@@ -65,8 +74,10 @@ namespace IceInternal
~EventHandler()
{
- Debug.Assert(_stream != null);
- _stream.destroy();
+ lock(this)
+ {
+ IceUtil.Assert.FinalizerAssert(_stream != null);
+ }
}
protected internal Instance _instance;
diff --git a/cs/src/Ice/Ice.csproj b/cs/src/Ice/Ice.csproj
index bc225e183e2..761a3a3f2f1 100755
--- a/cs/src/Ice/Ice.csproj
+++ b/cs/src/Ice/Ice.csproj
@@ -94,6 +94,11 @@
BuildAction = "Compile"
/>
<File
+ RelPath = "Assert.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
RelPath = "BasicInputStream.cs"
SubType = "Code"
BuildAction = "Compile"
diff --git a/cs/src/Ice/Instance.cs b/cs/src/Ice/Instance.cs
index f5095a9f0fe..b30d8062e31 100755
--- a/cs/src/Ice/Instance.cs
+++ b/cs/src/Ice/Instance.cs
@@ -440,27 +440,27 @@ namespace IceInternal
}
}
+#if DEBUG
~Instance()
{
-#if DEBUG
lock(this)
{
- Debug.Assert(_destroyed);
- Debug.Assert(_referenceFactory == null);
- Debug.Assert(_proxyFactory == null);
- Debug.Assert(_outgoingConnectionFactory == null);
- Debug.Assert(_connectionMonitor == null);
- Debug.Assert(_servantFactoryManager == null);
- Debug.Assert(_objectAdapterFactory == null);
- Debug.Assert(_clientThreadPool == null);
- Debug.Assert(_serverThreadPool == null);
- Debug.Assert(_routerManager == null);
- Debug.Assert(_locatorManager == null);
- Debug.Assert(_endpointFactoryManager == null);
- Debug.Assert(_pluginManager == null);
- }
-#endif DEBUG
+ IceUtil.Assert.FinalizerAssert(_destroyed);
+ IceUtil.Assert.FinalizerAssert(_referenceFactory == null);
+ IceUtil.Assert.FinalizerAssert(_proxyFactory == null);
+ IceUtil.Assert.FinalizerAssert(_outgoingConnectionFactory == null);
+ IceUtil.Assert.FinalizerAssert(_connectionMonitor == null);
+ IceUtil.Assert.FinalizerAssert(_servantFactoryManager == null);
+ IceUtil.Assert.FinalizerAssert(_objectAdapterFactory == null);
+ IceUtil.Assert.FinalizerAssert(_clientThreadPool == null);
+ IceUtil.Assert.FinalizerAssert(_serverThreadPool == null);
+ IceUtil.Assert.FinalizerAssert(_routerManager == null);
+ IceUtil.Assert.FinalizerAssert(_locatorManager == null);
+ IceUtil.Assert.FinalizerAssert(_endpointFactoryManager == null);
+ IceUtil.Assert.FinalizerAssert(_pluginManager == null);
+ }
}
+#endif
public void finishSetup(ref string[] args)
{
diff --git a/cs/src/Ice/ObjectAdapterFactory.cs b/cs/src/Ice/ObjectAdapterFactory.cs
index 4640cc8a7af..b3051e51772 100755
--- a/cs/src/Ice/ObjectAdapterFactory.cs
+++ b/cs/src/Ice/ObjectAdapterFactory.cs
@@ -165,18 +165,18 @@ namespace IceInternal
_waitForShutdown = false;
}
+#if DEBUG
~ObjectAdapterFactory()
{
-#if DEBUG
lock(this)
{
- Debug.Assert(_instance == null);
- Debug.Assert(_communicator == null);
- Debug.Assert(_adapters != null);
- Debug.Assert(!_waitForShutdown);
+ IceUtil.Assert.FinalizerAssert(_instance == null);
+ IceUtil.Assert.FinalizerAssert(_communicator == null);
+ IceUtil.Assert.FinalizerAssert(_adapters != null);
+ IceUtil.Assert.FinalizerAssert(!_waitForShutdown);
}
-#endif DEBUG
}
+#endif
private Instance _instance;
private Ice.Communicator _communicator;
diff --git a/cs/src/Ice/ObjectAdapterI.cs b/cs/src/Ice/ObjectAdapterI.cs
index 3eb8c024c48..2c814341805 100755
--- a/cs/src/Ice/ObjectAdapterI.cs
+++ b/cs/src/Ice/ObjectAdapterI.cs
@@ -760,12 +760,12 @@ namespace Ice
{
lock(this)
{
- Debug.Assert(_threadPool == null);
- Debug.Assert(_servantManager == null);
- Debug.Assert(_communicator == null);
- Debug.Assert(_incomingConnectionFactories != null);
- Debug.Assert(_directCount == 0);
- Debug.Assert(!_waitForDeactivate);
+ IceUtil.Assert.FinalizerAssert(_threadPool == null);
+ IceUtil.Assert.FinalizerAssert(_servantManager == null);
+ IceUtil.Assert.FinalizerAssert(_communicator == null);
+ IceUtil.Assert.FinalizerAssert(_incomingConnectionFactories != null);
+ IceUtil.Assert.FinalizerAssert(_directCount == 0);
+ IceUtil.Assert.FinalizerAssert(!_waitForDeactivate);
}
}
diff --git a/cs/src/Ice/ServantManager.cs b/cs/src/Ice/ServantManager.cs
index 3a8ef35d92c..eb73c0d6653 100755
--- a/cs/src/Ice/ServantManager.cs
+++ b/cs/src/Ice/ServantManager.cs
@@ -209,7 +209,7 @@ public sealed class ServantManager
//
//lock(this)
//{
- //Debug.Assert(_instance == null);
+ //IceUtil.Assert.FinalizerAssert(_instance == null);
//}
}
diff --git a/cs/src/Ice/TcpAcceptor.cs b/cs/src/Ice/TcpAcceptor.cs
index ebf15fa064a..1e9779f9e14 100755
--- a/cs/src/Ice/TcpAcceptor.cs
+++ b/cs/src/Ice/TcpAcceptor.cs
@@ -118,15 +118,15 @@ namespace IceInternal
}
}
+#if DEBUG
~TcpAcceptor()
{
-#if DEBUG
lock(this)
{
- Debug.Assert(_fd == null);
+ IceUtil.Assert.FinalizerAssert(_fd == null);
}
-#endif DEBUG
}
+#endif
private Instance _instance;
private TraceLevels _traceLevels;
diff --git a/cs/src/Ice/TcpTransceiver.cs b/cs/src/Ice/TcpTransceiver.cs
index 8d778cdfa48..63d88bfd5a4 100755
--- a/cs/src/Ice/TcpTransceiver.cs
+++ b/cs/src/Ice/TcpTransceiver.cs
@@ -280,15 +280,15 @@ namespace IceInternal
_desc = Network.fdToString(_fd);
}
+#if DEBUG
~TcpTransceiver()
{
-#if DEBUG
lock(this)
{
- Debug.Assert(_fd == null);
+ IceUtil.Assert.FinalizerAssert(_fd == null);
}
-#endif DEBUG
}
+#endif
private Socket _fd;
private TraceLevels _traceLevels;
diff --git a/cs/src/Ice/ThreadPool.cs b/cs/src/Ice/ThreadPool.cs
index aaec1a1aa05..f7bacced0a2 100755
--- a/cs/src/Ice/ThreadPool.cs
+++ b/cs/src/Ice/ThreadPool.cs
@@ -108,14 +108,13 @@ namespace IceInternal
}
}
+#if DEBUG
~ThreadPool()
{
-#if DEBUG
lock(this)
{
- Debug.Assert(_destroyed);
+ IceUtil.Assert.FinalizerAssert(_destroyed);
}
-#endif DEBUG
try
{
@@ -126,6 +125,7 @@ namespace IceInternal
{
}
}
+#endif
public void destroy()
{
diff --git a/cs/src/Ice/UdpTransceiver.cs b/cs/src/Ice/UdpTransceiver.cs
index 79e47209dce..8503c4b6cb6 100755
--- a/cs/src/Ice/UdpTransceiver.cs
+++ b/cs/src/Ice/UdpTransceiver.cs
@@ -440,15 +440,15 @@ namespace IceInternal
}
}
+#if DEBUG
~UdpTransceiver()
{
-#if DEBUG
lock(this)
{
- Debug.Assert(_fd == null);
+ IceUtil.Assert.FinalizerAssert(_fd == null);
}
-#endif DEBUG
}
+#endif
private TraceLevels _traceLevels;
private Ice.Logger _logger;