34 sigqueue(mqhdr-mqh_pid, sigev-sigev_signo,
35 sigev-sigev_value);
36 }
37 mqhdr-mqh_pid = 0; /* снятие с регистрации */
38 }
39 } else if (attr-mq_curmsgs = attr-mq_maxmsg) {
40 /* 4queue is full */
41 if (mqinfo-mqi_flags O_NONBLOCK) {
32 errno = EAGAIN;
43 goto err;
44 }
45 /* ожидание освобождения места в очереди */
46 while (attr-mq_curmsgs = attr-mq_maxmsg)
47 pthread_cond_wait(mqhdr-mqh_wait, mqhdr-mqh_lock);
48 }
//my_pxmsg_mmap/mq_send.с
49 /* nmsghdr будет указывать на новое сообщение*/
50 if ((freeindex = mqhdr-mqh_free) == 0)
51 err_dump("mymq_send: curmsgs = %ld; free = 0", attr-mq_curmsgs);
52 nmsghdr = (struct mymsg_hdr *) mptr[freeindex];
53 nmsghdr-msg_prio = prio;
54 nmsghdr-msg_len = len;
55 memcpy(nmsghdr + 1, ptr, len); /* копирование сообщения в очередь */
56 mqhdr-mqh_free = nmsghdr-msg_next; /* новое начало списка пустых сообщений */
57 /* поиск места в списке для нового сообщения */
58 index = mqhdr-mqh_head;
59 pmsghdr = (struct mymsg_hdr *) (mqhdr-mqh_head);
60 while (index != 0) {
61 msghdr = (struct mymsg_hdr *) mptr[index];
62 if (prio msghdr-msg_prio) {
63 nmsghdr-msg_next = index;
64 pmsghdr-msg_next = freeindex;
65 break;
66 }
67 index = msghdr-msg_next;
68 pmsghdr = msghdr;
69 }
70 if (index == 0) {
71 /* очередь была пуста или новое письмо добавлено к концу списка */
72 pmsghdr-msg_next = freeindex;
73 nmsghdr-msg_next = 0;
74 }
75 /* запускаем любой из процессов, заблокированных в mq_receive */
76 if (attr-mq_curmsgs == 0)
77 pthread_cond_signal(mqhdr-mqh_wait);
78 attr-mq_curmsgs++;
79 pthread_mutex_unlock(mqhdr-mqh_lock);
80 return(0);
81 err:
82 pthread_mutex_unlock(mqhdr-mqh lock);
83 return(-1);
84 }
50-52 Поскольку количество свободных сообщений при создании очереди равно mq_maxmsg, ситуация, в которой mq_curmsgs будет меньше mq_maxmsg для пустого списка свободных сообщений, возникнуть не может.
53-56 Указатель nmsghdr хранит адрес области памяти, в которую помещается сообщение. Приоритет и длина сообщения сохраняются в структуре msg_hdr, а затем в память копируется содержимое сообщения, переданного вызвавшим процессом.
57-74 Порядок сообщений в нашем списке зависит от их приоритета: они расположены в порядке его убывания. При добавлении нового сообщения мы проверяем, существуют ли сообщения с тем же приоритетом; в этом случае сообщение добавляется после последнего из них. Используя такой метод упорядочения, мы гарантируем, что mq_receive всегда будет возвращать старейшее сообщение с наивысшим приоритетом. По мере продвижения по списку мы сохраняем в pmsghdr адрес предыдущего сообщения, поскольку именно это сообщение будет хранить индекс нового сообщения в поле msg_next.