protected override Result DoSetSize(long size) { using UniqueLock <SdkMutexType> scopedLock = _baseStorage.Target.GetLock(); Result rc = AccessCheck(isWriteAccess: true); if (rc.IsFailure()) { return(rc); } return(_baseStorage.Target.SetSize(size)); }
protected override Result DoWrite(long offset, ReadOnlySpan <byte> source) { using UniqueLock <SdkMutexType> scopedLock = _baseStorage.Target.GetLock(); Result rc = AccessCheck(isWriteAccess: true); if (rc.IsFailure()) { return(rc); } return(_baseStorage.Target.Write(offset, source)); }
protected override Result DoRead(long offset, Span <byte> destination) { using UniqueLock <SdkMutexType> scopedLock = _baseStorage.Target.GetLock(); Result rc = AccessCheck(isWriteAccess: false); if (rc.IsFailure()) { return(rc); } return(_baseStorage.Target.Read(offset, destination)); }
protected override Result DoOperateRange(Span <byte> outBuffer, OperationId operationId, long offset, long size, ReadOnlySpan <byte> inBuffer) { using UniqueLock <SdkMutexType> scopedLock = _baseStorage.Target.GetLock(); Result rc = AccessCheck(isWriteAccess: true); if (rc.IsFailure()) { return(rc); } return(_baseStorage.Target.OperateRange(outBuffer, operationId, offset, size, inBuffer)); }
protected override Result DoGetSize(out long size) { Unsafe.SkipInit(out size); using UniqueLock <SdkMutexType> scopedLock = _baseStorage.Target.GetLock(); Result rc = AccessCheck(isWriteAccess: false); if (rc.IsFailure()) { return(rc); } return(_baseStorage.Target.GetSize(out size)); }
/// <summary> /// Opens a <see cref="SaveDataIndexerAccessor"/> for the specified save data space. /// </summary> /// <remarks> /// The returned <see cref="SaveDataIndexerAccessor"/> will have exclusive access to the requested indexer. /// The accessor must be disposed after use. /// </remarks> /// <param name="accessor">If the method returns successfully, contains the created accessor.</param> /// <param name="neededInit">If the method returns successfully, contains <see langword="true"/> /// if the indexer needed to be initialized.</param> /// <param name="spaceId">The <see cref="SaveDataSpaceId"/> of the indexer to open.</param> /// <returns>The <see cref="Result"/> of the operation.</returns> public Result OpenSaveDataIndexerAccessor(out SaveDataIndexerAccessor accessor, out bool neededInit, SaveDataSpaceId spaceId) { UnsafeHelpers.SkipParamInit(out neededInit); if (IsBisUserRedirectionEnabled && spaceId == SaveDataSpaceId.User) { spaceId = SaveDataSpaceId.ProperSystem; } UniqueLock indexerLock = default; try { ISaveDataIndexer indexer; switch (spaceId) { case SaveDataSpaceId.System: case SaveDataSpaceId.User: indexerLock = new UniqueLock(_bisIndexer.Locker); if (!_bisIndexer.IsInitialized) { _bisIndexer.Indexer = new SaveDataIndexer(FsClient, new U8Span(SystemIndexerMountName), SaveDataSpaceId.System, SaveDataId, MemoryResource); neededInit = true; } indexer = _bisIndexer.Indexer; break; case SaveDataSpaceId.SdSystem: case SaveDataSpaceId.SdCache: // ReSharper doesn't realize that UniqueLock locks the indexer's lock object // ReSharper disable InconsistentlySynchronizedField indexerLock = new UniqueLock(_sdCardIndexer.Locker); // We need to reinitialize the indexer if the SD card has changed if (!_sdCardHandleManager.IsValid(in _sdCardHandle) && _sdCardIndexer.IsInitialized) { _sdCardIndexer.Indexer.Dispose(); _sdCardIndexer.Indexer = null; } if (!_sdCardIndexer.IsInitialized) { _sdCardIndexer.Indexer = new SaveDataIndexer(FsClient, new U8Span(SdCardIndexerMountName), SaveDataSpaceId.SdSystem, SaveDataId, MemoryResource); _sdCardHandleManager.GetHandle(out _sdCardHandle).IgnoreResult(); neededInit = true; } indexer = _sdCardIndexer.Indexer; // ReSharper restore InconsistentlySynchronizedField break; case SaveDataSpaceId.Temporary: indexerLock = new UniqueLock(_tempIndexer.Locker); indexer = _tempIndexer.Indexer; break; case SaveDataSpaceId.ProperSystem: indexerLock = new UniqueLock(_properSystemIndexer.Locker); if (!_properSystemIndexer.IsInitialized) { _properSystemIndexer.Indexer = new SaveDataIndexer(FsClient, new U8Span(ProperSystemIndexerMountName), SaveDataSpaceId.ProperSystem, SaveDataId, MemoryResource); neededInit = true; } indexer = _properSystemIndexer.Indexer; break; case SaveDataSpaceId.SafeMode: indexerLock = new UniqueLock(_safeIndexer.Locker); if (!_safeIndexer.IsInitialized) { _safeIndexer.Indexer = new SaveDataIndexer(FsClient, new U8Span(SafeModeIndexerMountName), SaveDataSpaceId.SafeMode, SaveDataId, MemoryResource); neededInit = true; } indexer = _safeIndexer.Indexer; break; default: accessor = default; return(ResultFs.InvalidArgument.Log()); } accessor = new SaveDataIndexerAccessor(indexer, ref indexerLock); return(Result.Success); } finally { indexerLock.Dispose(); } }
public SaveDataIndexerAccessor(ISaveDataIndexer indexer, ref UniqueLock locker) { Indexer = indexer; _locker = new UniqueLock(ref locker); }