public Result CheckSimulatedAccessFailureEvent(SimulatingDeviceTargetOperation operation) { if (_isEventSet) { return(Result.Success); } using ScopedLock <SdkRecursiveMutex> lk = ScopedLock.Lock(ref _mutex); if ((_simulatedOperation & operation) == 0) { return(Result.Success); } Result result = GetCorrespondingResult(_simulatedFailureType); if (result.IsFailure() && _failureResult.IsFailure()) { result = _failureResult; } if (_simulatedFailureType == SimulatingDeviceAccessFailureEventType.AccessTimeoutFailure) { SimulateTimeout(); } if (!_isRecurringEvent) { ClearDeviceEvent(); } return(result); }
public void Register(ReferenceCountedDisposable <DirectorySaveDataFileSystem> fileSystem) { if (_maxCachedFileSystemCount <= 0) { return; } Assert.SdkRequiresGreaterEqual(_nextCacheIndex, 0); Assert.SdkRequiresGreater(_maxCachedFileSystemCount, _nextCacheIndex); if (fileSystem.Target.GetSaveDataSpaceId() == SaveDataSpaceId.SdSystem) { return; } Result rc = fileSystem.Target.Rollback(); if (rc.IsFailure()) { return; } using ScopedLock <SdkRecursiveMutexType> scopedLock = ScopedLock.Lock(ref _mutex); _cachedFileSystems[_nextCacheIndex].Register(fileSystem.AddReference <IFileSystem>(), fileSystem.Target.GetSaveDataSpaceId(), fileSystem.Target.GetSaveDataId()); _nextCacheIndex = (_nextCacheIndex + 1) % _maxCachedFileSystemCount; }
public void SetDetectionSimulationMode(SimulatingDeviceDetectionMode mode) { using ScopedLock <SdkRecursiveMutex> lk = ScopedLock.Lock(ref _mutex); _isDetectionSimulationEnabled = mode != SimulatingDeviceDetectionMode.NoSimulation; _detectionSimulationMode = mode; }
protected virtual void Dispose(bool disposing) { if (!disposing) { return; } using (ScopedLock.Lock(ref _openListLock)) { Abort.DoAbortUnless(_openFiles.Count == 0, ResultFs.FileNotClosed.Value, "All files must be closed before unmounting."); Abort.DoAbortUnless(_openDirectories.Count == 0, ResultFs.DirectoryNotClosed.Value, "All directories must be closed before unmounting."); if (_isPathCacheAttached) { throw new NotImplementedException(); } } _saveDataAttributeGetter?.Dispose(); _saveDataAttributeGetter = null; _mountNameGenerator?.Dispose(); _mountNameGenerator = null; _fileSystem?.Dispose(); _fileSystem = null; }
public void SetCurrentPosixTimeWithTimeDifference(long currentTime, int timeDifference) { using ScopedLock <SdkMutexType> lk = ScopedLock.Lock(ref _mutex); _basePosixTime = currentTime - GetSystemSeconds(); _timeDifference = timeDifference; }
public void ClearDeviceEvent() { using ScopedLock <SdkRecursiveMutex> lk = ScopedLock.Lock(ref _mutex); _isEventSet = false; _simulatedFailureType = SimulatingDeviceAccessFailureEventType.None; _simulatedOperation = SimulatingDeviceTargetOperation.None; _failureResult = Result.Success; _isRecurringEvent = false; }
public Result Register(ReferenceCountedDisposable <ISaveDataExtraDataAccessor> accessor, SaveDataSpaceId spaceId, ulong saveDataId) { var cache = new Cache(accessor, spaceId, saveDataId); using ScopedLock <SdkRecursiveMutexType> scopedLock = ScopedLock.Lock(ref _mutex); _accessorList.AddLast(cache); return(Result.Success); }
public Result Mount(FileSystemAccessor fileSystem) { using ScopedLock <SdkMutexType> lk = ScopedLock.Lock(ref _mutex); if (!CanAcceptMountName(fileSystem.GetName())) { return(ResultFs.MountNameAlreadyExists.Log()); } _fileSystemList.AddLast(fileSystem); return(Result.Success); }
private Result GetLocationResolver(out LocationResolver resolver, StorageId storageId) { UnsafeHelpers.SkipParamInit(out resolver); if (!IsValidStorageId(storageId)) { return(ResultLr.LocationResolverNotFound.Log()); } using ScopedLock <SdkMutexType> lk = ScopedLock.Lock(ref _mutex); int index = GetResolverIndexFromStorageId(storageId); ref LocationResolver lr = ref _resolvers[index];
public void Unregister(SaveDataSpaceId spaceId, ulong saveDataId) { Assert.SdkRequiresGreaterEqual(_maxCachedFileSystemCount, 0); using ScopedLock <SdkRecursiveMutexType> scopedLock = ScopedLock.Lock(ref _mutex); for (int i = 0; i < _maxCachedFileSystemCount; i++) { if (_cachedFileSystems[i].IsCached(spaceId, saveDataId)) { _cachedFileSystems[i].Unregister(); } } }
public void Dispose() { using ScopedLock <SdkMutexType> scopedLock = ScopedLock.Lock(ref Globals.Mutex); LinkedListNode <Entry> currentEntry = _entryList.First; while (currentEntry is not null) { ref Entry entry = ref currentEntry.ValueRef; _entryList.Remove(currentEntry); entry.Dispose(); currentEntry = _entryList.First; }
/// <summary> /// Defines a new runtime type. /// </summary> /// <param name="attributes">The custom type attributes.</param> /// <param name="baseClass">The base class.</param> /// <param name="typeBuilder">The type builder.</param> /// <returns>The acquired scoped lock.</returns> private ScopedLock DefineRuntimeType( TypeAttributes attributes, Type baseClass, out TypeBuilder typeBuilder) { var scopedLock = new ScopedLock(this); typeBuilder = moduleBuilder.DefineType( CustomTypeName + typeBuilderIdx++, attributes, baseClass); return(scopedLock); }
public Result Commit() { using (ScopedLock.Lock(ref _openListLock)) { DumpUnclosedAccessorList(OpenMode.Write, 0); if (HasOpenWriteModeFiles(_openFiles)) { return(ResultFs.WriteModeFileNotClosed.Log()); } } return(_fileSystem.Commit()); }
public void SetDeviceEvent(SimulatingDeviceTargetOperation operation, SimulatingDeviceAccessFailureEventType failureType, Result failureResult, bool isRecurringEvent) { using ScopedLock <SdkRecursiveMutex> lk = ScopedLock.Lock(ref _mutex); if (failureResult.IsFailure()) { _failureResult = failureResult; } _isEventSet = true; _simulatedFailureType = failureType; _simulatedOperation = operation; _isRecurringEvent = isRecurringEvent; }
public Result OpenFile(out FileAccessor file, U8Span path, OpenMode mode) { UnsafeHelpers.SkipParamInit(out file); Result rc = CheckPath(new U8Span(_mountName.Name), path); if (rc.IsFailure()) { return(rc); } IFile iFile = null; try { rc = _fileSystem.OpenFile(out iFile, path, mode); if (rc.IsFailure()) { return(rc); } var fileAccessor = new FileAccessor(FsClient, ref iFile, this, mode); using (ScopedLock.Lock(ref _openListLock)) { _openFiles.AddLast(fileAccessor); } if (_isPathCacheAttached) { if (mode.HasFlag(OpenMode.AllowAppend)) { throw new NotImplementedException(); } else { throw new NotImplementedException(); } } file = Shared.Move(ref fileAccessor); return(Result.Success); } finally { iFile?.Dispose(); } }
public static FaultRule[] DeserializeRules(string fileName, Mutex mutex) { BinaryFormatter formatter = new BinaryFormatter(); using (ScopedLock scope = new ScopedLock(mutex)) { using (FileStream stream = File.Open(fileName, FileMode.Open)) { // Use assembly locations recorded to handle assembly resolvation Dictionary <string, string> locations = (Dictionary <string, string>)formatter.Deserialize(stream); resolver.AddAssemblyLocations(locations); return((FaultRule[])formatter.Deserialize(stream)); } } }
public Result GetCache(out ReferenceCountedDisposable <ISaveDataExtraDataAccessor> accessor, SaveDataSpaceId spaceId, ulong saveDataId) { UnsafeHelpers.SkipParamInit(out accessor); using ScopedLock <SdkRecursiveMutexType> scopedLock = ScopedLock.Lock(ref _mutex); LinkedListNode <Cache> currentNode = _accessorList.First; while (true) { if (currentNode is null) { return(ResultFs.TargetNotFound.Log()); } if (currentNode.ValueRef.Contains(spaceId, saveDataId)) { break; } currentNode = currentNode.Next; } ReferenceCountedDisposable <ISaveDataExtraDataAccessor> tempAccessor = null; try { tempAccessor = currentNode.ValueRef.Lock(); // Return early if the accessor was already disposed if (tempAccessor is null) { // Note: Nintendo doesn't remove the accessor from the list in this case _accessorList.Remove(currentNode); return(ResultFs.TargetNotFound.Log()); } accessor = SaveDataExtraDataResultConvertAccessor.CreateShared(ref tempAccessor); return(Result.Success); } finally { tempAccessor?.Dispose(); } }
/// <summary> /// Defines a new runtime method. /// </summary> /// <param name="returnType">The return type.</param> /// <param name="parameterTypes">All parameter types.</param> /// <param name="methodEmitter">The method emitter.</param> /// <returns>The acquired scoped lock.</returns> public ScopedLock DefineRuntimeMethod( Type returnType, Type[] parameterTypes, out MethodEmitter methodEmitter) { var scopedLock = new ScopedLock(this); methodEmitter = new MethodEmitter( new DynamicMethod( LauncherMethodName, returnType, parameterTypes, moduleBuilder, true)); return(scopedLock); }
public Result Initialize(int maxCacheCount) { Assert.SdkRequiresGreaterEqual(maxCacheCount, 0); using ScopedLock <SdkRecursiveMutexType> scopedLock = ScopedLock.Lock(ref _mutex); Assert.SdkAssert(_cachedFileSystems is null); _maxCachedFileSystemCount = maxCacheCount; if (maxCacheCount <= 0) { return(Result.Success); } // Note: The original checks for overflow here _cachedFileSystems = new Cache[maxCacheCount]; return(Result.Success); }
public Result Find(out FileSystemAccessor accessor, U8Span name) { UnsafeHelpers.SkipParamInit(out accessor); using ScopedLock <SdkMutexType> lk = ScopedLock.Lock(ref _mutex); for (LinkedListNode <FileSystemAccessor> currentNode = _fileSystemList.First; currentNode is not null; currentNode = currentNode.Next) { if (!Matches(currentNode.Value, name)) { continue; } accessor = currentNode.Value; return(Result.Success); } return(ResultFs.NotMounted.Log()); }
public void UnsetOpenType(OpenType type) { using ScopedLock <SdkMutexType> scopedLock = ScopedLock.Lock(ref Globals.Mutex); if (type == OpenType.Normal) { _isNormalStorageOpened = false; } else if (type == OpenType.Internal) { _isInternalStorageOpened = false; } if (!IsOpened()) { Globals.SaveDataFileStorageHolder.Unregister(_spaceId, _saveDataId); } }
public bool GetCache(out ReferenceCountedDisposable <IFileSystem> fileSystem, SaveDataSpaceId spaceId, ulong saveDataId) { Assert.SdkRequiresGreaterEqual(_maxCachedFileSystemCount, 0); using ScopedLock <SdkRecursiveMutexType> scopedLock = ScopedLock.Lock(ref _mutex); for (int i = 0; i < _maxCachedFileSystemCount; i++) { if (_cachedFileSystems[i].IsCached(spaceId, saveDataId)) { fileSystem = _cachedFileSystems[i].Move(); return(true); } } fileSystem = default; return(false); }
public static void SerializeRules(string fileName, FaultRule[] rules, Mutex mutex) { if (rules == null) { throw new FaultInjectionException(ApiErrorMessages.FaultRulesNullInSerialization); } // Recording locations for all assemblies loaded in AppDomain running test code // We need these information to find types while deserialization Dictionary <string, string> locations = new Dictionary <string, string>(); foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies()) { try { locations[assembly.FullName] = assembly.Location; } catch (NotSupportedException) { // Swallow NotSupportedException for dynamic assemblies } } // Serialize fault rules into a temporary file BinaryFormatter formatter = new BinaryFormatter(); string tempFile = Path.Combine(Path.GetDirectoryName(fileName), Path.GetFileName(Path.GetTempFileName())); using (FileStream stream = File.Open(tempFile, FileMode.Create)) { formatter.Serialize(stream, locations); formatter.Serialize(stream, rules); } // Swap it to serialization file using (ScopedLock scope = new ScopedLock(mutex)) { File.Delete(fileName); File.Move(tempFile, fileName); } }
public void Unmount(U8Span name) { using ScopedLock <SdkMutexType> lk = ScopedLock.Lock(ref _mutex); LinkedListNode <FileSystemAccessor> currentNode; for (currentNode = _fileSystemList.First; currentNode is not null; currentNode = currentNode.Next) { if (Matches(currentNode.Value, name)) { break; } } if (currentNode is null) { Abort.DoAbort(ResultFs.NotMounted.Log(), $"{name.ToString()} is not mounted."); } _fileSystemList.Remove(currentNode); currentNode.Value.Dispose(); }
public Result GetCurrentPosixTimeWithTimeDifference(out long currentTime, out int timeDifference) { UnsafeHelpers.SkipParamInit(out currentTime, out timeDifference); using ScopedLock <SdkMutexType> lk = ScopedLock.Lock(ref _mutex); if (_basePosixTime == 0) { return(ResultFs.NotInitialized.Log()); } if (!Unsafe.IsNullRef(ref currentTime)) { currentTime = _basePosixTime + GetSystemSeconds(); } if (!Unsafe.IsNullRef(ref timeDifference)) { timeDifference = _timeDifference; } return(Result.Success); }
public Result OpenDirectory(out DirectoryAccessor directory, U8Span path, OpenDirectoryMode mode) { UnsafeHelpers.SkipParamInit(out directory); Result rc = CheckPath(new U8Span(_mountName.Name), path); if (rc.IsFailure()) { return(rc); } IDirectory iDirectory = null; try { rc = _fileSystem.OpenDirectory(out iDirectory, path, mode); if (rc.IsFailure()) { return(rc); } var directoryAccessor = new DirectoryAccessor(ref iDirectory, this); using (ScopedLock.Lock(ref _openListLock)) { _openDirectories.AddLast(directoryAccessor); } directory = Shared.Move(ref directoryAccessor); return(Result.Success); } finally { iDirectory?.Dispose(); } }
public void Unregister(SaveDataSpaceId spaceId, ulong saveDataId) { using ScopedLock <SdkRecursiveMutexType> scopedLock = ScopedLock.Lock(ref _mutex); UnregisterImpl(spaceId, saveDataId); }
public void NotifyCloseFile(FileAccessor file) { using ScopedLock <SdkMutexType> lk = ScopedLock.Lock(ref _openListLock); Remove(_openFiles, file); }
public void NotifyCloseDirectory(DirectoryAccessor directory) { using ScopedLock <SdkMutexType> lk = ScopedLock.Lock(ref _openListLock); Remove(_openDirectories, directory); }