C ++ ScopeTryLock Macro - PullRequest
       20

C ++ ScopeTryLock Macro

0 голосов
/ 10 ноября 2018

Привет, у нас есть мьютекс, и он хотел бы создать TryScopeLock, который будет использоваться как

if (ScopeTryLock(mutex))
{
   ...
}

Идея состоит в том, что если мьютекс можно заблокировать, это так и вводится оператор if.В противном случае его пропускают.

Я пытаюсь использовать этот макрос и класс для его достижения

#define ScopeTryLock(lock) (_ScopeTryLock &lock = _ScopeTryLock::MakeTryLock(lock, __FILE__, __LINE__).tryToLock()).ownsLock()

class _ScopeTryLock
{
    bool didLock;
    const char *file;
    const int line;
public:
    static _ScopeTryLock MakeTryLock(Mutex& m, char* file, int line)
    {
        return _ScopeTryLock(m, file, line);
    }

    _ScopeTryLock(Mutex& m, char* file, int line) : mutex(m), didLock(false), file(file), line(line){}

    ~_ScopeTryLock() 
    {
        if (didLock) 
        {
            mutex.Unlock((char *) file, line);
        }
    }

    _ScopeTryLock &tryToLock()
    {
        if (mutex.TryLock((char *)file, line))
        {
            didLock = true;
        }
        return *this;
    }

    bool ownsLock() 
    {
        return didLock;
    }

protected:
    Mutex& mutex;
};

Проблема в том, что я не могу найти подходящий макрос, чтобы заставить эту работу работать так, как я хочу.Я попытался

#define ScopeTryLock(lock) _ScopeTryLock::MakeTryLock(lock, __FILE__, __LINE__).tryToLock().ownsLock()

, но это не сработало, поскольку кажется, что он вызывает деструктор, когда вводит оператор if, что не то, что я хочу.Я также хочу держаться подальше от использования кучи.Любые идеи, как заставить это работать?

edit:

извините, я должен указать, что это c ++ 11.Также у меня нет большой гибкости с мьютексом, который я использую.У мьютекса есть .Try (), который будет возвращать true, если блокировка была успешной, и false, если это не так.Это мой единственный механизм взаимодействия с мьютексом (конечно, я могу заблокировать и разблокировать его).Я действительно хотел бы выяснить немного магии с ++, чтобы заставить эту работу работать так, как я хочу в условии if.Это может быть невозможно, я думаю: (

1 Ответ

0 голосов
/ 10 ноября 2018

Если вы используете C ++ 17, вы можете использовать new veriion оператора if, где вы можете объявить переменную на время кода, управляемого if.

#define ScopeTryLock(mutex) ScopeTryLock lock(ScopeTryLock::MakeTryLock(lock, __FILE__, __LINE__)); lock.tryToLock().ownsLock()

(Примечание. Вокруг этого скобки нет, и точка с запятой отделяет оператор init от условия.) При этом будет объявлена ​​переменная lock, которая останется в области действия в течение действия оператора ifelse, если есть)

Затем, когда вы используете его в операторе if

if (ScopeTryLock(mutex))

создаст переменную (с именем lock), которая не будет уничтожена до тех пор, пока тело if не завершит выполнение.

...