tgstation-server 6.17.0
The /tg/station 13 server suite
Loading...
Searching...
No Matches
Public Member Functions | Properties | Private Member Functions | Private Attributes | List of all members
Tgstation.Server.Host.IO.BufferedFileStreamProvider Class Referencesealed

IFileStreamProvider that provides a ISeekableFileStreamProvider from an input Stream. More...

Inheritance diagram for Tgstation.Server.Host.IO.BufferedFileStreamProvider:
Inheritance graph
[legend]
Collaboration diagram for Tgstation.Server.Host.IO.BufferedFileStreamProvider:
Collaboration graph
[legend]

Public Member Functions

 BufferedFileStreamProvider (Stream input)
 Initializes a new instance of the BufferedFileStreamProvider class.
 
async ValueTask DisposeAsync ()
 
async ValueTask< StreamGetResult (CancellationToken cancellationToken)
 Gets the provided Stream. May be called multiple times, though cancelling any may cause all calls to be cancelled. All calls yield the same Stream reference.
Parameters
cancellationTokenThe CancellationToken for the operation.
Returns
A ValueTask<TResult> resulting in the provided Stream.
The resulting Stream is owned by the IFileStreamProvider and is short lived unless otherwise specified. It should be buffered if it needs use outside the lifetime of the IFileStreamProvider.
 
async ValueTask< MemoryStream > GetOwnedResult (CancellationToken cancellationToken)
 Gets the provided MemoryStream. May be called multiple times, though cancelling any may cause all calls to be cancelled.
Parameters
cancellationTokenThe CancellationToken for the operation.
Returns
A ValueTask<TResult> resulting in the provided MemoryStream on success.

 
Task EnsureBuffered (CancellationToken cancellationToken)
 Ensures the input Stream has been copied to the buffer.
 

Properties

bool Disposed [get]
 If the ISeekableFileStreamProvider has had global::System.IAsyncDisposable.DisposeAsync called on it.
 
- Properties inherited from Tgstation.Server.Host.IO.ISeekableFileStreamProvider

Private Member Functions

async ValueTask<(MemoryStream Stream, long StreamLength)> GetResultInternal (CancellationToken cancellationToken)
 Gets the shared MemoryStream and its Stream.Length.
 

Private Attributes

readonly Stream input
 The original input Stream must remain valid for the lifetime of the BufferedFileStreamProvider or until GetResult(CancellationToken) first returns.
 
readonly SemaphoreSlim semaphore
 The SemaphoreSlim used to synchronize writes to buffer.
 
volatile? MemoryStream buffer
 The backing Stream.
 
volatile bool buffered
 If buffer has been populated.
 

Detailed Description

IFileStreamProvider that provides a ISeekableFileStreamProvider from an input Stream.

Definition at line 13 of file BufferedFileStreamProvider.cs.

Constructor & Destructor Documentation

◆ BufferedFileStreamProvider()

Tgstation.Server.Host.IO.BufferedFileStreamProvider.BufferedFileStreamProvider ( Stream  input)

Initializes a new instance of the BufferedFileStreamProvider class.

Parameters
inputThe value of input.

Definition at line 42 of file BufferedFileStreamProvider.cs.

43 {
44 this.input = input ?? throw new ArgumentNullException(nameof(input));
45
46 semaphore = new SemaphoreSlim(1);
47 try
48 {
49 buffer = new MemoryStream();
50 }
51 catch
52 {
53 semaphore.Dispose();
54 throw;
55 }
56 }
readonly SemaphoreSlim semaphore
The SemaphoreSlim used to synchronize writes to buffer.
readonly Stream input
The original input Stream must remain valid for the lifetime of the BufferedFileStreamProvider or unt...

References Tgstation.Server.Host.IO.BufferedFileStreamProvider.buffer, Tgstation.Server.Host.IO.BufferedFileStreamProvider.input, and Tgstation.Server.Host.IO.BufferedFileStreamProvider.semaphore.

Member Function Documentation

◆ DisposeAsync()

async ValueTask Tgstation.Server.Host.IO.BufferedFileStreamProvider.DisposeAsync ( )

Definition at line 59 of file BufferedFileStreamProvider.cs.

60 {
61 MemoryStream? localBuffer;
62 lock (semaphore)
63 {
64 localBuffer = buffer;
65 if (localBuffer == null)
66 return;
67
68 // important to drop the reference so it can properly GC
69 // The implementation of MemoryStream doesn't fucking do this for some reason
70 buffer = null;
71 buffered = true;
72 }
73
74 var bufferDispose = localBuffer.DisposeAsync();
75 semaphore.Dispose();
76 await bufferDispose;
77 }
volatile bool buffered
If buffer has been populated.

References Tgstation.Server.Host.IO.BufferedFileStreamProvider.buffer, Tgstation.Server.Host.IO.BufferedFileStreamProvider.buffered, and Tgstation.Server.Host.IO.BufferedFileStreamProvider.semaphore.

◆ EnsureBuffered()

Task Tgstation.Server.Host.IO.BufferedFileStreamProvider.EnsureBuffered ( CancellationToken  cancellationToken)

Ensures the input Stream has been copied to the buffer.

Parameters
cancellationTokenThe CancellationToken for the operation.
Returns
A Task representing the running operation.

◆ GetOwnedResult()

async ValueTask< MemoryStream > Tgstation.Server.Host.IO.BufferedFileStreamProvider.GetOwnedResult ( CancellationToken  cancellationToken)

