Атрибут DOOR_UNREF для серверов

Атрибут DOOR_UNREF для серверов

В разделе 15.3 мы отметили, что при вызове door_create для создаваемой двери можно указать атрибут DOOR_UNREF. В документации говорится, что если количество дескрипторов, относящихся к этой двери, уменьшается с двух до одного, осуществляется специальный вызов процедуры сервера. Особенность вызова заключается в том, что второй аргумент процедуры сервера (указатель на данные) при этом является константой DOOR_UNREF_DATA. Мы продемонстрируем три способа обращения к двери.

1. Дескриптор, возвращаемый door_create, считается первой ссылкой на эту дверь. Вообще говоря, причина, по которой специальный вызов происходит при изменении количества дескрипторов с 2 на 1, а не с 1 на 0, заключается в том, что первый дескриптор обычно не закрывается сервером до завершения работы.

2. Полное имя, связанное с дверью в файловой системе, также считается ссылкой на дверь. Ее можно удалить вызовом функции fdetach, или запустив программу fdetach, или удалив полное имя из файловой системы (функцией unlink или командой rm).

3.  Дескриптор, возвращаемый клиенту функцией open, считается открытой ссылкой до тех пор, пока не будет закрыт либо явным вызовом close, либо неявно, при завершении клиента. Во всех примерах этой главы дескриптор закрывается неявно.

Первый пример показывает, что если сервер закрывает свой дескриптор после вызова fattach, немедленно происходит специальный вызов процедуры сервера. В листинге 15.13 приведен текст процедуры сервера и функции main.

Листинг 15.13. Процедура сервера, обрабатывающая специальный вызов

//doors/serverunref1.c

1  #include "unpipc.h"

2  void

3  servproc(void *cookie, char *dataptr, size_t datasize,

4   door_desc_t *descptr, size_t ndesc)

5  {

6   long arg, result;

7   if (dataptr == DOOR_UNREF_DATA) {

8    printf("door unreferenced ");

9    Door_return(NULL, 0, NULL, 0);

10  }

11  arg = *((long*)dataptr);

12  printf("thread id %ld, arg = %ld ", pr_thread_id(NULL), arg);

13  sleep(6);

14  result = arg * arg;

15  Door_return((char *)&result, sizeof(result), NULL, 0);

16 }

17 int

18 main(int argc, char **argv)

19 {

20  int fd;

21  if (argc != 2)

22   err_quit("usage: server1 <server-pathname>");

23  /* создание дескриптора и связывание с файлом */

24  fd = Door_create(servproc, NULL, DOOR_UNREF);

25  unlink(argv[1]);

26  Close(Open(argv[1], O_CREAT | O_RDWR, FILE_MODE));

27  Fattach(fd, argv[1]);

28  Close(fd);

29  /* процедура servproc() обрабатывает все запросы клиентов */

30  for(;;)

31   pause();

32 }

7-10 Процедура сервера распознает специальный вызов и выводит сообщение об этом. Возврат из специального вызова происходит путем вызова door_return с двумя нулевыми указателями и нулевыми значениями размеров.

28 Теперь мы закрываем дескриптор двери после выполнения fattach. Этот дескриптор может быть нужен серверу только для вызовов door_bind, doo_info и door_revoke.

Запустив сервер, мы увидим, что немедленно произойдет специальный вызов:

solaris % serverunref1 /tmp/door1

door unreferenced

Если мы проследим за значением счетчика открытых дескрипторов, мы увидим, что он становится равен 1 после возврата из door_create и 2 после возврата из fattach. Вызов close уменьшает количество открытых дескрипторов с двух до одного, что приводит к специальному вызову процедуры. Единственная оставшаяся ссылка при этом представляет собой имя в файловой системе, а этого клиенту достаточно, чтобы обратиться к двери. Поэтому клиент продолжает работать правильно:

solaris % clientunref1 /tmp/door1 11

result: 121

solaris % clientunref1 /tmp/door1 22

result: 484

Более того, дальнейших специальных вызовов серверной процедуры не происходит. Для каждой двери осуществляется только один специальный вызов.

Теперь изменим нашу программу-сервер обратно, убрав вызов close для дескриптора двери. Процедура сервера и функция main приведены в листинге 15.14.

Листинг 15.14. Сервер, не закрывающий дескриптор двери

//doors/serverunref2.c

