public LocalManager() { EnsureServer(null); Type type = typeof(RemoteManager); if (mChannelIdPool.Count != 0) { mRemoteChannelId = mChannelIdPool.First(); mChannelIdPool.Remove(mRemoteChannelId); mRemoteManager = (RemoteManager)Activator.GetObject(type, "ipc://" + mRemoteChannelId + "/" + type.GUID.ToString("N")); } else { string path = type.Assembly.Location; string remoteChannelId = Guid.NewGuid().ToString("N"); mRemoteProcess = new ChildProcess(path, "-ipc " + remoteChannelId); bool newSig1, newSig2; using (var signal1 = new Semaphore(0, 1, remoteChannelId + "/signal1", out newSig1)) using (var signal2 = new Semaphore(0, 1, remoteChannelId + "/signal2", out newSig2)) { signal1.WaitOne(); signal2.Release(); } mRemoteManager = (RemoteManager)Activator.GetObject(type, "ipc://" + remoteChannelId + "/" + type.GUID.ToString("N")); } }
internal static void EnsureServer(string channelId) { lock (mSync) { if (mChannelId == null) { mChannelId = channelId ?? Guid.NewGuid().ToString("N"); // By default the server formatter is configured for low security scenarios like the web, // causing it to reject marshalling delegates or client side object references. Since our // IPC channel is not accessible from other machines we are safe to turn the filter off. // This is required for the server to be able to call back into the client. var provider = new BinaryServerFormatterSinkProvider { TypeFilterLevel = TypeFilterLevel.Full }; var settings = new Hashtable(); settings["portName"] = mChannelId; ChannelServices.RegisterChannel(new IpcChannel(settings, null, provider), true); var manager = new RemoteManager(); RemotingServices.Marshal(manager, typeof(RemoteManager).GUID.ToString("N")); // NOTE: Assigning the manager should be the very last thing done in here. mLocalManager = manager; if (channelId != null) { bool newSig1, newSig2; using (var signal1 = new Semaphore(0, 1, channelId + "/signal1", out newSig1)) using (var signal2 = new Semaphore(0, 1, channelId + "/signal2", out newSig2)) { signal1.Release(); signal2.WaitOne(); } } } else if (channelId != null) { if (channelId != mChannelId) { throw new NotSupportedException("Multiple server channels are not supported."); } } } }
internal static void EnsureServer(string channelId) { lock (mSync) { if (mChannelId == null) { mChannelId = channelId ?? Guid.NewGuid().ToString("N"); // By default the server formatter is configured for low security scenarios like the web, // causing it to reject marshalling delegates or client side object references. Since our // IPC channel is not accessible from other machines we are safe to turn the filter off. // This is required for the server to be able to call back into the client. var provider = new BinaryServerFormatterSinkProvider { TypeFilterLevel = TypeFilterLevel.Full }; var settings = new Hashtable(); settings["portName"] = mChannelId; ChannelServices.RegisterChannel(new IpcChannel(settings, null, provider), true); var manager = new RemoteManager(); RemotingServices.Marshal(manager, typeof(RemoteManager).GUID.ToString("N")); // NOTE: Assigning the manager should be the very last thing done in here. mLocalManager = manager; if (channelId != null) { bool newSig1, newSig2; using (var signal1 = new Semaphore(0, 1, channelId + "/signal1", out newSig1)) using (var signal2 = new Semaphore(0, 1, channelId + "/signal2", out newSig2)) { signal1.Release(); signal2.WaitOne(); } } } else if (channelId != null) { if (channelId != mChannelId) throw new NotSupportedException("Multiple server channels are not supported."); } } }