lisp, CLOS: добавление слота в класс блокировки

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

К сожалению, этого, очевидно, нельзя сделать с помощью функции sure-class. Я могу добавить слоты для "процесса, но не для" блокировки, потому что он указан как встроенный в класс. Смотрите мой предыдущий вопрос здесь о том, как сделать это для 'process: lisp, CLOS: добавление слота в класс процесса

Вы знаете, как решить эту проблему? Если это невозможно, единственной альтернативой, которую я могу придумать, является сохранение иерархического отношения блокировок в хеш-таблице, но, поскольку некоторые блокировки создаются во время выполнения и в разных процессах, мне придется добавить еще одну блокировку просто чтобы получить доступ к хеш-таблице, которая хранит метаданные на замках.

Это кажется мне ужасно неэффективным. У тебя есть идея получше?

редактировать: для пояснения, я использую Clozure Common Lisp.

2 ответа

Решение

Вы можете указать метакласс, используя :metaclass опция класса в форме defclass.

CL-USER> (defclass hierarchical-lock (lock)
           ((parent :initarg :parent :reader parent))
           (:metaclass built-in-class))
#<BUILT-IN-CLASS HIERARCHICAL-LOCK>

Тем не менее, даже если вы можете сделать это и получить класс, я не уверен, как вы будете его создавать. Пытаясь использовать make-instance терпит неудачу:

CL-USER> (make-instance 'hierarchical-lock)

; There is no applicable method for the generic function:
;   #<STANDARD-GENERIC-FUNCTION MAKE-INSTANCE #x30200002676F>
; when called with arguments:
;   (#<BUILT-IN-CLASS HIERARCHICAL-LOCK>)
;    [Condition of type SIMPLE-ERROR]

make-lock реализован в l0-aprims.lisp как

(defun make-lock (&optional name)
  "Create and return a lock object, which can be used for synchronization
between threads."
  (%make-lock (%make-recursive-lock-ptr) name))

Вы можете следить за выполнением %make-lock пока вы не перейдете к деталям реализации низкого уровня, но ясно, что блокировки не получаются так, как это делают типичные экземпляры CLOS.

В дополнение к предложению Райнера Йосвига в комментарии к этому ответу, что вы даете знать разработчикам CCL, что вы бы оценили блокировки как объекты CLOS, вы всегда можете использовать некоторую агрегацию и определить свои собственные hierarchical-lock у которого есть слот для его примитивной блокировки и слот для родителя. С помощью магии обобщенных функций вы можете реализовать методы в обобщенных функциях, которые работают с блокировками, чтобы ваши hierarchical-lock ведет себя как встроенный замок. (Это предполагает, что API блокировки определен в терминах общих функций.)

Вы можете использовать подкласс, который имеет такой слот.

(defclass hierarchical-lock (lock)
  ((parent :initarg :parent :reader parent)))
Другие вопросы по тегам