Здравствуйте. Мне необходимо сделать блокировку одной фигнюшки, несколькими пользователями. Все могут ставить на блокировку когда она уже есть, но снимать её надо только тогда, когда все её сняли. Я додумалась до счётчика блокировок, а также возвращения идентификатора блокировки тому кто заблокировал. Посоветуйте пожалуйста, может есть что-то получше? Спасибо всем ответившим.
Подсчёт ссылок не нравится, так как можно по ошибке вызвать несколько раз. И идентификаторы тоже не очень красиво. Хотя если в качестве идентификаторов использовать гуиды, то наверно ошибки можно свести до минимума.
BlondinkoFifthSizeBreast я имел ввиду RAII + работа с этим объектом через его синглтон. м-д по установке блокировки сделать публичным. в деструкторе класса реализовать снятие блокировки. как только объект уничтожится -- она как раз и вызовется.
Вы имеете ввиду блокировать в конструкторе, а разблокировать в деструкторе? Тогда конечно гарантируется правильный подсчёт. Но пользователи могут блокировать по мере необходимости, где угодно. Или отдельный класс - блокировка? И чтобы её сделать необходимо было создать экземпляр этого класса?
вариантов несколько. чтобы определиться какое решение самое подходящее, нужно прояснить сл ньюансы: 1. по логике у вас должен быть лишь один объект (который блочат и разблокирывают) или нет? 2. операции блокирования/разблокирования этого объекта явл. деталями реализации (т.е. внешне никому нет дела до того, какие операции происходят с этим объектом). скажем, мы говорим ResourceManager-у чтобы он возвратил нам дескриптор текущего обрабатываемого объекта, которому мы далее уже напрямую говорим через его паблик методы "сделайТо()", "сделайСё()", и нас не заботит абсолютно то, КАК ResourceManager (который, кстати, является Синглтоном) возвратил нам этот дескриптор. (делал он блокировки, или подгружал объект из кеша -- нам это знать не надо, т.к. это детали реализации). что-то близкое к вашей ситуации здесь обрисовано?
Да, объект один и нужно иметь возможность его разблокировать так, чтобы блокировки других не снимались. Как сделать это так, чтобы с одной стороны это было максимально удобно, а с другой стороны максимально безопасно для объекта. На первом месте всё же стоит безопасность. Если сделать подсчёт ссылок, то кто-то может забыть разблокировать и наоборот сделать это несколько раз. И найти это будет не просто. Если при блокировке выдавать её уникальный идентификатор, то кто-то может передать по ошибке чужой. Пока наиболее привлекательным мне видиться вариант с абсолютно уникальными идентификаторами - гуидами, так как в этом случае возможность передать чужой очень мала. И если кто-то вдруг забыл разблокировать, то это гораздо проще найти.
есть объект. вся работа с ним осуществляется через Синглтон. для того чтобы с ним работать, нужно сначала сказать этому синглтону "block", и передать ему указатель на того, кто его вызывает (а-ля this). синглтон в свою очередь смотрит на полученный указатель (caller), пробегается по своей таблице и анализирует, не заблочен ли _уже_ агрегируемый им объект этой вызываемой стороной. если так, то ругается/бросает ексепшн/пишет в лог. в обратном случае заносит в тиблицу этот указатель на новую вызываемую сторону, и возвращает интерфейс по работе с агрегируемым объектом, через который внешняя вызываемая сторона может с этим объектом работать. как только вызывающая сторона закончила работать с этим объектом, она должна вызвать м-д синглтона "unblock", при вызове которого синглтон удалит указатель на эту вызывающую сторону из своей таблицы поиска. по разрушению синглтона он грохает сам агрегируемый объект. т.о. мы предоставляем разным caller-ам возможность работать с агрегируемым Синглтоном объектом, учитывая симметричности вызовов block/unblock для каждого из них (caller-ов).
varnie Дело не в синглтоне, а в механизме работы пользователей с ресурсом. Вариант с передачей this интересный, но проблема в том, что тогда весь механизм перекладывается на пользователей. Даже если предположить, что все будут передавать именно указатель на объект, то если будут сделаны две блокировки в одном классе, то всё пойдёт неправильно. Люди не в курсе, кто в каком месте с каким id заблокировал. Я сделала на уникальных идентификаторах. При блокировке он генерируется, запоминается в списке и возвращается пользователю. И если кто-то при разблокировании допустит ошибку и передаст незарегистрированный id, то сработает assert. Идентификатор уникален, и возможность передачи чужого практически равна нулю. Всем спасибо, считаю что проблема решена.