1  #include "unpipc.h"

2  void

3  servproc(void *cookie. char *dataptr, size_t datasize,

4   door_desc_t *descptr, size_t ndesc)

5  {

6   long arg, result;

7   if (dataptr == DOOR_UNREF_DATA) {

8    printf("door unreferenced ");

9    Door_return(NULL, 0, NULL, 0);

10  }

11  arg = *((long *)dataptr);

12  printf("thread id %ld, arg = %ld ", pr_thread_id(NULL), arg);

13  sleep(6);

14  result = arg * arg;

15  printf("thread id %ld returning ", pr_thread_id(NULL));

16  Door_return((char *)&result, sizeof(result), NULL, 0);

17 }

18 int

19 main(int argc, char **argv)

20 {

21  int fd;

23  if (argc != 2)

24   err_quit("usage: server1 <server-pathname>");

25  /* создание двери, дескриптора и подключение к файлу */

26  fd = Door_create(servproc, NULL, DOOR_UNREF);

27  unlink(argv[1]);

28  Close(Open(argv[1], O_CREAT | O_RDWR, FILE_MODE));

29  Fattach(fd, argv[1]);

30  /* servproc() обрабатывает все запросы клиентов */

31  for(;;)

32   pause();

33 }

Мы оставляем 6-секундную паузу и выводим сообщение о возврате из процедуры сервера. Запустим сервер в одном окне, а из другого проверим существование имени файла двери в файловой системе и удалим его с помощью rm:

solaris % ls –l /tmp/door2

Drw-r--r-- 1 rstevens other1 0 Apr 16 08:58 /tmp/door2

solaris % rm /tmp/door2

После удаления имени файла происходит специальный вызов процедуры сервера:

solaris % serverunref2 /trap/door2

door unreferenced после удаления файла из файловой системы

Если мы проследим за количеством ссылок на эту дверь, то увидим следующее: одна ссылка появляется после вызова door_create, вторая — после fattach. После удаления файла с помощью rm количество ссылок снова уменьшается до единицы, что приводит к специальному вызову процедуры.

В последнем примере использования этого атрибута мы снова удалим имя из файловой системы. Но на этот раз мы сначала запустим три экземпляра программы-клиента. Специальный вызов процедуры произойдет только после завершения последнего клиента, потому что каждый экземпляр клиента увеличивает количество ссылок на дверь. Используем сервер из листинга 15.14 и клиент из листинга 15.2.

solaris % clientunref2 /tmp/door2 44 & clientunref2 /tmp/door2 55 & clientunref2/tmp/door2 55 &

[2] 13552

[3] 13553

[4] 13554

solaris % rm /tmp/door2 клиенты все еще выполняются

solaris % result: 1936

result: 3025

result: 4356

Сервер при этом выведет вот что:

solaris % serverunref2 /tmp/door2

thread id 4, arg = 44

thread id 5, arg = 55

thread id 6, arg = 66

thread id 4 returning

thread id 5 returning

thread id 6 returning

door unreferenced

Проследим за значением счетчика открытых ссылок для этой двери. Он становится равным 1 после вызова door_create, 2 после вызова fattach. Когда три клиента вызывают open, счетчик увеличивается с 2 до 5. После удаления имени файла счетчик уменьшается до 4. После завершения работы трех клиентов счетчик уменьшается с 4 до 1 (последовательно), и последнее его изменение с 2 до 1 приводит к специальному вызову процедуры.

Этими примерами мы показали, что хотя описание атрибута DOOR_UNREF выглядит просто («специальный вызов происходит при изменении счетчика ссылок с 2 до 1»), мы должны понимать принципы работы этого счетчика, чтобы им пользоваться.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

Атрибут Obsolete в действии

Из книги Язык программирования С# 2005 и платформа .NET 2.0. [3-е издание] автора Троелсен Эндрю

Атрибут Obsolete в действии Теперь, когда класс HorseAndBuggy обозначен как устаревший, при размещении экземпляра этого типа вы должны увидеть соответствующую строку в сообщении, появившемся в окне со списком ошибок Visual Studio 2005 (рис. 12.7). Рис. 12.7. Атрибуты в действииВ данном случае


Атрибут [WebService]

Из книги TCP/IP Архитектура, протоколы, реализация (включая IP версии 6 и IP Security) автора Фейт Сидни М

