|
|
1.1.1.2 root 1: /*
1.1 root 2: * Mach Operating System
3: * Copyright (c) 1991,1990,1989 Carnegie Mellon University
4: * All Rights Reserved.
1.1.1.2 root 5: *
1.1 root 6: * Permission to use, copy, modify and distribute this software and its
7: * documentation is hereby granted, provided that both the copyright
8: * notice and this permission notice appear in all copies of the
9: * software, derivative works or modified versions, and any portions
10: * thereof, and that both notices appear in supporting documentation.
1.1.1.2 root 11: *
1.1 root 12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
1.1.1.2 root 15: *
1.1 root 16: * Carnegie Mellon requests users of this software to return to
1.1.1.2 root 17: *
1.1 root 18: * Software Distribution Coordinator or [email protected]
19: * School of Computer Science
20: * Carnegie Mellon University
21: * Pittsburgh PA 15213-3890
1.1.1.2 root 22: *
1.1 root 23: * any improvements or extensions that they make and grant Carnegie Mellon
24: * the rights to redistribute these changes.
25: */
26: /*
27: * File: ipc/ipc_notify.c
28: * Author: Rich Draves
29: * Date: 1989
30: *
31: * Notification-sending functions.
32: */
33:
1.1.1.3 root 34: #include <kern/printf.h>
1.1 root 35: #include <mach/port.h>
36: #include <mach/message.h>
37: #include <mach/notify.h>
38: #include <kern/assert.h>
39: #include <ipc/ipc_kmsg.h>
40: #include <ipc/ipc_mqueue.h>
41: #include <ipc/ipc_notify.h>
42: #include <ipc/ipc_port.h>
43:
44: #include <ipc/ipc_machdep.h>
45:
46: mach_port_deleted_notification_t ipc_notify_port_deleted_template;
47: mach_msg_accepted_notification_t ipc_notify_msg_accepted_template;
48: mach_port_destroyed_notification_t ipc_notify_port_destroyed_template;
49: mach_no_senders_notification_t ipc_notify_no_senders_template;
50: mach_send_once_notification_t ipc_notify_send_once_template;
51: mach_dead_name_notification_t ipc_notify_dead_name_template;
52:
53: #define NOTIFY_MSGH_SEQNO 0
54:
55: /*
56: * Routine: ipc_notify_init_port_deleted
57: * Purpose:
58: * Initialize a template for port-deleted notifications.
59: */
60:
61: void
1.1.1.4 ! root 62: ipc_notify_init_port_deleted(mach_port_deleted_notification_t *n)
1.1 root 63: {
64: mach_msg_header_t *m = &n->not_header;
65: mach_msg_type_t *t = &n->not_type;
66:
67: m->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0);
68: m->msgh_size = sizeof *n;
69: m->msgh_seqno = NOTIFY_MSGH_SEQNO;
70: m->msgh_local_port = MACH_PORT_NULL;
71: m->msgh_remote_port = MACH_PORT_NULL;
72: m->msgh_id = MACH_NOTIFY_PORT_DELETED;
73:
74: t->msgt_name = MACH_MSG_TYPE_PORT_NAME;
75: t->msgt_size = PORT_T_SIZE_IN_BITS;
76: t->msgt_number = 1;
77: t->msgt_inline = TRUE;
78: t->msgt_longform = FALSE;
79: t->msgt_deallocate = FALSE;
80: t->msgt_unused = 0;
81:
82: n->not_port = MACH_PORT_NULL;
83: }
84:
85: /*
86: * Routine: ipc_notify_init_msg_accepted
87: * Purpose:
88: * Initialize a template for msg-accepted notifications.
89: */
90:
91: void
1.1.1.4 ! root 92: ipc_notify_init_msg_accepted(mach_msg_accepted_notification_t *n)
1.1 root 93: {
94: mach_msg_header_t *m = &n->not_header;
95: mach_msg_type_t *t = &n->not_type;
96:
97: m->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0);
98: m->msgh_size = sizeof *n;
99: m->msgh_seqno = NOTIFY_MSGH_SEQNO;
100: m->msgh_local_port = MACH_PORT_NULL;
101: m->msgh_remote_port = MACH_PORT_NULL;
102: m->msgh_id = MACH_NOTIFY_MSG_ACCEPTED;
103:
104: t->msgt_name = MACH_MSG_TYPE_PORT_NAME;
105: t->msgt_size = PORT_T_SIZE_IN_BITS;
106: t->msgt_number = 1;
107: t->msgt_inline = TRUE;
108: t->msgt_longform = FALSE;
109: t->msgt_deallocate = FALSE;
110: t->msgt_unused = 0;
111:
112: n->not_port = MACH_PORT_NULL;
113: }
114:
115: /*
116: * Routine: ipc_notify_init_port_destroyed
117: * Purpose:
118: * Initialize a template for port-destroyed notifications.
119: */
120:
121: void
1.1.1.4 ! root 122: ipc_notify_init_port_destroyed(mach_port_destroyed_notification_t *n)
1.1 root 123: {
124: mach_msg_header_t *m = &n->not_header;
125: mach_msg_type_t *t = &n->not_type;
126:
127: m->msgh_bits = MACH_MSGH_BITS_COMPLEX |
128: MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0);
129: m->msgh_size = sizeof *n;
130: m->msgh_seqno = NOTIFY_MSGH_SEQNO;
131: m->msgh_local_port = MACH_PORT_NULL;
132: m->msgh_remote_port = MACH_PORT_NULL;
133: m->msgh_id = MACH_NOTIFY_PORT_DESTROYED;
134:
135: t->msgt_name = MACH_MSG_TYPE_PORT_RECEIVE;
136: t->msgt_size = PORT_T_SIZE_IN_BITS;
137: t->msgt_number = 1;
138: t->msgt_inline = TRUE;
139: t->msgt_longform = FALSE;
140: t->msgt_deallocate = FALSE;
141: t->msgt_unused = 0;
142:
143: n->not_port = MACH_PORT_NULL;
144: }
145:
146: /*
147: * Routine: ipc_notify_init_no_senders
148: * Purpose:
149: * Initialize a template for no-senders notifications.
150: */
151:
152: void
153: ipc_notify_init_no_senders(
154: mach_no_senders_notification_t *n)
155: {
156: mach_msg_header_t *m = &n->not_header;
157: mach_msg_type_t *t = &n->not_type;
158:
159: m->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0);
160: m->msgh_size = sizeof *n;
161: m->msgh_seqno = NOTIFY_MSGH_SEQNO;
162: m->msgh_local_port = MACH_PORT_NULL;
163: m->msgh_remote_port = MACH_PORT_NULL;
164: m->msgh_id = MACH_NOTIFY_NO_SENDERS;
165:
166: t->msgt_name = MACH_MSG_TYPE_INTEGER_32;
167: t->msgt_size = PORT_T_SIZE_IN_BITS;
168: t->msgt_number = 1;
169: t->msgt_inline = TRUE;
170: t->msgt_longform = FALSE;
171: t->msgt_deallocate = FALSE;
172: t->msgt_unused = 0;
173:
174: n->not_count = 0;
175: }
176:
177: /*
178: * Routine: ipc_notify_init_send_once
179: * Purpose:
180: * Initialize a template for send-once notifications.
181: */
182:
183: void
184: ipc_notify_init_send_once(
185: mach_send_once_notification_t *n)
186: {
187: mach_msg_header_t *m = &n->not_header;
188:
189: m->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0);
190: m->msgh_size = sizeof *n;
191: m->msgh_seqno = NOTIFY_MSGH_SEQNO;
192: m->msgh_local_port = MACH_PORT_NULL;
193: m->msgh_remote_port = MACH_PORT_NULL;
194: m->msgh_id = MACH_NOTIFY_SEND_ONCE;
195: }
196:
197: /*
198: * Routine: ipc_notify_init_dead_name
199: * Purpose:
200: * Initialize a template for dead-name notifications.
201: */
202:
203: void
204: ipc_notify_init_dead_name(
205: mach_dead_name_notification_t *n)
206: {
207: mach_msg_header_t *m = &n->not_header;
208: mach_msg_type_t *t = &n->not_type;
209:
210: m->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0);
211: m->msgh_size = sizeof *n;
212: m->msgh_seqno = NOTIFY_MSGH_SEQNO;
213: m->msgh_local_port = MACH_PORT_NULL;
214: m->msgh_remote_port = MACH_PORT_NULL;
215: m->msgh_id = MACH_NOTIFY_DEAD_NAME;
216:
217: t->msgt_name = MACH_MSG_TYPE_PORT_NAME;
218: t->msgt_size = PORT_T_SIZE_IN_BITS;
219: t->msgt_number = 1;
220: t->msgt_inline = TRUE;
221: t->msgt_longform = FALSE;
222: t->msgt_deallocate = FALSE;
223: t->msgt_unused = 0;
224:
225: n->not_port = MACH_PORT_NULL;
226: }
227:
228: /*
229: * Routine: ipc_notify_init
230: * Purpose:
231: * Initialize the notification subsystem.
232: */
233:
234: void
235: ipc_notify_init(void)
236: {
237: ipc_notify_init_port_deleted(&ipc_notify_port_deleted_template);
238: ipc_notify_init_msg_accepted(&ipc_notify_msg_accepted_template);
239: ipc_notify_init_port_destroyed(&ipc_notify_port_destroyed_template);
240: ipc_notify_init_no_senders(&ipc_notify_no_senders_template);
241: ipc_notify_init_send_once(&ipc_notify_send_once_template);
242: ipc_notify_init_dead_name(&ipc_notify_dead_name_template);
243: }
244:
245: /*
246: * Routine: ipc_notify_port_deleted
247: * Purpose:
248: * Send a port-deleted notification.
249: * Conditions:
250: * Nothing locked.
251: * Consumes a ref/soright for port.
252: */
253:
254: void
1.1.1.4 ! root 255: ipc_notify_port_deleted(
! 256: ipc_port_t port,
! 257: mach_port_t name)
1.1 root 258: {
259: ipc_kmsg_t kmsg;
260: mach_port_deleted_notification_t *n;
261:
262: kmsg = ikm_alloc(sizeof *n);
263: if (kmsg == IKM_NULL) {
1.1.1.3 root 264: printf("dropped port-deleted (0x%p, 0x%lx)\n", port, name);
1.1 root 265: ipc_port_release_sonce(port);
266: return;
267: }
268:
269: ikm_init(kmsg, sizeof *n);
270: n = (mach_port_deleted_notification_t *) &kmsg->ikm_header;
271: *n = ipc_notify_port_deleted_template;
272:
273: n->not_header.msgh_remote_port = (mach_port_t) port;
274: n->not_port = name;
275:
276: ipc_mqueue_send_always(kmsg);
277: }
278:
279: /*
280: * Routine: ipc_notify_msg_accepted
281: * Purpose:
282: * Send a msg-accepted notification.
283: * Conditions:
284: * Nothing locked.
285: * Consumes a ref/soright for port.
286: */
287:
288: void
1.1.1.4 ! root 289: ipc_notify_msg_accepted(
! 290: ipc_port_t port,
! 291: mach_port_t name)
1.1 root 292: {
293: ipc_kmsg_t kmsg;
294: mach_msg_accepted_notification_t *n;
295:
296: kmsg = ikm_alloc(sizeof *n);
297: if (kmsg == IKM_NULL) {
1.1.1.3 root 298: printf("dropped msg-accepted (0x%p, 0x%lx)\n", port, name);
1.1 root 299: ipc_port_release_sonce(port);
300: return;
301: }
302:
303: ikm_init(kmsg, sizeof *n);
304: n = (mach_msg_accepted_notification_t *) &kmsg->ikm_header;
305: *n = ipc_notify_msg_accepted_template;
306:
307: n->not_header.msgh_remote_port = (mach_port_t) port;
308: n->not_port = name;
309:
310: ipc_mqueue_send_always(kmsg);
311: }
312:
313: /*
314: * Routine: ipc_notify_port_destroyed
315: * Purpose:
316: * Send a port-destroyed notification.
317: * Conditions:
318: * Nothing locked.
319: * Consumes a ref/soright for port.
320: * Consumes a ref for right, which should be a receive right
321: * prepped for placement into a message. (In-transit,
322: * or in-limbo if a circularity was detected.)
323: */
324:
325: void
1.1.1.4 ! root 326: ipc_notify_port_destroyed(
! 327: ipc_port_t port,
! 328: ipc_port_t right)
1.1 root 329: {
330: ipc_kmsg_t kmsg;
331: mach_port_destroyed_notification_t *n;
332:
333: kmsg = ikm_alloc(sizeof *n);
334: if (kmsg == IKM_NULL) {
1.1.1.3 root 335: printf("dropped port-destroyed (0x%p, 0x%p)\n",
1.1 root 336: port, right);
337: ipc_port_release_sonce(port);
338: ipc_port_release_receive(right);
339: return;
340: }
341:
342: ikm_init(kmsg, sizeof *n);
343: n = (mach_port_destroyed_notification_t *) &kmsg->ikm_header;
344: *n = ipc_notify_port_destroyed_template;
345:
346: n->not_header.msgh_remote_port = (mach_port_t) port;
347: n->not_port = (mach_port_t) right;
348:
349: ipc_mqueue_send_always(kmsg);
350: }
351:
352: /*
353: * Routine: ipc_notify_no_senders
354: * Purpose:
355: * Send a no-senders notification.
356: * Conditions:
357: * Nothing locked.
358: * Consumes a ref/soright for port.
359: */
360:
361: void
1.1.1.4 ! root 362: ipc_notify_no_senders(
! 363: ipc_port_t port,
! 364: mach_port_mscount_t mscount)
1.1 root 365: {
366: ipc_kmsg_t kmsg;
367: mach_no_senders_notification_t *n;
368:
369: kmsg = ikm_alloc(sizeof *n);
370: if (kmsg == IKM_NULL) {
1.1.1.3 root 371: printf("dropped no-senders (0x%p, %u)\n", port, mscount);
1.1 root 372: ipc_port_release_sonce(port);
373: return;
374: }
375:
376: ikm_init(kmsg, sizeof *n);
377: n = (mach_no_senders_notification_t *) &kmsg->ikm_header;
378: *n = ipc_notify_no_senders_template;
379:
380: n->not_header.msgh_remote_port = (mach_port_t) port;
381: n->not_count = mscount;
382:
383: ipc_mqueue_send_always(kmsg);
384: }
385:
386: /*
387: * Routine: ipc_notify_send_once
388: * Purpose:
389: * Send a send-once notification.
390: * Conditions:
391: * Nothing locked.
392: * Consumes a ref/soright for port.
393: */
394:
395: void
1.1.1.4 ! root 396: ipc_notify_send_once(ipc_port_t port)
1.1 root 397: {
398: ipc_kmsg_t kmsg;
399: mach_send_once_notification_t *n;
400:
401: kmsg = ikm_alloc(sizeof *n);
402: if (kmsg == IKM_NULL) {
1.1.1.3 root 403: printf("dropped send-once (0x%p)\n", port);
1.1 root 404: ipc_port_release_sonce(port);
405: return;
406: }
407:
408: ikm_init(kmsg, sizeof *n);
409: n = (mach_send_once_notification_t *) &kmsg->ikm_header;
410: *n = ipc_notify_send_once_template;
411:
412: n->not_header.msgh_remote_port = (mach_port_t) port;
413:
414: ipc_mqueue_send_always(kmsg);
415: }
416:
417: /*
418: * Routine: ipc_notify_dead_name
419: * Purpose:
420: * Send a dead-name notification.
421: * Conditions:
422: * Nothing locked.
423: * Consumes a ref/soright for port.
424: */
425:
426: void
1.1.1.4 ! root 427: ipc_notify_dead_name(
! 428: ipc_port_t port,
! 429: mach_port_t name)
1.1 root 430: {
431: ipc_kmsg_t kmsg;
432: mach_dead_name_notification_t *n;
433:
434: kmsg = ikm_alloc(sizeof *n);
435: if (kmsg == IKM_NULL) {
1.1.1.3 root 436: printf("dropped dead-name (0x%p, 0x%lx)\n", port, name);
1.1 root 437: ipc_port_release_sonce(port);
438: return;
439: }
440:
441: ikm_init(kmsg, sizeof *n);
442: n = (mach_dead_name_notification_t *) &kmsg->ikm_header;
443: *n = ipc_notify_dead_name_template;
444:
445: n->not_header.msgh_remote_port = (mach_port_t) port;
446: n->not_port = name;
447:
448: ipc_mqueue_send_always(kmsg);
449: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.