private void UnlockFile(long offset, long count) { #if !SILICONSTUDIO_PLATFORM_WINDOWS_RUNTIME && !SILICONSTUDIO_PLATFORM_MONO_MOBILE var fileStream = stream as FileStream; if (fileStream == null) { return; } #if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP var countLow = (uint)count; var countHigh = (uint)(count >> 32); var overlapped = new NativeLockFile.OVERLAPPED() { internalLow = 0, internalHigh = 0, offsetLow = (uint)offset, offsetHigh = (uint)(offset >> 32), hEvent = IntPtr.Zero, }; if (!NativeLockFile.UnlockFileEx(fileStream.SafeFileHandle, 0, countLow, countHigh, ref overlapped)) { throw new IOException("Couldn't unlock file."); } #else fileStream.Unlock(offset, count); #endif #endif }
private void LockFile(long offset, long count, bool exclusive) { #if !SILICONSTUDIO_PLATFORM_WINDOWS_RUNTIME var fileStream = stream as FileStream; if (fileStream == null) { return; } #if SILICONSTUDIO_PLATFORM_ANDROID // Android does not support large file and thus is limited to files // whose sizes are less than 2GB. // We substract the offset to not go beyond the 2GB limit. count = (count + offset > int.MaxValue) ? int.MaxValue - offset: count; #endif #if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP var countLow = (uint)count; var countHigh = (uint)(count >> 32); var overlapped = new NativeLockFile.OVERLAPPED() { internalLow = 0, internalHigh = 0, offsetLow = (uint)offset, offsetHigh = (uint)(offset >> 32), hEvent = IntPtr.Zero, }; if (!NativeLockFile.LockFileEx(fileStream.SafeFileHandle, exclusive ? NativeLockFile.LOCKFILE_EXCLUSIVE_LOCK : 0, 0, countLow, countHigh, ref overlapped)) { throw new IOException("Couldn't lock file."); } #elif SILICONSTUDIO_RUNTIME_CORECLR // There is no implementation of FileStream.Lock on CoreCLR #else bool tryAgain; do { tryAgain = false; try { fileStream.Lock(offset, count); } catch (IOException) { tryAgain = true; } } while (tryAgain); #endif #endif }
private void LockFile(long offset, long count, bool exclusive) { #if !SILICONSTUDIO_PLATFORM_WINDOWS_RUNTIME && !SILICONSTUDIO_PLATFORM_MONO_MOBILE var fileStream = stream as FileStream; if (fileStream == null) { return; } #if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP var countLow = (uint)count; var countHigh = (uint)(count >> 32); var overlapped = new NativeLockFile.OVERLAPPED() { internalLow = 0, internalHigh = 0, offsetLow = (uint)offset, offsetHigh = (uint)(offset >> 32), hEvent = IntPtr.Zero, }; if (!NativeLockFile.LockFileEx(fileStream.SafeFileHandle, exclusive ? NativeLockFile.LOCKFILE_EXCLUSIVE_LOCK : 0, 0, countLow, countHigh, ref overlapped)) { throw new IOException("Couldn't lock file."); } #elif SILICONSTUDIO_RUNTIME_CORECLR // There is no implementation of FileStream.Lock on CoreCLR #else bool tryAgain; do { tryAgain = false; try { fileStream.Lock(offset, count); } catch (IOException) { tryAgain = true; } } while (tryAgain); #endif #endif }
/// <summary> /// Releases the file lock. /// </summary> public void Dispose() { if (lockFile != null) { var overlapped = new NativeLockFile.OVERLAPPED(); NativeLockFile.UnlockFileEx(lockFile.SafeFileHandle, 0, uint.MaxValue, uint.MaxValue, ref overlapped); lockFile.Dispose(); // Try to delete the file // Ideally we would use FileOptions.DeleteOnClose, but it doesn't seem to work well with FileShare for second instance try { File.Delete(lockFile.Name); } catch (Exception) { } lockFile = null; } }
private void UnlockFile(long offset, long count) { #if !SILICONSTUDIO_PLATFORM_WINDOWS_RUNTIME var fileStream = stream as FileStream; if (fileStream == null) { return; } #if SILICONSTUDIO_PLATFORM_ANDROID // See comment on `LockFile`. count = (count + offset > int.MaxValue) ? int.MaxValue - offset: count; #endif #if SILICONSTUDIO_PLATFORM_WINDOWS_DESKTOP var countLow = (uint)count; var countHigh = (uint)(count >> 32); var overlapped = new NativeLockFile.OVERLAPPED() { internalLow = 0, internalHigh = 0, offsetLow = (uint)offset, offsetHigh = (uint)(offset >> 32), hEvent = IntPtr.Zero, }; if (!NativeLockFile.UnlockFileEx(fileStream.SafeFileHandle, 0, countLow, countHigh, ref overlapped)) { throw new IOException("Couldn't unlock file."); } #elif SILICONSTUDIO_RUNTIME_CORECLR // There is no implementation of FileStream.Unlock on CoreCLR #else fileStream.Unlock(offset, count); #endif #endif }
/// <summary> /// Tries to take ownership of the file lock within a given delay. /// </summary> /// <param name="name">A unique name identifying the file lock.</param> /// <param name="millisecondsTimeout">The maximum delay to wait before returning, in milliseconds.</param> /// <returns>A new instance of <see cref="FileLock"/> if the ownership could be taken, <c>null</c> otherwise.</returns> /// <remarks> /// The returned <see cref="FileLock"/> must be disposed to release the file lock. /// Calling this method with 0 for <see paramref="millisecondsTimeout"/> is equivalent to call <see cref="TryLock"/>. /// Calling this method with a negative value for <see paramref="millisecondsTimeout"/> is equivalent to call <see cref="Wait(string)"/>. /// </remarks> public static FileLock Wait(string name, int millisecondsTimeout) { var fileLock = BuildFileLock(name); try { if (millisecondsTimeout != 0 && millisecondsTimeout != -1) throw new NotImplementedException("GlobalMutex.Wait() is implemented only for millisecondsTimeout 0 or -1"); var overlapped = new NativeLockFile.OVERLAPPED(); bool hasHandle = NativeLockFile.LockFileEx(fileLock.SafeFileHandle, NativeLockFile.LOCKFILE_EXCLUSIVE_LOCK | (millisecondsTimeout == 0 ? NativeLockFile.LOCKFILE_FAIL_IMMEDIATELY : 0), 0, uint.MaxValue, uint.MaxValue, ref overlapped); return hasHandle == false ? null : new FileLock(fileLock); } catch (AbandonedMutexException) { return new FileLock(fileLock); } }