Атрибут [WebService] Класс Web-сервиса XML может быть помечен необязательным атрибутом [WebService] (не путайте его с базовым классом WebService). Этот атрибут поддерживает ряд именованных свойств, первым из которых является Namespace. Это свойство можно использовать для указания пространства


Атрибут [WebServiceBinding]

Из книги Сетевые средства Linux автора Смит Родерик В.

Атрибут [WebServiceBinding] В .NET 2.0 Web-сервис XML может содержать атрибут [WebServiceBinding]. Среди прочего этот атрибут используется для того, чтобы указать соответствие данного Web-сервиса XML "базовому профилю совместимости Web-сервисов (WSI) версии 1.1". Но что это значит? Если вы активно


Атрибут [WebMethod]

Из книги Технология XSLT автора Валиков Алексей Николаевич

Атрибут [WebMethod] Атрибут [WebMethod] должен указываться для каждого метода, который вы хотите сделать доступным в рамках данного Web-сервиса XML. Как и большинство других атрибутов, тип WebMethodAttiibute может иметь целый ряд необязательных именованных свойств. Давайте рассмотрим каждую


12.11.2 Размещение серверов DNS

Из книги Компьютерра PDA N177 (09.06.2012-15.06.2012) автора Журнал «Компьютерра»

12.11.2 Размещение серверов DNS Многие организации предпочитают иметь в своей внутренней сети один комплект из первичного и вторичного серверов, даже если сеть разделена на отдельные зоны. Вполне допустимо использовать один сервер для множества зон (или для нескольких


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

Из книги Фотоприколы с помощью Photoshop автора Гурский Юрий Анатольевич

Использование серверов NFS Как правило, серверы NFS применяются для разделения файлов в системах UNIX и Linux. Необходимость в совместном доступе к файлам может возникнуть по разным причинам. Возможно, вы захотите хранить на сервере программы большого объема для того, чтобы их


Отключение серверов

Из книги Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ автора Борри Хелен

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


Атрибут

Из книги HTML, XHTML и CSS на 100% автора Квинт Игорь


Атрибут xsl:use-attribute-sets

Из книги автора

Атрибут xsl:use-attribute-sets Мы упомянули о том, что именованные наборы атрибутов используются в элементах посредством атрибута xsl:use-attribute-sets. Разберем более детально, где этот атрибут может применяться, и какие функции он при этом выполняет. Для удобства эти данные сведены в


Урок 10 Слои как необходимый атрибут многослойных изображений

Из книги автора

Урок 10 Слои как необходимый атрибут многослойных изображений До нынешнего момента мы рассматривали изображения как нечто скучное и плоское, что-то напоминающее лист бумаги. На самом же деле они могут иметь гораздо более сложную форму. Вспомните такую вещь, как


Атрибут DEFAULT

Из книги автора

Атрибут DEFAULT Домен может определять значение по умолчанию, которое сервер будет использовать при добавлении новой строки, если оператор INSERT не содержит этот столбец в списке столбцов. Значения по умолчанию могут сэкономить время и избавить от ошибок в процессе ввода


Атрибут NOT NULL

Из книги автора

Атрибут NOT NULL Включите этот атрибут в описание домена, если вы хотите, чтобы все столбцы, создаваемые на основе этого домена, имели непустое значение.NULL - который является не значением, а состоянием, - всегда будет недопустимым для любого столбца, имеющего атрибут NOT NULL.


Атрибут CHARSET/CHARACTER SET

Из книги автора

Атрибут CHARSET/CHARACTER SET Для систем, которым нужно множество наборов символов внутри одной базы данных, объявление доменов, связанных с наборами символов для всех ваших символьных столбцов (CHAR, VARCHAR SUB_TYPE 1 и массивов символьных типов), может быть очень элегантным способом


Атрибут COLLATE

Из книги автора

Атрибут COLLATE Предложение COLLATE в операторе создания домена задает явную последовательность сортировки для доменов CHAR и VARCHAR. Вы должны выбрать порядок сортировки, который поддерживается набором символов, объявленным наследуемыми и предполагаемым для домена.Синтаксис


Атрибут

Из книги автора

Атрибут С помощью атрибутов можно указывать различные способы отображения информации, добавляемой с помощью одинаковых элементов, а в некоторых случаях применение элемента без атрибутов не дает результатов. Например, в одном абзаце нужно выровнять текст по левому краю,