/// <summary> /// Constructs an instance of the SMAcceptConnectionClosure class. /// </summary> /// <param name="iTransportContext">The transport context.</param> /// <param name="sharedMemoryConnection">The server's connection.</param> /// <param name="sharedMemoryConnectionManager">The connection manager.</param> /// <param name="shareName">The name of the share.</param> public SMAcceptConnectionClosure(ITransportContext iTransportContext, SharedMemoryConnection sharedMemoryConnection, SharedMemoryConnectionManager sharedMemoryConnectionManager, string shareName) { this.ITransportContext = iTransportContext; this.SharedMemoryConnection = sharedMemoryConnection; this.SharedMemoryConnectionManager = sharedMemoryConnectionManager; this.ShareName = shareName; }
/// <summary> /// Closes the specified connections to the remote host and releases acquired resources. /// </summary> /// <param name="hostInformation">The host information.</param> /// <param name="genuineConnectionType">A value indicating what kind of connections will be affected by this operation.</param> /// <param name="reason">The reason of resource releasing.</param> public override void ReleaseConnections(HostInformation hostInformation, GenuineConnectionType genuineConnectionType, Exception reason) { BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; reason = GenuineExceptions.Get_Channel_ConnectionShutDown(reason); // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0) { binaryLogWriter.WriteEvent(LogCategory.Connection, "SharedMemoryConnectionManager.ReleaseConnections", LogMessageType.ReleaseConnections, reason, null, hostInformation, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, Enum.Format(typeof(GenuineConnectionType), genuineConnectionType, "g"), null, null, null, "Connections \"{0}\" will be terminated.", Enum.Format(typeof(GenuineConnectionType), genuineConnectionType, "g"), null); } if (hostInformation == null) { this.InternalDispose(reason); return; } SharedMemoryConnection sharedMemoryConnection = null; if (hostInformation.Url != null) { sharedMemoryConnection = this._persistent[hostInformation.Url] as SharedMemoryConnection; } if (sharedMemoryConnection != null) { this.ConnectionFailed(reason, sharedMemoryConnection); } sharedMemoryConnection = null; if (hostInformation.Uri != null) { sharedMemoryConnection = this._persistent[hostInformation.Uri] as SharedMemoryConnection; } if (sharedMemoryConnection != null) { this.ConnectionFailed(reason, sharedMemoryConnection); } }
/// <summary> /// Sends the message through the specified connection. /// </summary> /// <param name="message">The message.</param> /// <param name="sharedMemoryConnection">The connection.</param> private void SendSync(Message message, SharedMemoryConnection sharedMemoryConnection) { BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; try { // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 ) { binaryLogWriter.WriteEvent(LogCategory.Connection, "SharedMemoryConnectionManager.SendSync", LogMessageType.MessageIsSentSynchronously, null, message, sharedMemoryConnection.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, sharedMemoryConnection.ConnectionLevelSecurity, sharedMemoryConnection.ConnectionLevelSecurity == null ? null : sharedMemoryConnection.ConnectionLevelSecurity.Name, sharedMemoryConnection.DbgConnectionId, 0, 0, 0, null, null, null, null, "Message is sent synchronously through the Shared Memory connection."); } // now that we have the connection, obtain the write access int sendTimeout = GenuineUtility.GetTimeout(this._sendTimeoutSpan); if (GenuineUtility.IsTimeoutExpired(message.FinishTime, sendTimeout)) sendTimeout = message.FinishTime; try { if (! Monitor.TryEnter(sharedMemoryConnection.WriteAccess, GenuineUtility.GetMillisecondsLeft(sendTimeout)) ) throw GenuineExceptions.Get_Send_Timeout(); } catch { throw GenuineExceptions.Get_Send_Timeout(); } // the write access was obtained, send the message try { sharedMemoryConnection.LowLevel_SendSync(message.SerializedContent, sendTimeout); } catch(Exception ex) { this.ConnectionFailed(ex, sharedMemoryConnection); throw; } finally { Monitor.Exit(sharedMemoryConnection.WriteAccess); } message.Dispose(); } catch (Exception ex) { // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 ) { binaryLogWriter.WriteEvent(LogCategory.Connection, "SharedMemoryConnectionManager.SendSync", LogMessageType.MessageIsSentSynchronously, ex, message, sharedMemoryConnection.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, sharedMemoryConnection.DbgConnectionId, 0, 0, 0, null, null, null, null, "The message cannot be delivered."); } throw; } finally { message.Dispose(); } }
/// <summary> /// Opens a connection to the host specified by the url. /// </summary> /// <param name="remote">The HostInformation of the Remote Host.</param> /// <param name="localUri">The uri of the local host.</param> /// <param name="remoteUri">The uri of the remote host.</param> /// <param name="remoteHostUniqueIdentifier">The unique identifier of the HostInformation used by the remote host.</param> /// <returns>The established connection.</returns> private SharedMemoryConnection LowLevel_OpenConnection(HostInformation remote, string localUri, out string remoteUri, out int remoteHostUniqueIdentifier) { using (new ReaderAutoLocker(this._disposeLock)) { if (this._disposed) throw OperationException.WrapException(this._disposeReason); } remoteUri = null; Stream inputStream = null; Stream outputStream = null; string url = remote.Url; // the maximum time during which the connection must be established int timeout = GenuineUtility.GetTimeout((TimeSpan) this.ITransportContext.IParameterProvider[GenuineParameter.ConnectTimeout]); IParameterProvider parameters = this.ITransportContext.IParameterProvider; string mutexName = GenuineSharedMemoryChannel.ConstructSharedObjectName( "MUTEX" + url, parameters); string clientConnected = GenuineSharedMemoryChannel.ConstructSharedObjectName( "CC" + url, parameters); string clientAccepted = GenuineSharedMemoryChannel.ConstructSharedObjectName( "CA" + url, parameters); // open the server share SharedMemoryConnection serverSharedMemoryConnection = new SharedMemoryConnection(this.ITransportContext, url, false, false); // LOG: BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 ) { binaryLogWriter.WriteConnectionParameterEvent(LogCategory.Connection, "SharedMemoryConnectionManager.LowLevel_OpenConnection", LogMessageType.ConnectionParameters, null, remote, this.ITransportContext.IParameterProvider, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, serverSharedMemoryConnection.DbgConnectionId, "A Shared Memory connection is being established."); } // and create the local share string shareName = "gshmem://" + Guid.NewGuid().ToString("N"); SharedMemoryConnection sharedMemoryConnection = new SharedMemoryConnection(this.ITransportContext, shareName, true, true); BinaryWriter connectionInformation = MessageCoder.SerializeConnectionHeader(MessageCoder.PROTOCOL_VERSION, GenuineConnectionType.Persistent, "Default"); connectionInformation.Write(shareName); // let the server know that a client's share is ready Mutex mutex = null; try { mutex = WindowsAPI.OpenMutex(mutexName); NamedEvent _clientConnected = NamedEvent.OpenNamedEvent(clientConnected); NamedEvent _clientAccepted = NamedEvent.OpenNamedEvent(clientAccepted); if (! GenuineUtility.WaitOne(mutex, GenuineUtility.GetMillisecondsLeft(timeout)) ) throw GenuineExceptions.Get_Connect_CanNotConnectToRemoteHost(url, "Can not acquire the lock for the global mutex."); // wait until server accepts this client _clientAccepted.ManualResetEvent.Reset(); _clientConnected.ManualResetEvent.Set(); // copy client's name serverSharedMemoryConnection.LowLevel_SendSync(connectionInformation.BaseStream, timeout); if (! GenuineUtility.WaitOne(_clientAccepted.ManualResetEvent, GenuineUtility.GetMillisecondsLeft(timeout)) ) throw GenuineExceptions.Get_Connect_CanNotConnectToRemoteHost(url, "Remote server did not accept a request within the specified time span."); } finally { if (mutex != null) { try { mutex.ReleaseMutex(); } catch { } try { mutex.Close(); } catch { } } } // get the connection-level Security Session string connectionLevelSSName = this.ITransportContext.IParameterProvider[GenuineParameter.SecuritySessionForPersistentConnections] as string; SecuritySession securitySession = null; if (connectionLevelSSName != null) securitySession = this.ITransportContext.IKeyStore.GetKey(connectionLevelSSName).CreateSecuritySession(connectionLevelSSName, null); // establish it if (securitySession != null && ! securitySession.IsEstablished) { bool firstPass = true; for ( ; ; ) { inputStream = Stream.Null; try { // prepare streams if (! firstPass) inputStream = sharedMemoryConnection.LowLevel_ReadSync(timeout); else firstPass = false; outputStream = securitySession.EstablishSession(inputStream, true); if (outputStream == null) break; // send a packet to the remote host sharedMemoryConnection.LowLevel_SendSync(outputStream, timeout); if (securitySession.IsEstablished) break; } finally { if (inputStream != null) inputStream.Close(); if (outputStream != null) outputStream.Close(); } } } sharedMemoryConnection.ConnectionLevelSecurity = securitySession; // now send connection info through the established connection using (GenuineChunkedStream serializedLocalInfo = new GenuineChunkedStream(false)) { // serialize local info BinaryWriter binaryWriter = new BinaryWriter(serializedLocalInfo); binaryWriter.Write((string) localUri); binaryWriter.Write((int) remote.LocalHostUniqueIdentifier); // and send it sharedMemoryConnection.LowLevel_SendSync(serializedLocalInfo, timeout); // read remote info using (Stream remoteUriStream = sharedMemoryConnection.LowLevel_ReadSync(timeout)) { BinaryReader binaryReader = new BinaryReader(remoteUriStream); remoteUri = binaryReader.ReadString(); remoteHostUniqueIdentifier = binaryReader.ReadInt32(); } } sharedMemoryConnection.Remote = remote; sharedMemoryConnection.Remote.UpdateUri(remoteUri, remoteHostUniqueIdentifier); sharedMemoryConnection.Remote.GenuinePersistentConnectionState = GenuinePersistentConnectionState.Opened; // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.HostInformation] > 0 ) { binaryLogWriter.WriteHostInformationEvent("SharedMemoryConnectionManager.LowLevel_OpenConnection", LogMessageType.HostInformationCreated, null, remote, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, sharedMemoryConnection.DbgConnectionId, "HostInformation is ready for actions."); } // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 ) { binaryLogWriter.WriteEvent(LogCategory.Connection, "SharedMemoryConnectionManager.LowLevel_OpenConnection", LogMessageType.ConnectionEstablished, null, null, remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, securitySession, connectionLevelSSName, sharedMemoryConnection.DbgConnectionId, (int) GenuineConnectionType.Persistent, 0, 0, this.GetType().Name, null, null, null, "The connection to the remote host is established."); } return sharedMemoryConnection; }
/// <summary> /// Accepts an incoming connection. /// </summary> /// <param name="url">The name of the share.</param> /// <param name="localUri">URI of the local host.</param> /// <param name="protocolVersion">The version of the protocol supported by the remote host.</param> /// <param name="remoteUri">Uri of the remote host.</param> /// <param name="remoteHostUniqueIdentifier">The unique identifier of the HostInformation used by the remote host.</param> /// <returns>The established connection.</returns> private SharedMemoryConnection LowLevel_AcceptConnection_1(string url, string localUri, byte protocolVersion, out string remoteUri, out int remoteHostUniqueIdentifier) { BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; using (new ReaderAutoLocker(this._disposeLock)) { if (this._disposed) throw OperationException.WrapException(this._disposeReason); } remoteUri = null; Stream inputStream = null; Stream outputStream = null; remoteHostUniqueIdentifier = 0; // the maximum time during which the connection must be established int timeout = GenuineUtility.GetTimeout((TimeSpan) this.ITransportContext.IParameterProvider[GenuineParameter.ConnectTimeout]); // open the client's share SharedMemoryConnection sharedMemoryConnection = new SharedMemoryConnection(this.ITransportContext, url, false, true); // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 ) { binaryLogWriter.WriteConnectionParameterEvent(LogCategory.Connection, "SharedMemoryConnectionManager.LowLevel_AcceptConnection", LogMessageType.ConnectionParameters, null, null, this.ITransportContext.IParameterProvider, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, sharedMemoryConnection.DbgConnectionId, "The connection is being established to \"{0}\".", url); } // get the connection-level Security Session string connectionLevelSSName = this.ITransportContext.IParameterProvider[GenuineParameter.SecuritySessionForPersistentConnections] as string; SecuritySession securitySession = null; if (connectionLevelSSName != null) securitySession = this.ITransportContext.IKeyStore.GetKey(connectionLevelSSName).CreateSecuritySession(connectionLevelSSName, null); // establish it if (securitySession != null && ! securitySession.IsEstablished) { for ( ; ; ) { inputStream = Stream.Null; try { // prepare streams inputStream = sharedMemoryConnection.LowLevel_ReadSync(timeout); outputStream = securitySession.EstablishSession(inputStream, true); if (outputStream == null) break; // send a packet to the remote host sharedMemoryConnection.LowLevel_SendSync(outputStream, timeout); if (securitySession.IsEstablished) break; } finally { if (inputStream != null) inputStream.Close(); if (outputStream != null) outputStream.Close(); } } } sharedMemoryConnection.ConnectionLevelSecurity = securitySession; HostInformation remote = null; // read remote info using (Stream remoteUriStream = sharedMemoryConnection.LowLevel_ReadSync(timeout)) { BinaryReader binaryReader = new BinaryReader(remoteUriStream); remoteUri = binaryReader.ReadString(); remote = this.ITransportContext.KnownHosts[remoteUri]; if (protocolVersion > 0) remoteHostUniqueIdentifier = binaryReader.ReadInt32(); } // now send connection info through the established connection using (GenuineChunkedStream serializedLocalInfo = new GenuineChunkedStream(false)) { // serialize local info BinaryWriter binaryWriter = new BinaryWriter(serializedLocalInfo); binaryWriter.Write((string) localUri); if (protocolVersion > 0) binaryWriter.Write((int) remote.LocalHostUniqueIdentifier); // and send it sharedMemoryConnection.LowLevel_SendSync(serializedLocalInfo, timeout); } // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 ) { binaryLogWriter.WriteEvent(LogCategory.Connection, "SharedMemoryConnectionManager.LowLevel_AcceptConnection_1", LogMessageType.ConnectionEstablished, null, null, remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, securitySession, connectionLevelSSName, sharedMemoryConnection.DbgConnectionId, (int) GenuineConnectionType.Persistent, 0, 0, this.GetType().Name, null, null, null, "The connection to the remote host has been established."); } return sharedMemoryConnection; }
/// <summary> /// Releases all resources related to the specified connection. /// </summary> /// <param name="exception">The reason.</param> /// <param name="sharedMemoryConnection">The connection.</param> private void ConnectionFailed(Exception exception, SharedMemoryConnection sharedMemoryConnection) { BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; try { sharedMemoryConnection.IsValid = false; // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 ) { binaryLogWriter.WriteEvent(LogCategory.Connection, "SharedMemoryConnectionManager.ConnectionFailed", LogMessageType.ConnectionFailed, exception, null, sharedMemoryConnection.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, sharedMemoryConnection.DbgConnectionId, 0, 0, 0, null, null, null, null, "Connection has failed."); } // unregister the connection if (sharedMemoryConnection.Remote.GenuinePersistentConnectionState == GenuinePersistentConnectionState.Accepted) this._persistent.Remove(sharedMemoryConnection.Remote.Uri); else this._persistent.Remove(sharedMemoryConnection.Remote.Url); // release all resources this.ITransportContext.KnownHosts.ReleaseHostResources(sharedMemoryConnection.Remote, exception); sharedMemoryConnection.ReleaseUnmanagedResources(); sharedMemoryConnection.SignalState(GenuineEventType.GeneralConnectionClosed, exception, null); } catch(Exception ex) { // LOG: if ( binaryLogWriter != null) { binaryLogWriter.WriteImplementationWarningEvent("SharedMemoryConnectionManager.ConnectionFailed", LogMessageType.CriticalError, ex, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, "Unexpected exception inside the SharedMemoryClientConnectionManager.ConnectionFailed method. Most likely, something must be fixed."); } } }
/// <summary> /// Initiates reading incoming content from the socket and dispatching it to the message handler manager. /// Should be called only once for persistent and named connections. /// </summary> /// <param name="sharedMemoryConnection">The connection.</param> internal void Connection_InitiateReceiving(SharedMemoryConnection sharedMemoryConnection) { SynchronousReceiving synchronousReceiving = new SynchronousReceiving(); synchronousReceiving.SharedMemoryConnection = sharedMemoryConnection; synchronousReceiving.SharedMemoryConnectionManager = this; Thread thread = new Thread(new ThreadStart(synchronousReceiving.ReceiveSynchronously)); thread.IsBackground = true; thread.Start(); }
/// <summary> /// Starts listening to the specified end point and accepting incoming connections. /// </summary> /// <param name="endPoint">The end point.</param> public override void StartListening(object endPoint) { BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; if (this._smAcceptConnectionClosure != null) throw GenuineExceptions.Get_Server_EndPointIsAlreadyBeingListenedTo(this._smAcceptConnectionClosure.ShareName); SharedMemoryConnection sharedMemoryConnection = null; using (new ReaderAutoLocker(this._disposeLock)) { if (this._disposed) throw OperationException.WrapException(this._disposeReason); } string shareName = endPoint as string; if (shareName == null || shareName.Length <= 0 || ! shareName.StartsWith("gshmem")) throw GenuineExceptions.Get_Server_IncorrectAddressToListen(shareName); try { sharedMemoryConnection = new SharedMemoryConnection(this.ITransportContext, shareName, true, true); this._smAcceptConnectionClosure = new SMAcceptConnectionClosure(this.ITransportContext, sharedMemoryConnection, this, shareName); this.ITransportContext.IGenuineEventProvider.Fire(new GenuineEventArgs(GenuineEventType.GeneralListenerStarted, null, this.Local, endPoint)); Thread thread = new Thread(new ThreadStart(this._smAcceptConnectionClosure.AcceptConnections)); thread.IsBackground = true; thread.Start(); // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 ) { binaryLogWriter.WriteEvent(LogCategory.AcceptingConnection, "SharedMemoryConnectionManager.StartListening", LogMessageType.ListeningStarted, null, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, shareName, null, null, null, "\"{0}\" is now listened.", shareName); } } catch(Exception ex) { // LOG: if ( binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0 ) { binaryLogWriter.WriteEvent(LogCategory.AcceptingConnection, "SharedMemoryConnectionManager.StartListening", LogMessageType.ListeningStarted, ex, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, shareName, null, null, null, "Listening to \"{0}\" cannot be started.", shareName); } if (sharedMemoryConnection != null) sharedMemoryConnection.ReleaseUnmanagedResources(); throw; } }
/// <summary> /// Starts listening to the specified end point and accepting incoming connections. /// </summary> /// <param name="endPoint">The end point.</param> public override void StartListening(object endPoint) { BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; if (this._smAcceptConnectionClosure != null) { throw GenuineExceptions.Get_Server_EndPointIsAlreadyBeingListenedTo(this._smAcceptConnectionClosure.ShareName); } SharedMemoryConnection sharedMemoryConnection = null; using (new ReaderAutoLocker(this._disposeLock)) { if (this._disposed) { throw OperationException.WrapException(this._disposeReason); } } string shareName = endPoint as string; if (shareName == null || shareName.Length <= 0 || !shareName.StartsWith("gshmem")) { throw GenuineExceptions.Get_Server_IncorrectAddressToListen(shareName); } try { sharedMemoryConnection = new SharedMemoryConnection(this.ITransportContext, shareName, true, true); this._smAcceptConnectionClosure = new SMAcceptConnectionClosure(this.ITransportContext, sharedMemoryConnection, this, shareName); this.ITransportContext.IGenuineEventProvider.Fire(new GenuineEventArgs(GenuineEventType.GeneralListenerStarted, null, this.Local, endPoint)); Thread thread = new Thread(new ThreadStart(this._smAcceptConnectionClosure.AcceptConnections)); thread.IsBackground = true; thread.Start(); // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0) { binaryLogWriter.WriteEvent(LogCategory.AcceptingConnection, "SharedMemoryConnectionManager.StartListening", LogMessageType.ListeningStarted, null, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, shareName, null, null, null, "\"{0}\" is now listened.", shareName); } } catch (Exception ex) { // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0) { binaryLogWriter.WriteEvent(LogCategory.AcceptingConnection, "SharedMemoryConnectionManager.StartListening", LogMessageType.ListeningStarted, ex, null, null, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1, 0, 0, 0, shareName, null, null, null, "Listening to \"{0}\" cannot be started.", shareName); } if (sharedMemoryConnection != null) { sharedMemoryConnection.ReleaseUnmanagedResources(); } throw; } }
/// <summary> /// Sends the message through the specified connection. /// </summary> /// <param name="message">The message.</param> /// <param name="sharedMemoryConnection">The connection.</param> private void SendSync(Message message, SharedMemoryConnection sharedMemoryConnection) { BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter; try { // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0) { binaryLogWriter.WriteEvent(LogCategory.Connection, "SharedMemoryConnectionManager.SendSync", LogMessageType.MessageIsSentSynchronously, null, message, sharedMemoryConnection.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, sharedMemoryConnection.ConnectionLevelSecurity, sharedMemoryConnection.ConnectionLevelSecurity == null ? null : sharedMemoryConnection.ConnectionLevelSecurity.Name, sharedMemoryConnection.DbgConnectionId, 0, 0, 0, null, null, null, null, "Message is sent synchronously through the Shared Memory connection."); } // now that we have the connection, obtain the write access int sendTimeout = GenuineUtility.GetTimeout(this._sendTimeoutSpan); if (GenuineUtility.IsTimeoutExpired(message.FinishTime, sendTimeout)) { sendTimeout = message.FinishTime; } try { if (!Monitor.TryEnter(sharedMemoryConnection.WriteAccess, GenuineUtility.GetMillisecondsLeft(sendTimeout))) { throw GenuineExceptions.Get_Send_Timeout(); } } catch { throw GenuineExceptions.Get_Send_Timeout(); } // the write access was obtained, send the message try { sharedMemoryConnection.LowLevel_SendSync(message.SerializedContent, sendTimeout); } catch (Exception ex) { this.ConnectionFailed(ex, sharedMemoryConnection); throw; } finally { Monitor.Exit(sharedMemoryConnection.WriteAccess); } message.Dispose(); } catch (Exception ex) { // LOG: if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0) { binaryLogWriter.WriteEvent(LogCategory.Connection, "SharedMemoryConnectionManager.SendSync", LogMessageType.MessageIsSentSynchronously, ex, message, sharedMemoryConnection.Remote, null, GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, sharedMemoryConnection.DbgConnectionId, 0, 0, 0, null, null, null, null, "The message cannot be delivered."); } throw; } finally { message.Dispose(); } }