Поделиться через


Семантика сбоя для дескрипторов контекста

В этом разделе рассматривается семантика сбоев для дескрипторов контекста.

Семантика сбоя при сбое закрытия дескриптора контекста

Представьте, что клиентское приложение пытается закрыть дескриптор контекста, открытый на сервере, без завершения клиентского процесса. Кроме того, предположим, что вызов сервера для закрытия дескриптора контекста завершается сбоем (например, у клиента не хватает памяти). Правильный способ справиться с этой ситуацией — вызвать функцию RpcSsDeкислоухиЕнтКонтекст . В этом случае клиент очищает свою сторону дескриптора контекста и прерывает подключение к серверу. Так как соединение на самом деле является пулом соединений (см. раздел RPC и сеть), которое учитывается по одной ссылке для каждого открытого дескриптора привязки или контекста, уничтожение дескриптора контекста путем вызова функции RpcSsDe переключенияClientContext на самом деле не приводит к разрушению соединения. Вместо этого уменьшается количество ссылок для пула подключений. Чтобы соединения в пуле были закрыты, клиент должен закрыть все дескрипторы привязки и дескрипторы контекста для этого сервера из клиентского процесса. Затем все подключения в пуле закрываются, а механизм запуска сервера запускается и очищается.

Семантика сбоя при изменении состояния дескриптора контекста

Сведения в этом разделе относятся к платформам Windows XP и более поздних версий.

Дескрипторы контекста — это просто параметры функции. Все изменения состояния дескриптора контекста происходят при маршале или отмене маршалинга параметров. Например, если клиент открывает дескриптор контекста (изменяет его с NULL на не null), время выполнения RPC фактически не открывает часть RPC дескриптора, пока аргументы не будут маршалированы для отправки клиенту. В промежуточный период могут возникнуть сбои. Из-за различных возможных сетевых условий или низкого уровня ресурсов передача пакета клиенту может завершиться ошибкой. Или подпрограмма сервера может вызвать исключение при попытке изменить дескриптор контекста. В этих или других ситуациях сбоя клиент и сервер могут получить несогласованные представления дескриптора контекста. В этом разделе описывается правило для состояния дескриптора контекста и ответственность клиентского и серверного кода при различных условиях сбоя.

  • Возвращается дескриптор контекста NULL , но подпрограмма сервера сталкивается с ошибкой и создает исключение.

    Подпрограмма сервера отвечает за очистку любого состояния, связанного с дескриптором контекста, которое она может создать. Во время выполнения RPC очищается его состояние.

  • Поступает дескриптор контекста, отличного от NULL , но подпрограмма сервера сталкивается с ошибкой и вызывает исключение.

    Если подпрограмма сервера закрыла дескриптор контекста, клиент не будет знать об этом, так как вызов не будет выполнен успешно; Дальнейшее использование дескриптора контекста приведет к ошибке RPC_X_SS_CONTEXT_MISMATCH на клиенте. Если подпрограмма сервера не изменяет дескриптор контекста, клиент по-прежнему может использовать его. Если подпрограмма сервера изменяет сведения, хранящиеся в контексте сервера, новые вызовы от клиента будут использовать эти сведения.

  • Поступает дескриптор контекста, отличный от NULL , и подпрограмма сервера закрывает дескриптор, но не удалось выполнить маршалинг после маршалирования дескриптора контекста или выполнить обработку после маршалинга.

    Дескриптор контекста закрывается, и последующие вызовы этого клиента с помощью этого дескриптора контекста приводят к ошибке RPC_X_SS_CONTEXT_MISMATCH на клиенте.

  • Поступает дескриптор контекста NULL , и сервер создает контекст для этого дескриптора, но не удалось выполнить маршалинг после маршалирования дескриптора контекста или выполнить обработку после сбоя маршалинга.

    В этом случае время выполнения RPC вызывает запуск для этого дескриптора контекста и очищает состояние RPC для этого дескриптора контекста. Дескриптор контекста не будет создан на стороне клиента.

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

    Новые вызовы от клиента будут использовать дескриптор контекста, имеющийся на сервере.

  • Поступает дескриптор контекста NULL , и сервер не устанавливает для него значение, отличное от NULL, но вызов завершается сбоем до маршалирования дескриптора контекста.

    В этом случае на клиенте не создается дескриптор контекста.

  • Поступает дескриптор контекста, отличный от NULL , и сервер присваивает ему значение NULL, но маршалирование завершается сбоем до того, как дескриптор контекста будет маршалирован.

    В этом случае дескриптор контекста остается закрытым на сервере, и клиент получает RPC_X_SS_CONTEXT_MISMATCH ошибок при попытке использовать дескриптор контекста.

  • Дескриптор контекста NULL поступает на сервер, и сервер задает ему значение, отличное от NULL, но маршалирование завершается сбоем до маршалирования дескриптора контекста.

    Дескриптор контекста должен быть вызван для очистки сервера, и на клиенте не будет создан дескриптор контекста.

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

    Новые вызовы от клиента будут использовать состояние на сервере.

  • Дескриптор контекста объявляется как возвращаемое значение, а подпрограмма сервера возвращает значение NULL для дескриптора контекста, и маршалинг завершается сбоем до маршалирования дескриптора контекста.

    В этом случае на клиенте не создается новый контекст.

  • Дескриптор контекста объявляется как возвращаемое значение, а подпрограмма сервера возвращает не null для дескриптора контекста, и маршалинг завершается сбоем до маршалирования дескриптора контекста.

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