static int SwarmOpenConnection(FConnectionCallback CallbackFunc, IntPtr CallbackData, ELogFlags LoggingFlags, IntPtr OptionsFolder) { try { return GInstance.OpenConnection(CallbackFunc, CallbackData, (ELogFlags)LoggingFlags, FStringMarshaler.MarshalNativeToManaged(OptionsFolder)); } catch(Exception Ex) { DebugLog.Write(Ex.Message + "\n" + Ex.ToString()); return 0; } }
Int32 TryOpenConnection(FConnectionCallback CallbackFunc, IntPtr CallbackData, ELogFlags LoggingFlags) { try { // Allocate our new connection wrapper object Connection = new IAgentInterfaceWrapper(); // Make sure the agent is alive and responsive before continuing EditorLog(EVerbosityLevel.Informative, "[TryOpenConnection] Testing the Agent"); Hashtable InParameters = null; Hashtable OutParameters = null; bool AgentIsReady = false; while (!AgentIsReady) { try { // Simply try to call the method and if it doesn't throw // an exception, consider it a success Connection.Method(0, InParameters, ref OutParameters); AgentIsReady = true; } catch (Exception ex) { // Wait a little longer EditorLog(EVerbosityLevel.Critical, "[TryOpenConnection] Waiting for the agent to start up ..."); EditorLog(EVerbosityLevel.Critical, ex.ToString()); Thread.Sleep(5000); } } // Request an official connection to the Agent EditorLog(EVerbosityLevel.Informative, "[TryOpenConnection] Opening Connection to Agent"); EditorLog(EVerbosityLevel.Informative, "[TryOpenConnection] Local Process ID is " + Process.GetCurrentProcess().Id.ToString()); StartTiming("OpenConnection-Remote", false); ConnectionHandle = Connection.OpenConnection(AgentProcess, AgentProcessOwner, Process.GetCurrentProcess().Id, LoggingFlags, out ConnectionConfiguration); StopTiming(); if (ConnectionHandle >= 0) { Log(EVerbosityLevel.Informative, ELogColour.Green, "[Interface:TryOpenConnection] Local connection established"); // Spawn a thread to monitor the message queue MessageThreadData ThreadData = new MessageThreadData(); ThreadData.Owner = this; ThreadData.Connection = Connection; ThreadData.ConnectionHandle = ConnectionHandle; ThreadData.ConnectionCallback = CallbackFunc; ThreadData.ConnectionCallbackData = CallbackData; ThreadData.ConnectionConfiguration = ConnectionConfiguration; // Launch the message queue thread ConnectionMessageThread = new Thread(new ParameterizedThreadStart(MessageThreadProc)); ConnectionMessageThread.Name = "ConnectionMessageThread"; ConnectionMessageThread.Start( ThreadData ); // Launch the agent monitor thread ConnectionMonitorThread = new Thread(new ParameterizedThreadStart(MonitorThreadProc)); ConnectionMonitorThread.Name = "ConnectionMonitorThread"; ConnectionMonitorThread.Start(ThreadData); // Save the user's callback routine ConnectionCallback = CallbackFunc; ConnectionCallbackData = CallbackData; ConnectionLoggingFlags = LoggingFlags; } } catch (Exception Ex) { EditorLog(EVerbosityLevel.Critical, "[TryOpenConnection] Error: " + Ex.Message); EditorLog(EVerbosityLevel.Critical, Ex.ToString()); ConnectionHandle = Constants.INVALID; Connection = null; } return ConnectionHandle; }
/* * Clean up all of the remainders from a closed connection, including the network channels, etc. */ Int32 CleanupClosedConnection() { Monitor.Enter(CleanupClosedConnectionLock); // NOTE: Do not make any calls to the real Connection in here! // If, for any reason, the connection has died, calling into it from here will // end up causing this thread to hang, waiting for the dead connection to respond. DebugLog.Write("[Interface:CleanupClosedConnection] Closing all connections to the Agent"); // Reset all necessary assigned variables AgentProcess = null; AgentProcessOwner = false; if (Connection != null) { // Notify the connection wrapper that the connection is gone Connection.SignalConnectionDropped(); Connection = null; } ConnectionHandle = Constants.INVALID; ConnectionConfiguration = null; // Clean up and close up the connection callback if (ConnectionCallback != null) { IntPtr QuitMessage = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(FMessage))); Marshal.StructureToPtr(new FMessage(ESwarmVersionValue.VER_1_0, EMessageType.QUIT), QuitMessage, false); ConnectionCallback(QuitMessage, ConnectionCallbackData); } ConnectionCallback = null; ConnectionCallbackData = IntPtr.Zero; // Close all associated channels if (OpenChannels.Count > 0) { foreach (ChannelInfo NextChannel in OpenChannels.Values) { // Just close the handle and we'll clear the entire list later if (NextChannel.ChannelFileStream != null) { NextChannel.ChannelFileStream.Close(); NextChannel.ChannelFileStream = null; } } OpenChannels.Clear(); } // Unregister the primary network communication channel if (NetworkChannel != null) { ChannelServices.UnregisterChannel(NetworkChannel); NetworkChannel = null; } Monitor.Exit(CleanupClosedConnectionLock); return Constants.SUCCESS; }
/** * Opens a new connection to the Swarm * * @param CallbackFunc The callback function Swarm will use to communicate back to the Instigator * * @return An INT containing the error code (if < 0) or the handle (>= 0) which is useful for debugging only */ public virtual Int32 OpenConnection(FConnectionCallback CallbackFunc, IntPtr CallbackData, ELogFlags LoggingFlags, string OptionsFolder) { // Checked here so we can time OpenConnection if ((LoggingFlags & ELogFlags.LOG_TIMINGS) == ELogFlags.LOG_TIMINGS) { PerfTimerInstance = new PerfTimer(); } StartTiming("OpenConnection-Managed", true); // Establish a connection to the local Agent server object ConnectionHandle = Constants.INVALID; Int32 ReturnValue = Constants.INVALID; try { EditorLog(EVerbosityLevel.Informative, "[OpenConnection] Registering TCP channel ..."); // Start up network services, by opening a network communication channel NetworkChannel = new TcpClientChannel(); ChannelServices.RegisterChannel(NetworkChannel, false); // See if an agent is already running, and if not, launch one EnsureAgentIsRunning(OptionsFolder); if (AgentProcess != null) { EditorLog(EVerbosityLevel.Informative, "[OpenConnection] Connecting to agent ..."); ReturnValue = TryOpenConnection(CallbackFunc, CallbackData, LoggingFlags); if (ReturnValue >= 0) { AgentCacheFolder = ConnectionConfiguration.AgentCachePath; if (AgentCacheFolder.Length == 0) { EditorLog(EVerbosityLevel.Critical, "[OpenConnection] Agent cache folder with 0 length."); CloseConnection(); ReturnValue = Constants.ERROR_FILE_FOUND_NOT; } } } else { EditorLog(EVerbosityLevel.Critical, "[OpenConnection] Failed to find Swarm Agent"); ReturnValue = Constants.ERROR_FILE_FOUND_NOT; } } catch (Exception Ex) { EditorLog(EVerbosityLevel.Critical, "[OpenConnection] Error: " + Ex.Message); ReturnValue = Constants.ERROR_EXCEPTION; } // Finally, if there have been no errors, assign the connection handle if (ReturnValue >= 0) { ConnectionHandle = ReturnValue; } else { // If we've failed for any reason, call the clean up routine CleanupClosedConnection(); } StopTiming(); return ReturnValue; }
FSwarmInterface() { AgentProcess = null; AgentProcessOwner = false; Connection = null; ConnectionHandle = Constants.INVALID; ConnectionMessageThread = null; ConnectionMonitorThread = null; ConnectionConfiguration = null; ConnectionCallback = null; BaseChannelHandle = 0; PendingTasks = null; NetworkChannel = null; PerfTimerInstance = null; OpenChannels = new ReaderWriterDictionary<Int32, ChannelInfo>(); FreeChannelWriteBuffers = new Stack<byte[]>(); CleanupClosedConnectionLock = new Object(); // TODO: Delete old files }