input/Stream: remove attribute "cond", replace with handler interface
This adds a bit of overhead, but also adds flexibility to the API, because arbitrary triggers may be invoked from that virtual method implementation, not just Cond::signal(). The motivation for this is to make the handlers more dynamic, for the upcoming buffering class utilizing ProxyInputStream.
This commit is contained in:
@@ -31,8 +31,8 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
class Cond;
|
||||
struct Tag;
|
||||
class InputStreamHandler;
|
||||
|
||||
class InputStream {
|
||||
public:
|
||||
@@ -55,6 +55,7 @@ public:
|
||||
*/
|
||||
Mutex &mutex;
|
||||
|
||||
private:
|
||||
/**
|
||||
* A cond that gets signalled when the state of this object
|
||||
* changes from the I/O thread. The client of this object may
|
||||
@@ -63,7 +64,7 @@ public:
|
||||
* This object is allocated by the client, and the client is
|
||||
* responsible for freeing it.
|
||||
*/
|
||||
Cond &cond;
|
||||
InputStreamHandler *handler = nullptr;
|
||||
|
||||
protected:
|
||||
/**
|
||||
@@ -96,9 +97,9 @@ private:
|
||||
std::string mime;
|
||||
|
||||
public:
|
||||
InputStream(const char *_uri, Mutex &_mutex, Cond &_cond) noexcept
|
||||
InputStream(const char *_uri, Mutex &_mutex) noexcept
|
||||
:uri(_uri),
|
||||
mutex(_mutex), cond(_cond) {
|
||||
mutex(_mutex) {
|
||||
assert(_uri != nullptr);
|
||||
}
|
||||
|
||||
@@ -122,16 +123,33 @@ public:
|
||||
* notifications
|
||||
* @return an #InputStream object on success
|
||||
*/
|
||||
gcc_nonnull_all
|
||||
static InputStreamPtr Open(const char *uri, Mutex &mutex, Cond &cond);
|
||||
gcc_nonnull(1)
|
||||
static InputStreamPtr Open(const char *uri, Mutex &mutex);
|
||||
|
||||
/**
|
||||
* Just like Open(), but waits for the stream to become ready.
|
||||
* It is a wrapper for Open(), WaitReady() and Check().
|
||||
*/
|
||||
gcc_nonnull_all
|
||||
static InputStreamPtr OpenReady(const char *uri,
|
||||
Mutex &mutex, Cond &cond);
|
||||
gcc_nonnull(1)
|
||||
static InputStreamPtr OpenReady(const char *uri, Mutex &mutex);
|
||||
|
||||
/**
|
||||
* Install a new handler.
|
||||
*
|
||||
* The caller must lock the mutex.
|
||||
*/
|
||||
void SetHandler(InputStreamHandler *new_handler) noexcept {
|
||||
handler = new_handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Install a new handler and return the old one.
|
||||
*
|
||||
* The caller must lock the mutex.
|
||||
*/
|
||||
InputStreamHandler *ExchangeHandler(InputStreamHandler *new_handler) noexcept {
|
||||
return std::exchange(handler, new_handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* The absolute URI which was used to open this stream.
|
||||
@@ -166,14 +184,6 @@ public:
|
||||
return ready;
|
||||
}
|
||||
|
||||
void WaitReady() noexcept;
|
||||
|
||||
/**
|
||||
* Wrapper for WaitReady() which locks and unlocks the mutex;
|
||||
* the caller must not be holding it already.
|
||||
*/
|
||||
void LockWaitReady() noexcept;
|
||||
|
||||
gcc_pure
|
||||
bool HasMimeType() const noexcept {
|
||||
assert(ready);
|
||||
@@ -380,6 +390,30 @@ public:
|
||||
*/
|
||||
gcc_nonnull_all
|
||||
void LockReadFull(void *ptr, size_t size);
|
||||
|
||||
protected:
|
||||
void InvokeOnReady() noexcept;
|
||||
void InvokeOnAvailable() noexcept;
|
||||
};
|
||||
|
||||
/**
|
||||
* Install an #InputStreamHandler during the scope in which this
|
||||
* variable lives, and restore the old handler afterwards.
|
||||
*/
|
||||
class ScopeExchangeInputStreamHandler {
|
||||
InputStream &is;
|
||||
InputStreamHandler *const old_handler;
|
||||
|
||||
public:
|
||||
ScopeExchangeInputStreamHandler(InputStream &_is,
|
||||
InputStreamHandler *new_handler) noexcept
|
||||
:is(_is), old_handler(is.ExchangeHandler(new_handler)) {}
|
||||
|
||||
ScopeExchangeInputStreamHandler(const ScopeExchangeInputStreamHandler &) = delete;
|
||||
|
||||
~ScopeExchangeInputStreamHandler() noexcept {
|
||||
is.SetHandler(old_handler);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user