[英]Callbacks and `std::recursive_mutex` - valid use case?
我具有以下多態接口:
struct service
{
virtual void connect(std::function<void>(bool) cb);
// Invoke 'cb' with 'true' on connection success, 'false' otherwise.
virtual ~service() { }
};
service
某些實現是同步的:
struct synchronous_service : service
{
void connect(std::function<void>(bool) cb) override
{
cb(true);
}
};
其他是異步的:
struct asynchronous_service : service
{
void connect(std::function<void>(bool) cb) override
{
_thread_pool.post([this, cb]{ cb(true); });
}
};
我需要創建一個service
包裝器,它本身就是service
。 這需要是線程安全的,並在mutex
下保持某些狀態:
struct wrapped_service : service
{
state _state;
std::mutex _mutex;
std::unique_ptr<service> _underlying;
void connect(std::function<void>(bool) cb) override
{
std::lock_guard<decltype(_mutex)> guard{_mutex};
// update `_state`
_underlying->connect([this, cb]
{
std::lock_guard<decltype(_mutex)> guard{_mutex};
// update `_state`
cb(true);
});
// update `_state`
}
}
如果_underlying->connect
調用始終是異步的,則std::mutex
將正常工作。 但是,在_underlying->connect
是同步的情況下,程序將凍結。
這可以通過使用std::recursive_mutex
而不是std::mutex
來解決,但是眾所周知,這是一種代碼味道。
這是std::recursive_mutex
的有效用例嗎?
還是設計有缺陷? 請注意,我無法控制service
接口。
回調有兩種模式:立即和延遲。 這就要求客戶端准備好立即回調並重新進入。 這使客戶端實現變得復雜。 如果您使回調始終被延遲,則無需重新進入客戶端。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.