Обратные вызовы и `std::recursive_mutex` - допустимый вариант использования?

У меня есть следующий полиморфный интерфейс:

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 интерфейс.

1 ответ

Существует два режима обратного вызова: немедленный и отложенный. Это требует от клиента быть готовым к немедленному обратному вызову и повторному входу. Это усложняет реализацию клиента. Если вы выполняете обратный вызов всегда с задержкой, это устраняет необходимость повторного входа клиента.

Другие вопросы по тегам