//NB: initially, you could have multiple blooms, if they were different projects. //however, then we switched to the embedded http image server, which can't share //a port. So we could fix that (get different ports), but for now, I'm just going //to lock it down to a single bloom private static bool GrabTokenForThisProject(string pathToProject) { //ok, here's how this complex method works... //First, we try to get the mutex quickly and quitely. //If that fails, we put up a dialog and wait a number of seconds, //while we wait for the mutex to come free. string mutexId = "bloom"; // string mutexId = pathToProject; // mutexId = mutexId.Replace(Path.DirectorySeparatorChar, '-'); // mutexId = mutexId.Replace(Path.VolumeSeparatorChar, '-'); bool mutexAcquired = false; try { _oneInstancePerProjectMutex = Mutex.OpenExisting(mutexId); mutexAcquired = _oneInstancePerProjectMutex.WaitOne(TimeSpan.FromMilliseconds(1 * 1000), false); } catch (WaitHandleCannotBeOpenedException e)//doesn't exist, we're the first. { _oneInstancePerProjectMutex = new Mutex(true, mutexId, out mutexAcquired); mutexAcquired = true; } catch (AbandonedMutexException e) { //that's ok, we'll get it below } using (var dlg = new SimpleMessageDialog("Waiting for other Bloom to finish...")) { dlg.TopMost = true; dlg.Show(); try { _oneInstancePerProjectMutex = Mutex.OpenExisting(mutexId); mutexAcquired = _oneInstancePerProjectMutex.WaitOne(TimeSpan.FromMilliseconds(10 * 1000), false); } catch (AbandonedMutexException e) { _oneInstancePerProjectMutex = new Mutex(true, mutexId, out mutexAcquired); mutexAcquired = true; } catch (Exception e) { ErrorReport.NotifyUserOfProblem(e, "There was a problem starting Bloom which might require that you restart your computer."); } } if (!mutexAcquired) // cannot acquire? { _oneInstancePerProjectMutex = null; ErrorReport.NotifyUserOfProblem("Another copy of Bloom is already open with " + pathToProject + ". If you cannot find that Bloom, restart your computer."); return false; } return true; }