По сравнению с листингом 15.2 было внесено четыре изменения: 1. Убрано объявление дескриптора двери fd (теперь это глобальная переменная, описанная в листинге 15.18). 2. Вызов door_create защищен взаимным исключением (также описанным в листинге 15.18). 3. Вызов door_server_create делается перед созданием двери, при этом указывается процедура создания сервера (my_thread, которая, будет показана позже). 4. В вызове door_create последний аргумент (атрибуты) имеет значение DOOR_PRIVATE вместо 0. Это говорит библиотеке о том, что данная дверь будет иметь собственный пул потоков, называемый частным пулом сервера. Задание процедуры создания сервера с помощью door_server_create и выделение частного пула сервера с помощью DOOR_PRIVATE осуществляются независимо друг от друга. Возможны четыре ситуации: 1. По умолчанию частный пул сервера и процедура создания сервера отсутствуют. Система создает потоки по мере необходимости и они переходят в пул потоков процесса. 2. Указан флаг DOOR_PRIVATE, но процедура создания сервера отсутствует. Система создает потоки по мере необходимости и они отходят в пул потоков процесса, если относятся к тем дверям, для которых флаг DOOR_PRIVATE не был указан, либо в пул данной двери, если она была создана с флагом DOOR_PRIVATE. 3. Отсутствует частный пул сервера, но указана процедура создания сервера. Процедура создания вызывается при необходимости создания нового потока, который затем переходит в пул потоков процесса. 4. Указан флаг DOOR_PRIVATE и процедура создания сервера. Процедура создания сервера вызывается каждый раз при необходимости создания потока. После создания поток должен вызвать door_bind для отнесения его к нужному частному пулу сервера, иначе он будет добавлен к пулу потоков процесса. В листинге 15.18 приведен текст двух новых функций: my_create (процедура создания сервера) и my_thread (функция, выполняемая каждым потоком, который создается my_create).Листинг 15.17. Функция main для примера с управлением пулом потоков
//doors/server6.c
42 int
43 main(int argc, char **argv)
44 {
45 if (argc != 2)
46 err_quit("usage: server6
47 Door_server_create(my_create);
48 /* создание дескриптора двери и связывание его с именем */
49 Pthread_mutex_lock(&fdlock);
50 fd = Door_create(servproc, NULL, DOOR_PRIVATE);
51 Pthread_mutex_unlock(&fdlock);
52 unlink(argv[1]);
53 Close(Open(argv[1], O_CREAT | O_RDWR, FILE_MODE));
54 Fattach(fd, argv[1]);
55 /* servproc() обслуживает запросы клиентов */
56 for(;;)
57 pause();
58 }