Ресурс шкафчик в Qt


Идея заключается в блокировке ресурсов в C# или Java с использованием библиотеки Qt:

lock(obj){/*process with locked obj*/}`

Теперь я вижу проблему с удалением объекта obj под замок().

resourcelocker.ч

#ifndef RESOURCELOCKER_H
#define RESOURCELOCKER_H

#include <QObject>
#include <QHash>
#include <QSemaphore>

class ResourceLocker : public QObject
{
    Q_OBJECT
public:

    friend class ResourceWatcher;
    explicit ResourceLocker(QObject *parent = 0);
    ~ResourceLocker();

    bool lock();

private:
    static QHash<QObject*,QSemaphore*> resources;
    QSemaphore * sem;
    QObject * expectedParent;
    bool doubleLock;

signals:

public slots:

};

#define _LOCK(object) for (ResourceLocker locker((object)); locker.lock(); )

#endif // RESOURCELOCKER_H

resourcelocker.cpp

#include "resourcelocker.h"
#include <QMutex>
#include <QMutexLocker>
#include <QSemaphore>
#include <QDebug>

QHash<QObject* ,QSemaphore*> ResourceLocker::resources;

class ResourceWatcher: public QObject
{
public:
    explicit ResourceWatcher(QObject * parent):
        QObject(parent)
    {
        //qDebug()<<"creating watcher";
    }

    ~ResourceWatcher()
    {
        QSemaphore * sem = ResourceLocker::resources.value(parent(),NULL);
        if (sem->available()>0)
        {
            //unlocked
            ResourceLocker::resources.remove(parent());
            delete sem;
        }
        else
        {
            //locked
            ResourceLocker::resources.remove(parent());
        }
        //qDebug()<<"removing sem";

    }
};

ResourceLocker::ResourceLocker(QObject *parent) :QObject(),expectedParent(parent),doubleLock(false)
{
}

bool ResourceLocker::lock()
{
    static QMutex internalMutex;
    {
        QMutexLocker locker(&internalMutex);

        if (doubleLock)
            return false;
        doubleLock = true;
        //qDebug()<<&expectedParent;

        sem = resources.value(expectedParent,NULL);
        if (sem == NULL)
        {
            //qDebug()<<"Crearting sem";
            sem = new QSemaphore(1);
            resources.insert(expectedParent,sem);
            new ResourceWatcher(expectedParent);
        }
    }
    //qDebug()<<"acquiring";
   sem->acquire();
   return true;
}

ResourceLocker::~ResourceLocker()
{
    QMutex internalMutex;
    QMutexLocker locker(&internalMutex);
    //qDebug()<<"releasing";
    sem->release();
    if (!resources.values().contains(sem))
        delete sem;
}

Использование:

_LOCK(smth)
    {
        //prcoess with smth locked

    }


1035
3
задан 17 сентября 2011 в 10:09 Источник Поделиться
Комментарии
1 ответ

Есть причина, почему такие языки, как Java имеет ту особенность, что они не имеют РАИИ, как с++.

Я не совсем понимаю, как это лучше, чем просто:

// Note: Braces for scope. "mutex" could optionally be declared static, or as a class member.
{
QMutexLocker lock(&mutex);

/* code */
}

2
ответ дан 17 сентября 2011 в 09:09 Источник Поделиться