public void Lock_Reentrancy_DoesNotBlock() { using (var mutex = new GlobalMutex("test")) { mutex.Initialize(); using (mutex.Lock()) { using (mutex.Lock()) {} } } }
/// <summary> /// API to query the SLDR for an LDML file and save it locally in the SLDR cache and specified directories /// </summary> /// <param name="destinationPath">Destination path to save the requested LDML file</param> /// <param name="languageTag">Current IETF language tag</param> /// <param name="topLevelElements">List of top level element names to request. SLDR will always publish identity, so it doesn't need to be requested. /// If null, the entire LDML file will be requested.</param> /// <param name="filename">Saved filename</param> /// <returns>Enum status SldrStatus if file could be retrieved and the source</returns> public static SldrStatus GetLdmlFile(string destinationPath, string languageTag, IEnumerable <string> topLevelElements, out string filename) { CheckInitialized(); if (String.IsNullOrEmpty(destinationPath)) { throw new ArgumentException("destinationPath"); } if (!Directory.Exists(destinationPath)) { throw new DirectoryNotFoundException("destinationPath"); } if (String.IsNullOrEmpty(languageTag) || (!IetfLanguageTag.IsValid(languageTag))) { throw new ArgumentException("ietfLanguageTag"); } if (topLevelElements == null) { throw new ArgumentNullException("topLevelElements"); } string sldrLanguageTag = IetfLanguageTag.Canonicalize(languageTag); SldrLanguageTagInfo langTagInfo; if (LanguageTags.TryGet(sldrLanguageTag, out langTagInfo)) { sldrLanguageTag = langTagInfo.SldrLanguageTag; } string[] topLevelElementsArray = topLevelElements.ToArray(); using (_sldrCacheMutex.Lock()) { var status = SldrStatus.NotFound; CreateSldrCacheDirectory(); string sldrCacheFilePath; bool redirected; do { string revid, uid = "", tempString; if (destinationPath == SldrCachePath) { filename = string.Format("{0}.{1}", sldrLanguageTag, LdmlExtension); } else { filename = string.Format("{0}.{1}", languageTag, LdmlExtension); // Check if LDML file already exists in destination and read revid and uid if (!ReadSilIdentity(Path.Combine(destinationPath, filename), out tempString, out uid)) { uid = DefaultUserId; } } // If languageTag contains fonipa, don't bother trying to access the SLDR if (sldrLanguageTag.Contains(WellKnownSubtags.IpaVariant) || sldrLanguageTag.Contains(WellKnownSubtags.AudioScript)) { return(SldrStatus.NotFound); } sldrCacheFilePath = Path.Combine(SldrCachePath, !string.IsNullOrEmpty(uid) && uid != DefaultUserId ? string.Format("{0}-{1}.{2}", sldrLanguageTag, uid, LdmlExtension) : string.Format("{0}.{1}", sldrLanguageTag, LdmlExtension)); // Read revid from cache file ReadSilIdentity(sldrCacheFilePath, out revid, out tempString); // Concatenate parameters for url string string requestedElements = string.Empty; if (topLevelElementsArray.Length > 0) { requestedElements = string.Format("&inc[]={0}", string.Join("&inc[]=", topLevelElementsArray)); } string requestedUserId = !string.IsNullOrEmpty(uid) ? string.Format("&uid={0}", uid) : string.Empty; string requestedRevid = !string.IsNullOrEmpty(revid) ? string.Format("&revid={0}", revid) : string.Empty; string url = string.Format("{0}{1}?ext={2}&flatten=1{3}{4}{5}", SldrRepository, sldrLanguageTag, LdmlExtension, requestedElements, requestedUserId, requestedRevid); string tempFilePath = sldrCacheFilePath + "." + TmpExtension; // Using WebRequest instead of WebClient so we have access to disable AllowAutoRedirect var webRequest = (HttpWebRequest)WebRequest.Create(Uri.EscapeUriString(url)); webRequest.AllowAutoRedirect = false; webRequest.UserAgent = UserAgent; webRequest.Timeout = 10000; try { if (_offlineMode) { throw new WebException("Test mode: SLDR offline so accessing cache", WebExceptionStatus.ConnectFailure); } // Check the response header to see if the requested LDML file got redirected using (var webResponse = (HttpWebResponse)webRequest.GetResponse()) { if (webResponse.StatusCode == HttpStatusCode.NotModified) { // Report status that file is the most current from SLDR status = SldrStatus.FromSldr; redirected = false; } else if (webResponse.StatusCode == HttpStatusCode.MovedPermanently) { // Extract ietfLanguageTag from the response header var parsedresponse = HttpUtilityFromMono.ParseQueryString(webResponse.Headers["Location"]); sldrLanguageTag = parsedresponse.Get("ws_id").Split('?')[0]; redirected = true; } else { // Download the LDML file to a temp file in case the transfer gets interrupted using (Stream responseStream = webResponse.GetResponseStream()) using (var fs = new FileStream(tempFilePath, FileMode.OpenOrCreate, FileAccess.Write)) { var buff = new byte[102400]; int c; while ((c = responseStream.Read(buff, 0, buff.Length)) > 0) { fs.Write(buff, 0, c); fs.Flush(); } } status = SldrStatus.FromSldr; sldrCacheFilePath = MoveTmpToCache(tempFilePath, uid); redirected = false; } } } catch (WebException we) { // Return from 404 error var errorResponse = (HttpWebResponse)we.Response; if ((we.Status == WebExceptionStatus.ProtocolError) && (errorResponse.StatusCode == HttpStatusCode.NotFound)) { return(SldrStatus.NotFound); } string sldrCacheFilename; // Download failed so check SLDR cache if (!string.IsNullOrEmpty(uid) && (uid != DefaultUserId)) { sldrCacheFilename = string.Format("{0}-{1}.{2}", sldrLanguageTag, uid, LdmlExtension); } else { sldrCacheFilename = string.Format("{0}.{1}", sldrLanguageTag, LdmlExtension); } sldrCacheFilePath = Path.Combine(SldrCachePath, sldrCacheFilename); if (File.Exists(sldrCacheFilePath)) { status = SldrStatus.FromCache; } else { return(SldrStatus.UnableToConnectToSldr); } redirected = false; } finally { if (File.Exists(tempFilePath)) { File.Delete(tempFilePath); } } } while (redirected); if (destinationPath != SldrCachePath) { // Copy from Cache to destination (w/o uid in filename), overwriting whatever used to be there File.Copy(sldrCacheFilePath, Path.Combine(destinationPath, filename), true); } return(status); } }
protected override void ShutdownInternal() { if (m_commitLogMutex != null && m_commitLogMetadata != null) { CompleteAllCommits(); using (m_commitLogMutex.Lock()) { #if __MonoCS__ bool delete = false; #endif using (MemoryMappedViewStream stream = m_commitLogMetadata.CreateViewStream()) { CommitLogMetadata metadata; if (TryGetMetadata(stream, out metadata)) { if (metadata.Master == m_peerID) { // commit any unseen foreign changes List <ICmObjectSurrogate> foreignNewbies; List <ICmObjectSurrogate> foreignDirtballs; List <ICmObjectId> foreignGoners; if (GetUnseenForeignChanges(metadata, out foreignNewbies, out foreignDirtballs, out foreignGoners)) { var newObjects = new HashSet <ICmObjectOrSurrogate>(foreignNewbies); var editedObjects = new HashSet <ICmObjectOrSurrogate>(foreignDirtballs); var removedObjects = new HashSet <ICmObjectId>(foreignGoners); IEnumerable <CustomFieldInfo> fields; if (HaveAnythingToCommit(newObjects, editedObjects, removedObjects, out fields) && (StartupVersionNumber == ModelVersion)) { base.WriteCommitWork(new CommitWork(newObjects, editedObjects, removedObjects, fields)); } } // XML file is now totally up-to-date metadata.FileGeneration = metadata.CurrentGeneration; } RemovePeer(metadata, m_peerID); #if __MonoCS__ delete = metadata.Peers.Count == 0; #endif SaveMetadata(stream, metadata); } } base.UnlockProject(); m_commitLog.Dispose(); m_commitLog = null; m_commitLogMetadata.Dispose(); m_commitLogMetadata = null; #if __MonoCS__ if (delete) { File.Delete(Path.Combine(m_commitLogDir, CommitLogMetadataName)); File.Delete(Path.Combine(m_commitLogDir, CommitLogName)); m_commitLogMutex.Unlink(); } #endif } } if (m_commitLogMutex != null) { m_commitLogMutex.Dispose(); m_commitLogMutex = null; } if (CommitThread != null) { CommitThread.Stop(); CommitThread.Dispose(); CommitThread = null; } foreach (Process peerProcess in m_peerProcesses.Values) { peerProcess.Close(); } m_peerProcesses.Clear(); }