4#include "../Common/CompilerOffsetOf.h"
5#include "AsyncStreams.h"
12template <
typename AsyncRequestType,
typename AsyncEventLoopType>
20 AsyncRequestType request;
26 AsyncEventLoopType* eventLoop =
nullptr;
28 bool autoCloseDescriptor =
false;
32 SC_ASYNC_STREAMS_ASSERT_RELEASE(request.isFree());
33 if (eventLoop ==
nullptr)
34 return Result::Error(AsyncStreamsResultCategory, AsyncStreamsError::AsyncEventLoopMissing);
37 request.callback.template bind<Self, &Self::afterRead>(*
this);
38 const Result startResult = request.start(*eventLoop);
53 finalizeReadableDestruction();
58 return request.stop(*eventLoop, &getStopCallback());
62 void afterRead(
typename AsyncRequestType::Result& result)
67 SC_ASYNC_STREAMS_ASSERT_RELEASE(request.isFree());
76 const bool continuePushing = this->
push(bufferID, data.sizeInBytes());
77 SC_ASYNC_STREAMS_ASSERT_RELEASE(result.getAsync().isFree());
89 request.callback.template bind<Self, &Self::afterRead>(*
this);
90 result.reactivateRequest(
true);
97 if (bufferID.isValid())
106 void finalizeReadableDestruction()
108 if (bufferID.isValid())
113 if (autoCloseDescriptor)
115 SC_ASYNC_STREAMS_ASSERT_RELEASE(request.closeHandle());
121 template <
typename T_AsyncResult>
122 static void stopReadableCallback(T_AsyncResult& result)
124 SC_COMPILER_WARNING_PUSH_OFFSETOF;
125 Self& stream = SC_COMPILER_FIELD_OFFSET(Self, request,
static_cast<AsyncRequestType&
>(result.async));
126 stream.finalizeReadableDestruction();
127 SC_COMPILER_WARNING_POP_OFFSETOF;
132 static Function<void(AsyncResult&)>& getStopCallback() {
static Function<void(AsyncResult&)> cb = &stopReadableCallback<AsyncResult>;
return cb; }
136 template <
typename DescriptorType>
137 Result init(AsyncBuffersPool& buffersPool, AsyncEventLoopType& loop,
const DescriptorType& descriptor)
139 if (request.isCancelling())
140 return Result::Error(AsyncStreamsResultCategory, AsyncStreamsError::AsyncRequestDestroying);
141 this->eventLoop = &loop;
142 SC_TRY(descriptor.get(this->request.handle,
143 Result::Error(AsyncStreamsResultCategory, AsyncStreamsError::AsyncDescriptorMissing)));
148template <
typename AsyncRequestType,
typename AsyncEventLoopType>
156 AsyncRequestType request;
162 AsyncEventLoopType* eventLoop =
nullptr;
164 bool autoCloseDescriptor =
false;
170 if (eventLoop ==
nullptr)
171 return Result::Error(AsyncStreamsResultCategory, AsyncStreamsError::AsyncEventLoopMissing);
172 bufferID = newBufferID;
173 SC_ASYNC_STREAMS_ASSERT_RELEASE(not callback.isValid());
175 SC_TRY(this->
getBuffersPool().getReadableData(bufferID, request.buffer));
176 request.callback.template bind<Self, &Self::afterWrite>(*
this);
177 const Result res = request.start(*eventLoop);
187 if (request.isFree())
189 finalizeWritableDestruction();
194 return request.stop(*eventLoop, &getStopCallback());
200 void afterWrite(
typename AsyncRequestType::Result& result)
205 auto cb = move(callback);
210 void finalizeWritableDestruction()
212 if (autoCloseDescriptor)
214 SC_ASYNC_STREAMS_ASSERT_RELEASE(request.closeHandle());
220 template <
typename T_AsyncResult>
221 static void stopWritableCallback(T_AsyncResult& result)
223 SC_COMPILER_WARNING_PUSH_OFFSETOF;
224 Self& stream = SC_COMPILER_FIELD_OFFSET(Self, request,
static_cast<AsyncRequestType&
>(result.async));
225 stream.finalizeWritableDestruction();
226 SC_COMPILER_WARNING_POP_OFFSETOF;
231 static Function<void(AsyncResult&)>& getStopCallback() {
static Function<void(AsyncResult&)> cb = &stopWritableCallback<AsyncResult>;
return cb; }
234 template <
typename DescriptorType>
235 Result init(AsyncBuffersPool& buffersPool, AsyncEventLoopType& loop,
const DescriptorType& descriptor)
237 this->eventLoop = &loop;
238 SC_TRY(descriptor.get(this->request.handle,
239 Result::Error(AsyncStreamsResultCategory, AsyncStreamsError::AsyncDescriptorMissing)));
Definition AsyncStreams.h:67
void refBuffer(AsyncBufferView::ID bufferID)
Increments a buffer reference count.
void unrefBuffer(AsyncBufferView::ID bufferID)
Decrements a buffer reference count.
Uses an SC::AsyncFileRead to stream data from a file.
Definition AsyncRequestStreams.h:246
Uses an SC::AsyncSocketReceive to stream data from a socket.
Definition AsyncRequestStreams.h:250
Async source abstraction emitting data events in caller provided byte buffers.
Definition AsyncStreams.h:229
void pushEnd()
Use pushEnd from inside AsyncReadableStream::asyncRead to signal production end.
void emitError(Result error)
Signals an async error received.
bool push(AsyncBufferView::ID bufferID, size_t newSize)
Use push from inside AsyncReadableStream::asyncRead function to queue received data.
bool hasBeenDestroyed() const
Returns true if the stream has been already destroyed (asynchronously through destroy())
Definition AsyncStreams.h:270
Result finishedDestroyingReadable()
Called from inside asyncDestroy to transition from Destroying to Destroyed state (emitting eventClose...
AsyncBuffersPool & getBuffersPool()
Obtains the AsyncBuffersPool to request more buffers.
bool getBufferOrPause(size_t minumumSizeInBytes, AsyncBufferView::ID &bufferID, Span< char > &data)
Returns an unused buffer from pool or pauses the stream if none is available.
Result init(AsyncBuffersPool &buffersPool)
Emitted when the underlying resource has been closed.
Definition AsyncRequestStreams.h:14
virtual Result asyncDestroyReadable() override
Function that a readable stream can re-implement to release its internal resources.
Definition AsyncRequestStreams.h:49
void setAutoCloseDescriptor(bool value)
Automatically closes descriptor during read stream close event.
Definition AsyncRequestStreams.h:18
virtual Result asyncRead() override
Function that every stream must define to implement its custom read operation.
Definition AsyncRequestStreams.h:30
Definition AsyncRequestStreams.h:150
void setAutoCloseDescriptor(bool value)
Automatically closes descriptor during write stream finish event.
Definition AsyncRequestStreams.h:154
virtual Result asyncDestroyWritable() override
Function that a writable stream can re-implement to release its internal resources.
Definition AsyncRequestStreams.h:185
virtual bool canEndWritable() override
Allows keeping a writable in ENDING state until it has finished flushing all pending data.
Definition AsyncRequestStreams.h:198
AsyncBufferView::ID BufferViewID
AsyncFileRead / AsyncFileWrite / AsyncSocketReceive / AsyncSocketSend.
Definition AsyncRequestStreams.h:159
virtual Result asyncWrite(BufferViewID newBufferID, Function< void(BufferViewID)> cb) override
Function that every stream must define to implement its custom write operation.
Definition AsyncRequestStreams.h:168
Uses an SC::AsyncFileWrite to stream data to a file.
Definition AsyncRequestStreams.h:248
Uses an SC::AsyncSocketSend to stream data to a socket.
Definition AsyncRequestStreams.h:252
Async destination abstraction where bytes can be written to.
Definition AsyncStreams.h:365
void finishedDestroyingWritable()
Function that MUST be called by re-implementations of asyncDestroyWritable once they're done.
Result init(AsyncBuffersPool &buffersPool)
Emitted when the underlying resource has been closed.
void finishedWriting(AsyncBufferView::ID bufferID, Function< void(AsyncBufferView::ID)> &&cb, Result res)
Signals that the given buffer (previously queued by write) has been fully written.
AsyncBuffersPool & getBuffersPool()
Obtains the buffers pool to access its data.