|
|
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
62: ipc_notify_init_port_deleted(n)
63: mach_port_deleted_notification_t *n;
64: {
65: mach_msg_header_t *m = &n->not_header;
66: mach_msg_type_t *t = &n->not_type;
67:
68: m->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0);
69: m->msgh_size = sizeof *n;
70: m->msgh_seqno = NOTIFY_MSGH_SEQNO;
71: m->msgh_local_port = MACH_PORT_NULL;
72: m->msgh_remote_port = MACH_PORT_NULL;
73: m->msgh_id = MACH_NOTIFY_PORT_DELETED;
74:
75: t->msgt_name = MACH_MSG_TYPE_PORT_NAME;
76: t->msgt_size = PORT_T_SIZE_IN_BITS;
77: t->msgt_number = 1;
78: t->msgt_inline = TRUE;
79: t->msgt_longform = FALSE;
80: t->msgt_deallocate = FALSE;
81: t->msgt_unused = 0;
82:
83: n->not_port = MACH_PORT_NULL;
84: }
85:
86: /*
87: * Routine: ipc_notify_init_msg_accepted
88: * Purpose:
89: * Initialize a template for msg-accepted notifications.
90: */
91:
92: void
93: ipc_notify_init_msg_accepted(n)
94: mach_msg_accepted_notification_t *n;
95: {
96: mach_msg_header_t *m = &n->not_header;
97: mach_msg_type_t *t = &n->not_type;
98:
99: m->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0);
100: m->msgh_size = sizeof *n;
101: m->msgh_seqno = NOTIFY_MSGH_SEQNO;
102: m->msgh_local_port = MACH_PORT_NULL;
103: m->msgh_remote_port = MACH_PORT_NULL;
104: m->msgh_id = MACH_NOTIFY_MSG_ACCEPTED;
105:
106: t->msgt_name = MACH_MSG_TYPE_PORT_NAME;
107: t->msgt_size = PORT_T_SIZE_IN_BITS;
108: t->msgt_number = 1;
109: t->msgt_inline = TRUE;
110: t->msgt_longform = FALSE;
111: t->msgt_deallocate = FALSE;
112: t->msgt_unused = 0;
113:
114: n->not_port = MACH_PORT_NULL;
115: }
116:
117: /*
118: * Routine: ipc_notify_init_port_destroyed
119: * Purpose:
120: * Initialize a template for port-destroyed notifications.
121: */
122:
123: void
124: ipc_notify_init_port_destroyed(
125: mach_port_destroyed_notification_t *n)
126: {
127: mach_msg_header_t *m = &n->not_header;
128: mach_msg_type_t *t = &n->not_type;
129:
130: m->msgh_bits = MACH_MSGH_BITS_COMPLEX |
131: MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0);
132: m->msgh_size = sizeof *n;
133: m->msgh_seqno = NOTIFY_MSGH_SEQNO;
134: m->msgh_local_port = MACH_PORT_NULL;
135: m->msgh_remote_port = MACH_PORT_NULL;
136: m->msgh_id = MACH_NOTIFY_PORT_DESTROYED;
137:
138: t->msgt_name = MACH_MSG_TYPE_PORT_RECEIVE;
139: t->msgt_size = PORT_T_SIZE_IN_BITS;
140: t->msgt_number = 1;
141: t->msgt_inline = TRUE;
142: t->msgt_longform = FALSE;
143: t->msgt_deallocate = FALSE;
144: t->msgt_unused = 0;
145:
146: n->not_port = MACH_PORT_NULL;
147: }
148:
149: /*
150: * Routine: ipc_notify_init_no_senders
151: * Purpose:
152: * Initialize a template for no-senders notifications.
153: */
154:
155: void
156: ipc_notify_init_no_senders(
157: mach_no_senders_notification_t *n)
158: {
159: mach_msg_header_t *m = &n->not_header;
160: mach_msg_type_t *t = &n->not_type;
161:
162: m->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0);
163: m->msgh_size = sizeof *n;
164: m->msgh_seqno = NOTIFY_MSGH_SEQNO;
165: m->msgh_local_port = MACH_PORT_NULL;
166: m->msgh_remote_port = MACH_PORT_NULL;
167: m->msgh_id = MACH_NOTIFY_NO_SENDERS;
168:
169: t->msgt_name = MACH_MSG_TYPE_INTEGER_32;
170: t->msgt_size = PORT_T_SIZE_IN_BITS;
171: t->msgt_number = 1;
172: t->msgt_inline = TRUE;
173: t->msgt_longform = FALSE;
174: t->msgt_deallocate = FALSE;
175: t->msgt_unused = 0;
176:
177: n->not_count = 0;
178: }
179:
180: /*
181: * Routine: ipc_notify_init_send_once
182: * Purpose:
183: * Initialize a template for send-once notifications.
184: */
185:
186: void
187: ipc_notify_init_send_once(
188: mach_send_once_notification_t *n)
189: {
190: mach_msg_header_t *m = &n->not_header;
191:
192: m->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0);
193: m->msgh_size = sizeof *n;
194: m->msgh_seqno = NOTIFY_MSGH_SEQNO;
195: m->msgh_local_port = MACH_PORT_NULL;
196: m->msgh_remote_port = MACH_PORT_NULL;
197: m->msgh_id = MACH_NOTIFY_SEND_ONCE;
198: }
199:
200: /*
201: * Routine: ipc_notify_init_dead_name
202: * Purpose:
203: * Initialize a template for dead-name notifications.
204: */
205:
206: void
207: ipc_notify_init_dead_name(
208: mach_dead_name_notification_t *n)
209: {
210: mach_msg_header_t *m = &n->not_header;
211: mach_msg_type_t *t = &n->not_type;
212:
213: m->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0);
214: m->msgh_size = sizeof *n;
215: m->msgh_seqno = NOTIFY_MSGH_SEQNO;
216: m->msgh_local_port = MACH_PORT_NULL;
217: m->msgh_remote_port = MACH_PORT_NULL;
218: m->msgh_id = MACH_NOTIFY_DEAD_NAME;
219:
220: t->msgt_name = MACH_MSG_TYPE_PORT_NAME;
221: t->msgt_size = PORT_T_SIZE_IN_BITS;
222: t->msgt_number = 1;
223: t->msgt_inline = TRUE;
224: t->msgt_longform = FALSE;
225: t->msgt_deallocate = FALSE;
226: t->msgt_unused = 0;
227:
228: n->not_port = MACH_PORT_NULL;
229: }
230:
231: /*
232: * Routine: ipc_notify_init
233: * Purpose:
234: * Initialize the notification subsystem.
235: */
236:
237: void
238: ipc_notify_init(void)
239: {
240: ipc_notify_init_port_deleted(&ipc_notify_port_deleted_template);
241: ipc_notify_init_msg_accepted(&ipc_notify_msg_accepted_template);
242: ipc_notify_init_port_destroyed(&ipc_notify_port_destroyed_template);
243: ipc_notify_init_no_senders(&ipc_notify_no_senders_template);
244: ipc_notify_init_send_once(&ipc_notify_send_once_template);
245: ipc_notify_init_dead_name(&ipc_notify_dead_name_template);
246: }
247:
248: /*
249: * Routine: ipc_notify_port_deleted
250: * Purpose:
251: * Send a port-deleted notification.
252: * Conditions:
253: * Nothing locked.
254: * Consumes a ref/soright for port.
255: */
256:
257: void
258: ipc_notify_port_deleted(port, name)
259: ipc_port_t port;
260: mach_port_t name;
261: {
262: ipc_kmsg_t kmsg;
263: mach_port_deleted_notification_t *n;
264:
265: kmsg = ikm_alloc(sizeof *n);
266: if (kmsg == IKM_NULL) {
1.1.1.3 ! root 267: printf("dropped port-deleted (0x%p, 0x%lx)\n", port, name);
1.1 root 268: ipc_port_release_sonce(port);
269: return;
270: }
271:
272: ikm_init(kmsg, sizeof *n);
273: n = (mach_port_deleted_notification_t *) &kmsg->ikm_header;
274: *n = ipc_notify_port_deleted_template;
275:
276: n->not_header.msgh_remote_port = (mach_port_t) port;
277: n->not_port = name;
278:
279: ipc_mqueue_send_always(kmsg);
280: }
281:
282: /*
283: * Routine: ipc_notify_msg_accepted
284: * Purpose:
285: * Send a msg-accepted notification.
286: * Conditions:
287: * Nothing locked.
288: * Consumes a ref/soright for port.
289: */
290:
291: void
292: ipc_notify_msg_accepted(port, name)
293: ipc_port_t port;
294: mach_port_t name;
295: {
296: ipc_kmsg_t kmsg;
297: mach_msg_accepted_notification_t *n;
298:
299: kmsg = ikm_alloc(sizeof *n);
300: if (kmsg == IKM_NULL) {
1.1.1.3 ! root 301: printf("dropped msg-accepted (0x%p, 0x%lx)\n", port, name);
1.1 root 302: ipc_port_release_sonce(port);
303: return;
304: }
305:
306: ikm_init(kmsg, sizeof *n);
307: n = (mach_msg_accepted_notification_t *) &kmsg->ikm_header;
308: *n = ipc_notify_msg_accepted_template;
309:
310: n->not_header.msgh_remote_port = (mach_port_t) port;
311: n->not_port = name;
312:
313: ipc_mqueue_send_always(kmsg);
314: }
315:
316: /*
317: * Routine: ipc_notify_port_destroyed
318: * Purpose:
319: * Send a port-destroyed notification.
320: * Conditions:
321: * Nothing locked.
322: * Consumes a ref/soright for port.
323: * Consumes a ref for right, which should be a receive right
324: * prepped for placement into a message. (In-transit,
325: * or in-limbo if a circularity was detected.)
326: */
327:
328: void
329: ipc_notify_port_destroyed(port, right)
330: ipc_port_t port;
331: ipc_port_t right;
332: {
333: ipc_kmsg_t kmsg;
334: mach_port_destroyed_notification_t *n;
335:
336: kmsg = ikm_alloc(sizeof *n);
337: if (kmsg == IKM_NULL) {
1.1.1.3 ! root 338: printf("dropped port-destroyed (0x%p, 0x%p)\n",
1.1 root 339: port, right);
340: ipc_port_release_sonce(port);
341: ipc_port_release_receive(right);
342: return;
343: }
344:
345: ikm_init(kmsg, sizeof *n);
346: n = (mach_port_destroyed_notification_t *) &kmsg->ikm_header;
347: *n = ipc_notify_port_destroyed_template;
348:
349: n->not_header.msgh_remote_port = (mach_port_t) port;
350: n->not_port = (mach_port_t) right;
351:
352: ipc_mqueue_send_always(kmsg);
353: }
354:
355: /*
356: * Routine: ipc_notify_no_senders
357: * Purpose:
358: * Send a no-senders notification.
359: * Conditions:
360: * Nothing locked.
361: * Consumes a ref/soright for port.
362: */
363:
364: void
365: ipc_notify_no_senders(port, mscount)
366: ipc_port_t port;
367: mach_port_mscount_t mscount;
368: {
369: ipc_kmsg_t kmsg;
370: mach_no_senders_notification_t *n;
371:
372: kmsg = ikm_alloc(sizeof *n);
373: if (kmsg == IKM_NULL) {
1.1.1.3 ! root 374: printf("dropped no-senders (0x%p, %u)\n", port, mscount);
1.1 root 375: ipc_port_release_sonce(port);
376: return;
377: }
378:
379: ikm_init(kmsg, sizeof *n);
380: n = (mach_no_senders_notification_t *) &kmsg->ikm_header;
381: *n = ipc_notify_no_senders_template;
382:
383: n->not_header.msgh_remote_port = (mach_port_t) port;
384: n->not_count = mscount;
385:
386: ipc_mqueue_send_always(kmsg);
387: }
388:
389: /*
390: * Routine: ipc_notify_send_once
391: * Purpose:
392: * Send a send-once notification.
393: * Conditions:
394: * Nothing locked.
395: * Consumes a ref/soright for port.
396: */
397:
398: void
399: ipc_notify_send_once(port)
400: ipc_port_t port;
401: {
402: ipc_kmsg_t kmsg;
403: mach_send_once_notification_t *n;
404:
405: kmsg = ikm_alloc(sizeof *n);
406: if (kmsg == IKM_NULL) {
1.1.1.3 ! root 407: printf("dropped send-once (0x%p)\n", port);
1.1 root 408: ipc_port_release_sonce(port);
409: return;
410: }
411:
412: ikm_init(kmsg, sizeof *n);
413: n = (mach_send_once_notification_t *) &kmsg->ikm_header;
414: *n = ipc_notify_send_once_template;
415:
416: n->not_header.msgh_remote_port = (mach_port_t) port;
417:
418: ipc_mqueue_send_always(kmsg);
419: }
420:
421: /*
422: * Routine: ipc_notify_dead_name
423: * Purpose:
424: * Send a dead-name notification.
425: * Conditions:
426: * Nothing locked.
427: * Consumes a ref/soright for port.
428: */
429:
430: void
431: ipc_notify_dead_name(port, name)
432: ipc_port_t port;
433: mach_port_t name;
434: {
435: ipc_kmsg_t kmsg;
436: mach_dead_name_notification_t *n;
437:
438: kmsg = ikm_alloc(sizeof *n);
439: if (kmsg == IKM_NULL) {
1.1.1.3 ! root 440: printf("dropped dead-name (0x%p, 0x%lx)\n", port, name);
1.1 root 441: ipc_port_release_sonce(port);
442: return;
443: }
444:
445: ikm_init(kmsg, sizeof *n);
446: n = (mach_dead_name_notification_t *) &kmsg->ikm_header;
447: *n = ipc_notify_dead_name_template;
448:
449: n->not_header.msgh_remote_port = (mach_port_t) port;
450: n->not_port = name;
451:
452: ipc_mqueue_send_always(kmsg);
453: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.