Gets the provided MemoryStream. May be called multiple times, though cancelling any may cause all calls to be cancelled.

Parameters
cancellationTokenThe CancellationToken for the operation.
Returns
A ValueTask<TResult> resulting in the provided MemoryStream on success.

Implements Tgstation.Server.Host.IO.ISeekableFileStreamProvider.

Definition at line 87 of file BufferedFileStreamProvider.cs.

88 {
89 var (sharedStream, length) = await GetResultInternal(cancellationToken);
90 return new MemoryStream(sharedStream.GetBuffer(), 0, (int)length, false, true);
91 }
async ValueTask<(MemoryStream Stream, long StreamLength)> GetResultInternal(CancellationToken cancellationToken)
Gets the shared MemoryStream and its Stream.Length.

References Tgstation.Server.Host.IO.BufferedFileStreamProvider.GetResultInternal().

Here is the call graph for this function:

◆ GetResult()

async ValueTask< Stream > Tgstation.Server.Host.IO.BufferedFileStreamProvider.GetResult ( CancellationToken  cancellationToken)

Gets the provided Stream. May be called multiple times, though cancelling any may cause all calls to be cancelled. All calls yield the same Stream reference.

Parameters
cancellationTokenThe CancellationToken for the operation.
Returns
A ValueTask<TResult> resulting in the provided Stream.
The resulting Stream is owned by the IFileStreamProvider and is short lived unless otherwise specified. It should be buffered if it needs use outside the lifetime of the IFileStreamProvider.

Implements Tgstation.Server.Host.IO.IFileStreamProvider.

Definition at line 80 of file BufferedFileStreamProvider.cs.

81 {
82 var (sharedStream, _) = await GetResultInternal(cancellationToken);
83 return sharedStream;
84 }

References Tgstation.Server.Host.IO.BufferedFileStreamProvider.GetResultInternal().

Here is the call graph for this function:

◆ GetResultInternal()

async ValueTask<(MemoryStream Stream, long StreamLength)> Tgstation.Server.Host.IO.BufferedFileStreamProvider.GetResultInternal ( CancellationToken  cancellationToken)
private

Gets the shared MemoryStream and its Stream.Length.

Parameters
cancellationTokenThe CancellationToken for the operation.
Returns
A Task<TResult> resulting in buffer and its Stream.Length.

Definition at line 105 of file BufferedFileStreamProvider.cs.

106 {
107 if (!buffered)
108 using (await SemaphoreSlimContext.Lock(semaphore, cancellationToken))
109 if (!buffered)
110 {
111 MemoryStream localBuffer;
112 lock (semaphore)
113 localBuffer = buffer ?? throw new ObjectDisposedException(nameof(BufferedFileStreamProvider));
114
115 await input.CopyToAsync(localBuffer, cancellationToken);
116 localBuffer.Seek(0, SeekOrigin.Begin);
117 buffered = true;
118 return (Stream: localBuffer, StreamLength: localBuffer.Length);
119 }
120
121 lock (semaphore)
122 {
123 var localBuffer = buffer ?? throw new ObjectDisposedException(nameof(BufferedFileStreamProvider));
124 return (
125 Stream: localBuffer,
126 StreamLength: localBuffer.Length);
127 }
128 }
static async ValueTask< SemaphoreSlimContext > Lock(SemaphoreSlim semaphore, CancellationToken cancellationToken, ILogger? logger=null)
Asyncronously locks a semaphore .

References Tgstation.Server.Host.IO.BufferedFileStreamProvider.buffer, Tgstation.Server.Host.IO.BufferedFileStreamProvider.buffered, Tgstation.Server.Host.IO.BufferedFileStreamProvider.input, Tgstation.Server.Host.Utils.SemaphoreSlimContext.Lock(), and Tgstation.Server.Host.IO.BufferedFileStreamProvider.semaphore.

Referenced by Tgstation.Server.Host.IO.BufferedFileStreamProvider.GetOwnedResult(), and Tgstation.Server.Host.IO.BufferedFileStreamProvider.GetResult().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ buffer

volatile? MemoryStream Tgstation.Server.Host.IO.BufferedFileStreamProvider.buffer
private

◆ buffered

volatile bool Tgstation.Server.Host.IO.BufferedFileStreamProvider.buffered
private

◆ input

readonly Stream Tgstation.Server.Host.IO.BufferedFileStreamProvider.input
private

The original input Stream must remain valid for the lifetime of the BufferedFileStreamProvider or until GetResult(CancellationToken) first returns.

Definition at line 21 of file BufferedFileStreamProvider.cs.

Referenced by Tgstation.Server.Host.IO.BufferedFileStreamProvider.BufferedFileStreamProvider(), and Tgstation.Server.Host.IO.BufferedFileStreamProvider.GetResultInternal().

◆ semaphore

readonly SemaphoreSlim Tgstation.Server.Host.IO.BufferedFileStreamProvider.semaphore
private

Property Documentation

◆ Disposed

bool Tgstation.Server.Host.IO.BufferedFileStreamProvider.Disposed
get

If the ISeekableFileStreamProvider has had global::System.IAsyncDisposable.DisposeAsync called on it.

Implements Tgstation.Server.Host.IO.ISeekableFileStreamProvider.

Definition at line 16 of file BufferedFileStreamProvider.cs.


The documentation for this class was generated from the following file: