на главную | войти | регистрация | DMCA | контакты | справка | donate |      

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Э Ю Я


моя полка | жанры | рекомендуем | рейтинг книг | рейтинг авторов | впечатления | новое | форум | сборники | читалки | авторам | добавить



Листинг 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 ");

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.


Атрибут DOOR_UNREF для серверов | UNIX: взаимодействие процессов | Листинг 15.14. Сервер, не закрывающий дескриптор двери