public Evaluator(string jsShellPath, string options) { var psi = new ProcessStartInfo( jsShellPath, options ) { RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true, UseShellExecute = false, WindowStyle = ProcessWindowStyle.Hidden }; ManualResetEventSlim stdoutSignal, stderrSignal; stdoutSignal = new ManualResetEventSlim(false); stderrSignal = new ManualResetEventSlim(false); Process = Process.Start(psi); ThreadPool.QueueUserWorkItem((_) => { _StdOut = Process.StandardOutput.ReadToEnd(); stdoutSignal.Set(); }); ThreadPool.QueueUserWorkItem((_) => { _StdErr = Process.StandardError.ReadToEnd(); stderrSignal.Set(); }); _JoinImpl = () => { stdoutSignal.Wait(); stderrSignal.Wait(); stderrSignal.Dispose(); stderrSignal.Dispose(); }; }
public Evaluator(string jsShellPath, string options, Dictionary<string, string> environmentVariables = null) { Id = Interlocked.Increment(ref NextId); var psi = new ProcessStartInfo( jsShellPath, options ) { RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true, UseShellExecute = false, WindowStyle = ProcessWindowStyle.Hidden }; if (environmentVariables != null) { foreach (var kvp in environmentVariables) psi.EnvironmentVariables[kvp.Key] = kvp.Value; } ManualResetEventSlim stdoutSignal, stderrSignal; stdoutSignal = new ManualResetEventSlim(false); stderrSignal = new ManualResetEventSlim(false); Process = Process.Start(psi); ThreadPool.QueueUserWorkItem((_) => { try { _StdOut = Process.StandardOutput.ReadToEnd(); } catch { } stdoutSignal.Set(); }); ThreadPool.QueueUserWorkItem((_) => { try { _StdErr = Process.StandardError.ReadToEnd(); } catch { } stderrSignal.Set(); }); _JoinImpl = () => { stdoutSignal.Wait(); stderrSignal.Wait(); stderrSignal.Dispose(); stderrSignal.Dispose(); }; }
// Demonstrates: // ManualResetEventSlim construction w/ SpinCount // ManualResetEventSlim.WaitHandle static void MRES_SpinCountWaitHandle() { // Construct a ManualResetEventSlim with a SpinCount of 1000 // Higher spincount => longer time the MRES will spin-wait before taking lock System.Threading.ManualResetEventSlim mres1 = new System.Threading.ManualResetEventSlim(false, 1000); System.Threading.ManualResetEventSlim mres2 = new System.Threading.ManualResetEventSlim(false, 1000); Task bgTask = Task.Factory.StartNew(() => { // Just wait a little Thread.Sleep(100); // Now signal both MRESes Console.WriteLine("Task signalling both MRESes"); mres1.Set(); mres2.Set(); }); // A common use of MRES.WaitHandle is to use MRES as a participant in // WaitHandle.WaitAll/WaitAny. Note that accessing MRES.WaitHandle will // result in the unconditional inflation of the underlying ManualResetEvent. WaitHandle.WaitAll(new WaitHandle[] { mres1.WaitHandle, mres2.WaitHandle }); Console.WriteLine("WaitHandle.WaitAll(mres1.WaitHandle, mres2.WaitHandle) completed."); // Clean up bgTask.Wait(); mres1.Dispose(); mres2.Dispose(); }
public void Dispose() { var mre = new ManualResetEventSlim(false); mre.Dispose(); Assert.IsFalse(mre.IsSet, "#0a"); try { mre.Reset(); Assert.Fail("#1"); } catch (ObjectDisposedException) { } mre.Set(); try { mre.Wait(0); Assert.Fail("#3"); } catch (ObjectDisposedException) { } try { var v = mre.WaitHandle; Assert.Fail("#4"); } catch (ObjectDisposedException) { } }
// Demonstrates: // ManualResetEventSlim construction // ManualResetEventSlim.Wait() // ManualResetEventSlim.Set() // ManualResetEventSlim.Reset() // ManualResetEventSlim.IsSet static void MRES_SetWaitReset() { System.Threading.ManualResetEventSlim mres1 = new System.Threading.ManualResetEventSlim(false); // initialize as unsignaled System.Threading.ManualResetEventSlim mres2 = new System.Threading.ManualResetEventSlim(false); // initialize as unsignaled System.Threading.ManualResetEventSlim mres3 = new System.Threading.ManualResetEventSlim(true); // initialize as signaled // Start an asynchronous Task that manipulates mres3 and mres2 var observer = Task.Factory.StartNew(() => { mres1.Wait(); Console.WriteLine("observer sees signaled mres1!"); Console.WriteLine("observer resetting mres3..."); mres3.Reset(); // should switch to unsignaled Console.WriteLine("observer signalling mres2"); mres2.Set(); }); Console.WriteLine("main thread: mres3.IsSet = {0} (should be true)", mres3.IsSet); Console.WriteLine("main thread signalling mres1"); mres1.Set(); // This will "kick off" the observer Task mres2.Wait(); // This won't return until observer Task has finished resetting mres3 Console.WriteLine("main thread sees signaled mres2!"); Console.WriteLine("main thread: mres3.IsSet = {0} (should be false)", mres3.IsSet); // It's good form to Dispose() a ManualResetEventSlim when you're done with it observer.Wait(); // make sure that this has fully completed mres1.Dispose(); mres2.Dispose(); mres3.Dispose(); }
public void SuccessiveTimeoutTest(HostType hostType, TransportType transportType, MessageBusType messageBusType) { using (var host = CreateHost(hostType, transportType)) { // Arrange var mre = new ManualResetEventSlim(false); host.Initialize(keepAlive: 5, messageBusType: messageBusType); var connection = CreateConnection(host, "/my-reconnect"); using (connection) { connection.Reconnected += () => { mre.Set(); }; connection.Start(host.Transport).Wait(); ((Client.IConnection)connection).KeepAliveData = new KeepAliveData(TimeSpan.FromMilliseconds(500)); // Assert that Reconnected is called Assert.True(mre.Wait(TimeSpan.FromSeconds(15))); // Assert that Reconnected is called again mre.Reset(); Assert.True(mre.Wait(TimeSpan.FromSeconds(15))); // Clean-up mre.Dispose(); } } }
public static void Main(string[] args) { string url = "http://www.intelliTechture.com"; if(args.Length > 0) { url = args[0]; } Console.Write(url); WebRequest webRequest = WebRequest.Create(url); ManualResetEventSlim resetEvent = new ManualResetEventSlim(); IAsyncResult asyncResult = webRequest.BeginGetResponse( (completedAsyncResult) => { HttpWebResponse response = (HttpWebResponse)webRequest.EndGetResponse( completedAsyncResult); Stream stream = response.GetResponseStream(); StreamReader reader = new StreamReader(stream); int length = reader.ReadToEnd().Length; Console.WriteLine(FormatBytes(length)); resetEvent.Set(); resetEvent.Dispose(); }, null); // Indicate busy using dots while(!asyncResult.AsyncWaitHandle.WaitOne(100)) { Console.Write('.'); } resetEvent.Wait(); }
public void ReconnectionSuccesfulTest(HostType hostType, TransportType transportType, MessageBusType messageBusType) { using (var host = CreateHost(hostType, transportType)) { // Arrange var mre = new ManualResetEventSlim(false); host.Initialize(keepAlive: null, messageBusType: messageBusType); var connection = CreateConnection(host, "/my-reconnect"); using (connection) { ((Client.IConnection)connection).KeepAliveData = new KeepAliveData(TimeSpan.FromSeconds(2)); connection.Reconnected += () => { mre.Set(); }; connection.Start(host.Transport).Wait(); // Assert Assert.True(mre.Wait(TimeSpan.FromSeconds(10))); // Clean-up mre.Dispose(); } } }
/// <summary> /// Starts the IISExpress process that hosts the test site. /// </summary> public void Start() { _manualResetEvent = new ManualResetEventSlim(false); var thread = new Thread(StartIisExpress) { IsBackground = true }; thread.Start(); if (!_manualResetEvent.Wait(15000)) throw new Exception("Could not start IIS Express"); _manualResetEvent.Dispose(); }
public void ManualResetEventSlim_SetAfterDisposeTest() { ManualResetEventSlim mre = new ManualResetEventSlim(); ParallelTestHelper.Repeat(delegate { Exception disp = null, setting = null; CountdownEvent evt = new CountdownEvent(2); CountdownEvent evtFinish = new CountdownEvent(2); Task.Factory.StartNew(delegate { try { evt.Signal(); evt.Wait(1000); mre.Dispose(); } catch (Exception e) { disp = e; } evtFinish.Signal(); }); Task.Factory.StartNew(delegate { try { evt.Signal(); evt.Wait(1000); mre.Set(); } catch (Exception e) { setting = e; } evtFinish.Signal(); }); bool bb = evtFinish.Wait(1000); if (!bb) Assert.AreEqual(true, evtFinish.IsSet); Assert.IsTrue(bb, "#0"); Assert.IsNull(disp, "#1"); Assert.IsNull(setting, "#2"); evt.Dispose(); evtFinish.Dispose(); }); }
public static void CancelBeforeWait() { ManualResetEventSlim mres = new ManualResetEventSlim(); CancellationTokenSource cs = new CancellationTokenSource(); cs.Cancel(); CancellationToken ct = cs.Token; const int millisec = 100; TimeSpan timeSpan = new TimeSpan(100); EnsureOperationCanceledExceptionThrown( () => mres.Wait(ct), ct, "CancelBeforeWait: An OCE should have been thrown."); EnsureOperationCanceledExceptionThrown( () => mres.Wait(millisec, ct), ct, "CancelBeforeWait: An OCE should have been thrown."); EnsureOperationCanceledExceptionThrown( () => mres.Wait(timeSpan, ct), ct, "CancelBeforeWait: An OCE should have been thrown."); mres.Dispose(); }
public bool Start() { RegisterEvents(); lastGenerationUpdate = String.Empty; lastTimespan = TimeSpan.Zero; finishedEventHandle = new ManualResetEventSlim(false, 1); Optimizer.Start(); finishedEventHandle.Wait(); if (Optimizer.ExecutionState == Core.ExecutionState.Started || Optimizer.ExecutionState == Core.ExecutionState.Paused) { Optimizer.Stop(); } ContentManager.Save(new RunCollection(GetRun().ToEnumerable()), runInfo.SavePath, false); DeregisterEvents(); finishedEventHandle.Dispose(); return finishedSuccessfully; }
/// <summary> /// /// </summary> /// <param name="name"></param> /// <param name="timeout">Seconds we will try to get the lock for.</param> /// <param name="ttl">Seconds until lock times out. Governs how frequently we extend the lock as well. Minimum of 10 seconds.</param> public DistributedLock(string name, int timeout = 10, int ttl = 30) { if (string.IsNullOrEmpty(name)) throw new Exception("Distributed Lock Requires a Name"); _ttl = ttl; if (_ttl < 10) throw new Exception("Minimum TTL is 10 seconds"); _timeout = DateTime.UtcNow.AddSeconds(timeout); _client = new EtcdClient(Configuration.Instance.Hostnames[0]); _name = name; _handle = new ManualResetEventSlim(false); // get the unique ID of this locking instance _guid = Guid.NewGuid(); // 1. try to create the node // -> if already exists set up a watch to lock after it // is given back. // watch should also have the ID of the modifyIndex so // it will catch up if something happens in between // 2. extend the lock while it's active automatically // by updating the TTL // // this will attempt to get the lock and re-call itself // if there are multiple threads/servers attempting to // get the same lock GetLock(); // use the reset event to block this thread _handle.Wait(timeout * 1000); _handle.Dispose(); if (_index == 0) { // we didn't get the lock throw new DistributedLockException("Could not aquire lock after retries"); } }
public static bool CancelBeforeWait() { TestHarness.TestLog("* ManualResetEventCancellationTests.CancelBeforeWait()"); bool passed = true; ManualResetEventSlim mres = new ManualResetEventSlim(); CancellationTokenSource cs = new CancellationTokenSource(); cs.Cancel(); CancellationToken ct = cs.Token; const int millisec = 100; TimeSpan timeSpan = new TimeSpan(100); passed &= TestHarnessAssert.EnsureOperationCanceledExceptionThrown(() => mres.Wait(ct), ct, "An OCE should have been thrown."); passed &= TestHarnessAssert.EnsureOperationCanceledExceptionThrown(() => mres.Wait(millisec, ct), ct, "An OCE should have been thrown."); passed &= TestHarnessAssert.EnsureOperationCanceledExceptionThrown(() => mres.Wait(timeSpan, ct), ct, "An OCE should have been thrown."); mres.Dispose(); return passed; }
protected virtual void Dispose(bool disposing) { if (_disposed) { return; } if (!disposing) { return; } if (IsReadLockHeld || IsUpgradeableReadLockHeld || IsWriteLockHeld) { throw new SynchronizationLockException("The lock is being disposed while still being used"); } _upgradableEvent.Dispose(); _writerDoneEvent.Dispose(); _readerDoneEvent.Dispose(); _disposed = true; }
void Dispatch() { wh = new ManualResetEventSlim(); while (true) { Task outTask = null; if (queue.TryDequeue(out outTask)) { Debug.WriteLine("--- Executing Task ---"); TryExecuteTask(outTask); Debug.WriteLine("--- Done Executing Task ---"); if (stopped) { stopped = false; dispatch = null; queue = new ConcurrentQueue<Task>(); Debug.WriteLine("Scheduler stopped."); del.OnStop(this); break; } } else { wh.Wait(); wh.Reset(); } } stopped = false; dispatch = null; wh.Dispose(); wh = null; }
public void Dispose_Double () { var mre = new ManualResetEventSlim (); mre.Dispose (); mre.Dispose (); }
public void PropertyBag_MultiEngine_Parallel() { // This is a torture test for ConcurrentWeakSet and general engine teardown/cleanup. // It has exposed some very tricky engine bugs. var bag = new PropertyBag(); engine.AddHostObject("bag", bag); const int threadCount = 256; var engineCount = 0; // 32-bit V8 starts failing requests to create new contexts rather quickly. This is // because each V8 isolate requires (among other things) a 32MB address space // reservation. 64-bit V8 reserves much larger blocks but benefits from the enormous // available address space. var maxV8Count = Environment.Is64BitProcess ? 128 : 16; var maxJScriptCount = (threadCount - maxV8Count) / 2; var startEvent = new ManualResetEventSlim(false); var checkpointEvent = new ManualResetEventSlim(false); var continueEvent = new ManualResetEventSlim(false); var stopEvent = new ManualResetEventSlim(false); ParameterizedThreadStart body = arg => { // ReSharper disable AccessToDisposedClosure var index = (int)arg; startEvent.Wait(); ScriptEngine scriptEngine; if (index < maxV8Count) { scriptEngine = new V8ScriptEngine(); } else if (index < (maxV8Count + maxJScriptCount)) { scriptEngine = new JScriptEngine(); } else { scriptEngine = new VBScriptEngine(); } scriptEngine.AddHostObject("bag", bag); if (Interlocked.Increment(ref engineCount) == threadCount) { checkpointEvent.Set(); } continueEvent.Wait(); scriptEngine.Dispose(); if (Interlocked.Decrement(ref engineCount) == 0) { stopEvent.Set(); } // ReSharper restore AccessToDisposedClosure }; var threads = Enumerable.Range(0, threadCount).Select(index => new Thread(body)).ToArray(); threads.ForEach((thread, index) => thread.Start(index)); startEvent.Set(); checkpointEvent.Wait(); Assert.AreEqual(threadCount + 1, bag.EngineCount); continueEvent.Set(); stopEvent.Wait(); GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); Assert.AreEqual(1, bag.EngineCount); Array.ForEach(threads, thread => thread.Join()); startEvent.Dispose(); checkpointEvent.Dispose(); continueEvent.Dispose(); stopEvent.Dispose(); }
public static void Main(string[] args) { Couchbase.Lite.Util.Log.SetLogger(Logger); var alternateDir = default(string); var pullUrl = default(Uri); var pushUrl = default(Uri); var portToUse = DefaultPort; var readOnly = false; var requiresAuth = false; var createTarget = false; var continuous = false; var userName = default(string); var password = default(string); var useSSL = false; var sslCertPath = default(string); var sslCertPass = default(string); var storageType = "SQLite"; var passwordMap = new Dictionary<string, string>(); var showHelp = false; var revsLimit = 0; View.Compiler = new JSViewCompiler(); var options = new OptionSet { { "dir=", "Specifies an alternate directory to store databases in", v => alternateDir = v }, { "port=", "Specifies the port to listen on (default 59840)", v => portToUse = Int32.Parse(v) }, { "readonly", "Enables readonly mode", v => readOnly = v != null }, { "auth", "Set listener to require HTTP auth", v => requiresAuth = v != null }, { "pull=", "Specifies a remote database to pull from", v => pullUrl = new Uri(v) }, { "push=", "Specifies a remote database to push to", v => pushUrl = new Uri(v) }, { "create-target", "Creates the replication target database, if pull", v => createTarget = v != null }, { "continuous", "Specifies continuous replication", v => continuous = v != null }, { "user="******"Specifies a username for connecting to a remote database", v => userName = v }, { "password="******"Specifies a password for connection to a remote database", v => password = v }, { "revs_limit=", "Sets default max rev-tree depth for databases", v => revsLimit = Int32.Parse(v) }, { "ssl", "Serve over SSL", v => useSSL = v != null }, { "sslcert=", "Path to the SSL certificate to use", v => sslCertPath = v }, { "sslpass="******"Password for the SSL certificate", v => sslCertPass = v }, { "storage=", "Set default storage engine ('SQLite' (default) or 'ForestDB')", v => storageType = v }, { "dbpassword="******"Register password to open a database (name=password)", v => RegisterPassword(passwordMap, v) }, { "help|h|?", "Show this help message", v => showHelp = v != null } }; try { var remaining = options.Parse(args); foreach(var arg in remaining) { Logger.W("Listener", "Unrecognized argument {0}, ignoring...", arg); } } catch(Exception e) { Logger.E("Listener", "Error parsing arguments", e); ShowHelp(options); Exit(); return; } if (showHelp) { ShowHelp(options); Exit(); return; } Couchbase.Lite.Storage.ForestDB.Plugin.Register(); Couchbase.Lite.Storage.SQLCipher.Plugin.Register(); var manager = alternateDir != null ? new Manager(new DirectoryInfo(alternateDir), ManagerOptions.Default) : Manager.SharedInstance; manager.StorageType = storageType; if(revsLimit > 0) { // Note: Internal API (used for testing) manager.DefaultMaxRevTreeDepth = revsLimit; } if (passwordMap.Count > 0) { foreach (var entry in passwordMap) { #pragma warning disable 618 manager.RegisterEncryptionKey(entry.Key, new SymmetricKey(entry.Value)); #pragma warning restore 618 } } var tcpOptions = CouchbaseLiteTcpOptions.Default | CouchbaseLiteTcpOptions.AllowBasicAuth; var sslCert = default(X509Certificate2); if (useSSL) { tcpOptions |= CouchbaseLiteTcpOptions.UseTLS; if (sslCertPath != null) { if (!File.Exists(sslCertPath)) { Logger.E("Listener", "No file exists at given path for SSL cert ({0})", sslCertPath); Exit(); return; } try { sslCert = new X509Certificate2(sslCertPath, sslCertPass); } catch(Exception e) { Logger.E("Listener", "Error reading SSL cert ({0}), {1}", sslCertPath, e); Exit(); return; } } } var replicator = default(Replication); if (pushUrl != null || pullUrl != null) { replicator = SetupReplication(manager, continuous, createTarget, pushUrl ?? pullUrl, pullUrl != null, userName, password); if (replicator == null) { Exit(); return; } } CouchbaseLiteServiceListener listener = new CouchbaseLiteTcpListener(manager, (ushort)portToUse, tcpOptions, sslCert); listener.ReadOnly = readOnly; if (requiresAuth) { var random = new Random(); var generatedPassword = random.Next().ToString(); listener.SetPasswords(new Dictionary<string, string> { { "cbl", generatedPassword } }); Logger.I("Listener", "Auth required: user='******', password='******'", generatedPassword); } listener.Start(); Logger.I("Listener", "LISTENING..."); var wait = new ManualResetEventSlim(); Console.WriteLine("Press Ctrl+C to end the process"); Console.CancelKeyPress += (sender, e) => wait.Set(); wait.Wait(); Console.WriteLine("Shutting down now"); wait.Dispose(); foreach(var db in manager.AllOpenDatabases()) { db.Close(); } if (replicator != null) { replicator.Stop(); Thread.Sleep(5000); } }
public override byte[] GetSerializedPhysicsShapes() { const int SHAPE_WAIT_TIMEOUT = 5000; byte[] outShapes = null; ManualResetEventSlim signalEvent = new ManualResetEventSlim(); _scene.QueueCommand(new Commands.GenericSyncCmd(this, (scene) => { IEnumerable<PhysX.Shape> shapes = null; if (HasActor) { shapes = _primaryShapes; } else { RelatedShapes childShapes; if (_parentPrim._childShapes.TryGetValue(this, out childShapes)) { shapes = childShapes.PhyShapes; } } if (shapes == null) { signalEvent.Set(); return; } using (PhysX.Collection coll = _scene.SceneImpl.Physics.CreateCollection()) { CollectShapesForSerialization(shapes, coll); if (coll.GetNumberOfObjects() > 0) { using (System.IO.MemoryStream memStream = new System.IO.MemoryStream()) { coll.Serialize(memStream); outShapes = memStream.ToArray(); } } } signalEvent.Set(); })); signalEvent.Wait(SHAPE_WAIT_TIMEOUT); if (signalEvent.IsSet) { //this is the normal case, safe to dispose now and not rely on the finalizer signalEvent.Dispose(); } return outShapes; }
public void OnConnectionSlowDoesntFireForLongPolling(HostType hostType, TransportType transportType) { using (var host = CreateHost(hostType, transportType)) { // Arrange var mre = new ManualResetEventSlim(); host.Initialize(keepAlive: 2); var connection = CreateConnection(host, "/my-reconnect"); using (connection) { ((Client.IConnection)connection).KeepAliveData = new KeepAliveData(TimeSpan.FromSeconds(2)); connection.ConnectionSlow += () => { mre.Set(); }; connection.Start(host.Transport).Wait(); // Assert Assert.False(mre.Wait(TimeSpan.FromSeconds(10))); // Clean-up mre.Dispose(); } } }
public void V8ScriptEngine_Parallel() { engine.AddHostObject("host", new HostFunctions()); engine.AddHostObject("clr", HostItemFlags.GlobalMembers, new HostTypeCollection("mscorlib")); const int threadCount = 256; engine.AddHostObject("list", Enumerable.Range(0, threadCount).ToList()); Assert.AreEqual(threadCount, engine.Evaluate("list.Count")); var startEvent = new ManualResetEventSlim(false); var stopEvent = new ManualResetEventSlim(false); engine.AddHostObject("stopEvent", stopEvent); ThreadStart body = () => { // ReSharper disable AccessToDisposedClosure startEvent.Wait(); engine.Execute("list.RemoveAt(0); if (list.Count == 0) { stopEvent.Set(); }"); // ReSharper restore AccessToDisposedClosure }; var threads = Enumerable.Range(0, threadCount).Select(index => new Thread(body)).ToArray(); threads.ForEach(thread => thread.Start()); startEvent.Set(); stopEvent.Wait(); Assert.AreEqual(0, engine.Evaluate("list.Count")); threads.ForEach(thread => thread.Join()); startEvent.Dispose(); stopEvent.Dispose(); }
} // func Yield #endregion #region -- ExecuteDelegate -------------------------------------------------------- private void ExecuteDelegate() { evResume = new ManualResetEventSlim(false); Task.Yield(); // force background thread // add this thread to the thread-pool lock (luaThreads) luaThreads.Add(this); try { yield(new LuaResult(Lua.RtInvoke(target, currentArguments.Values))); } finally { // remove the thread from the pool lock (luaThreads) luaThreads.Remove(this); taskExecute = null; taskCancelExecute.Dispose(); taskCancelExecute = null; // dispose the events currentYield = LuaResult.Empty; evResume.Dispose(); evResume = null; evYield.Set(); } } // proc ExecuteDelegate
/// <summary> /// Requests asset metadata and response synchronously /// </summary> /// <param name="assetID"></param> /// <returns></returns> public Dictionary<string, string> RequestAssetMetadataSync(OpenMetaverse.UUID assetID) { ManualResetEventSlim syncEvent = new ManualResetEventSlim(); Dictionary<string,string> meta = null; Exception thrown = null; _threadPool.QueueWorkItem(() => { try { meta = RequestAssetMetadataInternal(assetID); } catch (Exception e) { thrown = e; } syncEvent.Set(); }); if (syncEvent.Wait(ASSET_WAIT_TIMEOUT)) { syncEvent.Dispose(); } else { m_log.WarnFormat("[InWorldz.Stratus]: Timout waiting for synchronous metadata request for {0}", assetID); } if (thrown != null) throw new AssetServerException(thrown.Message, thrown); return meta; }
/// <summary> /// Executes the <paramref name="executable"/> asynchronously and waits a maximum time of <paramref name="maxWaitMs"/> for completion. /// </summary> /// <param name="executable">Program to execute</param> /// <param name="arguments">Program arguments</param> /// <param name="idWrapper"><see cref="WindowsIdentityWrapper"/> used to impersonate the external process</param> /// <param name="debugLogger">Debug logger for debug output</param> /// <param name="priorityClass">Process priority</param> /// <param name="maxWaitMs">Maximum time to wait for completion</param> /// <returns>> <see cref="ProcessExecutionResult"/> object that respresents the result of executing the Program</returns> /// <remarks> /// This method throws an exception only if process.Start() fails (in partiular, if the <paramref name="executable"/> doesn't exist). /// Any other error in managed code is signaled by the returned task being set to Faulted state. /// If the program itself does not result in an ExitCode of 0, the returned task ends in RanToCompletion state; /// the ExitCode of the program will be contained in the returned <see cref="ProcessExecutionResult"/>. /// This method is nearly identical to <see cref="ProcessUtils.ExecuteAsync"/>; it is necessary to have this code duplicated /// because AsyncImpersonationProcess hides several methods of the Process class and executing these methods on the base class does /// therefore not work. If this method is changed it is likely that <see cref="ProcessUtils.ExecuteAsync"/> also /// needs to be changed. /// </remarks> internal static Task<ProcessExecutionResult> ExecuteAsync(string executable, string arguments, WindowsIdentityWrapper idWrapper, ILogger debugLogger, ProcessPriorityClass priorityClass = ProcessPriorityClass.Normal, int maxWaitMs = ProcessUtils.DEFAULT_TIMEOUT) { var tcs = new TaskCompletionSource<ProcessExecutionResult>(); var process = new AsyncImpersonationProcess(debugLogger) { StartInfo = new ProcessStartInfo(executable, arguments) { UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = true, RedirectStandardError = true, StandardOutputEncoding = ProcessUtils.CONSOLE_ENCODING, StandardErrorEncoding = ProcessUtils.CONSOLE_ENCODING }, EnableRaisingEvents = true }; // We need to read standardOutput and standardError asynchronously to avoid a deadlock // when the buffer is not big enough to receive all the respective output. Otherwise the // process may block because the buffer is full and the Exited event below is never raised. Task<string> standardOutputTask = null; Task<string> standardErrorTask = null; var standardStreamTasksReady = new ManualResetEventSlim(); // The Exited event is raised in any case when the process has finished, i.e. when it gracefully // finished (ExitCode = 0), finished with an error (ExitCode != 0) and when it was killed below. // That ensures disposal of the process object. process.Exited += (sender, args) => { try { // standardStreamTasksReady is only disposed when starting the process was not successful, // in which case the Exited event is never raised. // ReSharper disable once AccessToDisposedClosure standardStreamTasksReady.Wait(); tcs.TrySetResult(new ProcessExecutionResult { ExitCode = process.ExitCode, // standardStreamTasksReady makes sure that we do not access the standard stream tasks before they are initialized. // For the same reason it is intended that these tasks (as closures) are modified (i.e. initialized). // We need to take this cumbersome way because it is not possible to access the standard streams before the process // is started. If on the other hand the Exited event is raised before the tasks are initialized, we need to make // sure that this method waits until the tasks are initialized before they are accessed. // ReSharper disable PossibleNullReferenceException // ReSharper disable AccessToModifiedClosure StandardOutput = standardOutputTask.Result, StandardError = standardErrorTask.Result // ReSharper restore AccessToModifiedClosure // ReSharper restore PossibleNullReferenceException }); } catch (Exception e) { debugLogger.Error("AsyncImpersonationProcess ({0}): Exception while executing the Exited handler", e, executable); tcs.TrySetException(e); } finally { process.Dispose(); } }; using (var tokenWrapper = idWrapper.TokenWrapper) if (!process.StartAsUser(tokenWrapper.Token)) { debugLogger.Error("AsyncImpersonationProcess ({0}): Could not start process", executable); standardStreamTasksReady.Dispose(); return Task.FromResult(new ProcessExecutionResult { ExitCode = int.MinValue }); } try { // This call may throw an exception if the process has already exited when we get here. // In that case the Exited event has already set tcs to RanToCompletion state so that // the TrySetException call below does not change the state of tcs anymore. This is correct // as it doesn't make sense to change the priority of the process if it is already finished. // Any other "real" error sets the state of tcs to Faulted below. process.PriorityClass = priorityClass; } catch (Exception e) { debugLogger.Error("AsyncImpersonationProcess ({0}): Exception while setting the PriorityClass", e, executable); tcs.TrySetException(e); } standardOutputTask = process.StandardOutput.ReadToEndAsync(); standardErrorTask = process.StandardError.ReadToEndAsync(); standardStreamTasksReady.Set(); // Here we take care of the maximum time to wait for the process if such was requested. if (maxWaitMs != ProcessUtils.INFINITE) Task.Delay(maxWaitMs).ContinueWith(task => { try { // We only kill the process if the state of tcs was not set to Faulted or // RanToCompletion before. if (tcs.TrySetCanceled()) { process.Kill(); debugLogger.Warn("AsyncImpersonationProcess ({0}): Process was killed because maxWaitMs was reached.", executable); } } // An exception is thrown in process.Kill() when the external process exits // while we set tcs to canceled. In that case there is nothing to do anymore. // This is not an error. In case of other errors that may happen, we log it anyways catch (Exception e) { debugLogger.Error("AsyncImpersonationProcess ({0}): Exception while trying to kill the process", e, executable); } }); return tcs.Task; }
/// <summary> /// Ensures the namedpipe singleton server is running and waits for a client connection. /// This is a blocking call that returns after the client connection ends. /// This method supports PowerShell running in "NamedPipeServerMode", which is used for /// PowerShell Direct Windows Server Container connection and management. /// </summary> /// <param name="configurationName">name of the configuration to use</param> internal static void RunServerMode(string configurationName) { IPCNamedPipeServerEnabled = true; CreateIPCNamedPipeServerSingleton(); if (IPCNamedPipeServer == null) { throw new RuntimeException(RemotingErrorIdStrings.NamedPipeServerCannotStart); } IPCNamedPipeServer.ConfigurationName = configurationName; ManualResetEventSlim clientConnectionEnded = new ManualResetEventSlim(false); IPCNamedPipeServer.ListenerEnded -= OnIPCNamedPipeServerEnded; IPCNamedPipeServer.ListenerEnded += (sender, e) => { clientConnectionEnded.Set(); }; // Wait for server to service a single client connection. clientConnectionEnded.Wait(); clientConnectionEnded.Dispose(); IPCNamedPipeServerEnabled = false; }
public void TestBrowser() { #if __ANDROID__ if(global::Android.OS.Build.VERSION.SdkInt < global::Android.OS.BuildVersionCodes.JellyBean) { Assert.Inconclusive("PeerToPeer requires API level 16, but found {0}", global::Android.OS.Build.VERSION.Sdk); } #endif Log.Domains.All.Level = Log.LogLevel.None; Log.Domains.Discovery.Level = Log.LogLevel.Debug; //Use a short timeout to speed up the test since it is performed locally //Android will get stuck in DNSProcessResult which hangs indefinitely if //no results are found (Which will happen if registration is aborted between //the resolve reply and query record steps) ServiceParams.Timeout = TimeSpan.FromSeconds(3); var mre1 = new ManualResetEventSlim(); var mre2 = new ManualResetEventSlim(); CouchbaseLiteServiceBrowser browser = new CouchbaseLiteServiceBrowser(new ServiceBrowser()); browser.ServiceResolved += (sender, e) => { Log.To.Discovery.I(TAG, "Discovered service: {0}", e.Service.Name); if(e.Service.Name == TAG) { mre1.Set(); } }; browser.ServiceRemoved += (o, args) => { Log.To.Discovery.I(TAG, "Service destroyed: {0}", args.Service.Name); if(args.Service.Name == TAG) { mre2.Set(); } }; browser.Start(); CouchbaseLiteServiceBroadcaster broadcaster = new CouchbaseLiteServiceBroadcaster(new RegisterService(), 59840); broadcaster.Name = TAG; broadcaster.Start(); Assert.IsTrue(mre1.Wait(TimeSpan.FromSeconds(10))); //FIXME.JHB: Why does Linux hate this part sporadically? broadcaster.Dispose(); var success = mre2.Wait(TimeSpan.FromSeconds(10)); browser.Dispose(); Assert.IsTrue(success); mre1.Dispose(); mre2.Dispose(); }
// Tests timeout on an event that is never set. private static bool RunManualResetEventSlimTest2_TimeoutWait() { TestHarness.TestLog("* RunManualResetEventSlimTest2_TimeoutWait()"); ManualResetEventSlim ev = new ManualResetEventSlim(false); if (ev.Wait(0)) { TestHarness.TestLog(" > ev.Wait(0) returned true -- event isn't set ({0})", ev.IsSet); return false; } if (ev.Wait(100)) { TestHarness.TestLog(" > ev.Wait(100) returned true -- event isn't set ({0})", ev.IsSet); return false; } if (ev.Wait(TimeSpan.FromMilliseconds(100))) { TestHarness.TestLog(" > ev.Wait(0) returned true -- event isn't set ({0})", ev.IsSet); return false; } ev.Dispose(); return true; }
private static bool RunManualResetEventSlimTest5_Dispose() { bool passed = true; TestHarness.TestLog("* RunManualResetEventSlimTest5_Dispose()"); ManualResetEventSlim mres = new ManualResetEventSlim(false); mres.Dispose(); passed &= TestHarnessAssert.EnsureExceptionThrown( () => mres.Reset(), typeof(ObjectDisposedException), "The object has been disposed, should throw ObjectDisposedException."); passed &= TestHarnessAssert.EnsureExceptionThrown( () => mres.Wait(0), typeof(ObjectDisposedException), "The object has been disposed, should throw ObjectDisposedException."); passed &= TestHarnessAssert.EnsureExceptionThrown( () => { WaitHandle handle = mres.WaitHandle; }, typeof(ObjectDisposedException), "The object has been disposed, should throw ObjectDisposedException."); mres = new ManualResetEventSlim(false); ; ManualResetEvent mre = (ManualResetEvent)mres.WaitHandle; mres.Dispose(); passed &= TestHarnessAssert.EnsureExceptionThrown( () => mre.WaitOne(0, false), typeof(ObjectDisposedException), "The underlying event object has been disposed, should throw ObjectDisposedException."); return passed; }
public bool RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID, InventoryItemBase item) { AssetXferUploader uploader = GetTransactionUploader(transactionID); if (uploader == null) { m_log.WarnFormat("[ASSET TRANSACTIONS]: Transaction {0} NOT FOUND (duplicate removed?) for inventory item update {1}", transactionID, item.Name); return false; } CachedUserInfo userInfo = Manager.MyScene.CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); if (userInfo == null) { m_log.WarnFormat("[ASSET TRANSACTIONS]: Could not find user {0} for transaction {1} for inventory update {2}", remoteClient.AgentId, transactionID, item.Name); return false; } // This may complete now if upload complete, or later when the upload completes. uploader.TriggerWhenUploadComplete(delegate(AssetBase asset) { // This upload transaction is complete. XferUploaders.Remove(transactionID); UUID assetID = UUID.Combine(transactionID, remoteClient.SecureSessionId); if (asset == null || asset.FullID != assetID) { m_log.ErrorFormat("[ASSETS]: RequestUpdateInventoryItem wrong asset ID or not found {0}", asset == null ? "null" : asset.FullID.ToString()); return; } // Assets never get updated, new ones get created UUID oldID = asset.FullID; asset.FullID = UUID.Random(); asset.Name = item.Name; asset.Description = item.Description; asset.Type = (sbyte)item.AssetType; try { m_log.DebugFormat("[ASSETS]: RequestUpdateInventoryItem for transaction {0}, new asset {1} -> {2}", transactionID, oldID, asset.FullID); Manager.MyScene.CommsManager.AssetCache.AddAsset(asset, AssetRequestInfo.GenericNetRequest()); } catch (AssetServerException e) { remoteClient.SendAgentAlertMessage("Unable to upload asset. Please try again later.", false); m_log.ErrorFormat("[ASSET TRANSACTIONS] Creation of asset failed {0}", e); return; } item.AssetID = asset.FullID; //wait for completion of the write to avoid reversion ManualResetEventSlim waitEvent = new ManualResetEventSlim(); remoteClient.HandleWithInventoryWriteThread(() => { // Update the asset ID userInfo.UpdateItem(item); waitEvent.Set(); }); waitEvent.Wait(); waitEvent.Dispose(); }); return true; // userInfo item was updated }
/// <exception cref="OutOfMemoryException">Failed to allocate the event object</exception> private ManualResetEventSlim GetOrCreateReaderEvent() { ManualResetEventSlim currentEvent = _readerEvent; if (currentEvent != null) { return currentEvent; } currentEvent = new ManualResetEventSlim(false, 0); ManualResetEventSlim previousEvent = Interlocked.CompareExchange(ref _readerEvent, currentEvent, null); if (previousEvent == null) { return currentEvent; } currentEvent.Dispose(); return previousEvent; }
private void StartCallbackQueueConsumer(AmqpChannelPooler pool) { //TODO: Double-checked locking -- make this better if (callbackConsumer == null || !isInConsumerLoop || !pool.Connection.IsOpen) { lock (restartConsumerSync) { if (!(callbackConsumer == null || !isInConsumerLoop || !pool.Connection.IsOpen)) return; //This method waits on this signal to make sure the callbackprocessor thread either started successfully or failed. ManualResetEventSlim consumerSignal = new ManualResetEventSlim(false); Exception consumerSignalException = null; Thread callBackProcessor = new Thread(p => { ConcurrentQueueingConsumer consumer = null; try { //Start consumer AmqpModelContainer channelContainer = null; try { channelContainer = pool.GetModel(ChannelFlags.Consumer); IModel channel = channelContainer.Channel; if (clientSettings.DisableDirectReplies || !channelContainer.IsDirectReplyToCapable) { DeclareIndirectReplyToQueue(channel, indirectReplyToQueueName); } consumer = new ConcurrentQueueingConsumer(channel, responseQueued); //Set consumerCancelled to true on consumer cancellation consumerCancelled = false; consumer.ConsumerCancelled += (s, e) => { consumerCancelled = true; }; channel.BasicQos(0, (ushort)clientSettings.PrefetchCount, false); //Start consumer: string replyToQueueName; if (clientSettings.DisableDirectReplies || !channelContainer.IsDirectReplyToCapable) { channel.BasicConsume(indirectReplyToQueueName, clientSettings.AckBehavior == ClientAckBehavior.Automatic, consumer); replyToQueueName = indirectReplyToQueueName; } else { //TODO: REMOVE LATER: This clause is never called because in this case the DirectReplyToRPCStrategy would be in use //instead of this strategy. //throw an InvalidOperationException instead channel.BasicConsume(RPCStrategyHelpers.DIRECT_REPLY_TO_QUEUENAME_ARG, true, consumer); //Discover direct reply to queue name replyToQueueName = DiscoverDirectReplyToQueueName(channel, indirectReplyToQueueName); } //Set callbackConsumer to consumer callbackQueueName = replyToQueueName; callbackConsumer = consumer; //Notify outer thread that channel has started consumption consumerSignal.Set(); BasicDeliverEventArgs evt; ExpectedResponse expected; isInConsumerLoop = true; while (true) { try { evt = DequeueCallbackQueue(); } catch { //TODO: Log this exception except it's ObjectDisposedException or OperationCancelledException throw; } expected = null; if (!String.IsNullOrEmpty(evt.BasicProperties.CorrelationId) && expectedResponses.TryRemove(evt.BasicProperties.CorrelationId, out expected)) { RPCStrategyHelpers.ReadAndSignalDelivery(expected, evt); } //Acknowledge receipt: //In ClientBehavior.Automatic mode //Client acks all received messages, even if it wasn't the expected one or even if it wasn't expecting anything. //This prevents a situation where crap messages are sent to the client but the good expected message is stuck behind the //crap ones and isn't delivered because the crap ones in front of the queue aren't acked and crap messages exceed prefetchCount. //In ClientAckBehavior.ValidResponses mode (and Direct Reply to is not in effect): //Client only acks expected messages if they could be deserialized //If not, they are rejected. if ((clientSettings.DisableDirectReplies || !channelContainer.IsDirectReplyToCapable) && clientSettings.AckBehavior == ClientAckBehavior.ValidResponses) { if (expected != null && expected.DeserializationException != null) { channel.BasicAck(evt.DeliveryTag, false); } else { channel.BasicReject(evt.DeliveryTag, false); } } //Exit loop if consumer is cancelled. if (consumerCancelled) { break; } } } finally { isInConsumerLoop = false; pool.SetRecycle(); if (channelContainer != null) { if (consumer != null && !consumerCancelled) { try { channelContainer.Channel.BasicCancel(consumer.ConsumerTag); } catch { } } channelContainer.Close(); } } } catch (Exception ex) { //TODO: Log error (Except it's object disposed exception) //Set Exception object which will be throw by signal waiter consumerSignalException = ex; //Notify outer thread to move on, in case it's still waiting try { consumerSignal.Set(); } catch { } } finally { if (pool != null) { pool.Dispose(); } } }); //Start Thread callBackProcessor.Name = "RestBus RabbitMQ Client Callback Queue Consumer"; callBackProcessor.IsBackground = true; callBackProcessor.Start(); //Wait for Thread to start consuming messages consumerSignal.Wait(); consumerSignal.Dispose(); //Examine exception if it were set and rethrow it Thread.MemoryBarrier(); //Ensure we have the non-cached version of consumerSignalException if (consumerSignalException != null) { throw consumerSignalException; } //No more code from this point in this method } } }
/// <summary> /// Requests that an asset be removed from storage and does not return until the operation completes /// </summary> /// <param name="assetID"></param> /// <returns></returns> public void PurgeAssetSync(OpenMetaverse.UUID assetID) { ManualResetEventSlim syncEvent = new ManualResetEventSlim(); Exception thrown = null; _threadPool.QueueWorkItem(() => { CloudFilesAssetWorker worker = null; try { worker = _asyncAssetWorkers.LeaseObject(); worker.PurgeAsset(assetID); } catch (Exception e) { thrown = e; } finally { if (worker != null) _asyncAssetWorkers.ReturnObject(worker); } syncEvent.Set(); }); if (syncEvent.Wait(ASSET_WAIT_TIMEOUT)) { syncEvent.Dispose(); } else { m_log.WarnFormat("[InWorldz.Stratus]: Timout waiting for synchronous asset purge for {0}", assetID); } if (thrown != null) throw new AssetServerException(thrown.Message, thrown); }
public void Dispose() { CanEnter.Dispose(); }