Чтение онлайн

на главную - закладки

Жанры

UNIX: взаимодействие процессов

Стивенс Уильям Ричард

Шрифт:

sqrtproc: thread id 4, arg = 77

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

Атрибут 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\n");

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

10 }

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

12 printf("thread id %ld, arg = %ld\n", 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\n");

Поделиться:
Популярные книги

Казачий князь

Трофимов Ерофей
5. Шатун
Фантастика:
боевая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Казачий князь

Вперед в прошлое 7

Ратманов Денис
7. Вперед в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 7

Лекарь

Первухин Андрей Евгеньевич
1. Лекарь
Фантастика:
фэнтези
попаданцы
альтернативная история
7.50
рейтинг книги
Лекарь

Бестужев. Служба Государевой Безопасности. Книга третья

Измайлов Сергей
3. Граф Бестужев
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Бестужев. Служба Государевой Безопасности. Книга третья

Креститель

Прозоров Александр Дмитриевич
6. Ведун
Фантастика:
фэнтези
8.60
рейтинг книги
Креститель

История США от глубокой древности до 1918 года

Азимов Айзек
Популярная наука от Азимова
Научно-образовательная:
история
5.00
рейтинг книги
История США от глубокой древности до 1918 года

Герой

Бубела Олег Николаевич
4. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.26
рейтинг книги
Герой

Пески веков (сборник)

Уиндем Джон Паркс Лукас Бейнон Харрис
1970. Зарубежная фантастика
Фантастика:
научная фантастика
5.00
рейтинг книги
Пески веков (сборник)

Мистика

Гейман Нил
Детективы:
классические детективы
исторические детективы
7.29
рейтинг книги
Мистика

Инженер Петра Великого 2

Гросов Виктор
2. Инженер Петра Великого
Фантастика:
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Инженер Петра Великого 2

На границе империй. Том 7. Часть 2

INDIGO
8. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
6.13
рейтинг книги
На границе империй. Том 7. Часть 2

Поход

Валериев Игорь
4. Ермак
Фантастика:
боевая фантастика
альтернативная история
6.25
рейтинг книги
Поход

Сопротивление

Осадчук Алексей Витальевич
11. Последняя жизнь
Фантастика:
аниме
фэнтези
попаданцы
7.33
рейтинг книги
Сопротивление

Этот мир не выдержит меня. Том 2

Майнер Максим
2. Первый простолюдин в Академии
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Этот мир не выдержит меня. Том 2