атомарно пишет в сокет - PullRequest
5 голосов
/ 20 февраля 2012

Я использую process-send-string для отправки данных в сокетное соединение, но меня не устраивает эффект этой функции.Грубо говоря, вызов (process-send-string "foo") может закончиться отправкой "bar", а затем "foo", как объяснено ниже.

Как указывалось сопровождающими Emacs, код C process-send-string вызывает функцию wait_reading_process_output(даже до того, как на самом деле что-то напишет), которые могут запускать таймеры, которые, в свою очередь, могут вызывать process-send-string, и между такими вложенными вызовами не производится упорядочение.

Это делает практически невозможным реализацию протокола RPC, которыйпредназначен для использования крючками, вызываемыми в неконтролируемое время.Поэтому мой вопрос: как мы могли бы создать атомарный, «синхронизированный» примитив для этой цели?

Ответы [ 3 ]

3 голосов
/ 22 февраля 2012

Вы можете сделать что-то вроде:

(defun my-send-cmd (proc str)
  (if (process-get proc 'my-waiting)
      (process-put proc 'my-pending (append (process-get proc 'my-pending) (list str)))
    (process-put proc 'my-waiting t)
    (process-send-string proc str)))

, затем в фильтре процесса, когда вы получите ответ на команду, отметьте `my-pending 'и, если не nil, возьмите первый аргумент, отправьте его в процесс, в противном случае установите my-ожидание обратно на ноль.Конечно, это предполагает, что каждая команда получит ответ от сервера, и что вы не можете выполнять потоковую передачу команд.

При этом поведение, которое вы видите, должно, вероятно, рассматриваться как ошибка или, по крайней мере, какошибка, поэтому сообщите об этом с помощью Mx report-emacs-bug.

2 голосов
/ 20 февраля 2012

Вместо того, чтобы использовать process-send-string непосредственно в ваших хуках, добавьте в буфер, а затем вызовите process-send-string так, чтобы он не был асинхронным.

1 голос
/ 06 марта 2012

Наконец, вариант, который работал для меня, состоял в том, чтобы использовать API очереди транзакций, который является более высоким уровнем (поэтому он не может обрабатывать все виды протоколов), но обеспечивает правильный порядок чередования сообщений.

...