diff options
Diffstat (limited to 'debian/patches/0002-Add-a-new-flavor-of-no-senders-notifications.patch')
-rw-r--r-- | debian/patches/0002-Add-a-new-flavor-of-no-senders-notifications.patch | 371 |
1 files changed, 371 insertions, 0 deletions
diff --git a/debian/patches/0002-Add-a-new-flavor-of-no-senders-notifications.patch b/debian/patches/0002-Add-a-new-flavor-of-no-senders-notifications.patch new file mode 100644 index 0000000..1178e8b --- /dev/null +++ b/debian/patches/0002-Add-a-new-flavor-of-no-senders-notifications.patch @@ -0,0 +1,371 @@ +From 25207576b2dca77da167c19a7ff16cf469acf1bc Mon Sep 17 00:00:00 2001 +From: Justus Winter <4winter@informatik.uni-hamburg.de> +Date: Sun, 7 Dec 2014 14:27:23 +0100 +Subject: [PATCH gnumach 2/2] Add a new flavor of no-senders notifications + +The no-senders notifications do not carry a port name. Add a new +flavor of no-senders notifications `MACH_NOTIFY_NO_SENDERS2' that does +carry the name of the port that lost the last sender. + +* include/mach/notify.defs (mach_notify_no_senders2): New simple routine. +* include/mach/notify.h (MACH_NOTIFY_NO_SENDERS2): New macro. +* ipc/ipc_notify.c (ipc_notify_no_senders2_template, +ipc_notify_init_no_senders2, ipc_notify_init): Initialize a template. +(ipc_notify_no_senders): Test whether a new-style notification has +been requested. +(ipc_notify_no_senders2): New function. +* ipc/ipc_notify.h (ipc_notify_no_senders2): New declaration. +(NSREQUEST_FLAG_NO_SENDERS2, NSREQUEST_FLAG_MASK, NSREQUEST_IPC_PORT, +NSREQUEST_HAS_FLAG, NSREQUEST_SET_FLAG): Machinery to store flags in +the least significant bits of the `nsrequest' field. +* ipc/ipc_port.c (ipc_port_nsrequest2): Add `new_style' parameter, +rename from `ipc_port_nsrequest', set flag if `new_style' is given, +and filter it from the returned `previous' port. +(ipc_port_nsrequest): New function. +(ipc_port_destroy): Filter out flags from `ip_nsrequest'. +* ipc/ipc_port.h (struct ipc_port): Document the use of flags. +(ipc_port_nsrequest2): New declaration. +* ipc/mach_port.c (mach_port_request_notification): Handle +MACH_NOTIFY_NO_SENDERS2. +--- + include/mach/notify.defs | 9 ++++++ + include/mach/notify.h | 11 +++++++ + ipc/ipc_notify.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++ + ipc/ipc_notify.h | 14 ++++++++ + ipc/ipc_port.c | 36 ++++++++++++++++++--- + ipc/ipc_port.h | 10 +++++- + ipc/mach_port.c | 6 ++-- + 7 files changed, 162 insertions(+), 8 deletions(-) + +diff --git a/include/mach/notify.defs b/include/mach/notify.defs +index 6ba4cde..06802ce 100644 +--- a/include/mach/notify.defs ++++ b/include/mach/notify.defs +@@ -110,3 +110,12 @@ simpleroutine mach_notify_dead_name( + msgseqno seqno : mach_port_seqno_t; + #endif + name : mach_port_name_t); ++ ++/* MACH_NOTIFY_NO_SENDERS2: 0111 */ ++simpleroutine mach_notify_no_senders2( ++ notify : notify_port_t; ++#if SEQNOS ++ msgseqno seqno : mach_port_seqno_t; ++#endif ++ name : mach_port_name_t; ++ mscount : mach_port_mscount_t); +diff --git a/include/mach/notify.h b/include/mach/notify.h +index 6d783dd..d3b4c01 100644 +--- a/include/mach/notify.h ++++ b/include/mach/notify.h +@@ -53,6 +53,9 @@ + /* An extant send-once right died */ + #define MACH_NOTIFY_DEAD_NAME (MACH_NOTIFY_FIRST + 010) + /* Send or send-once right died, leaving a dead-name */ ++#define MACH_NOTIFY_NO_SENDERS2 (MACH_NOTIFY_FIRST + 011) ++ /* Receive right has no extant send rights, ++ new version. */ + #define MACH_NOTIFY_LAST (MACH_NOTIFY_FIRST + 015) + + typedef struct { +@@ -81,6 +84,14 @@ typedef struct { + + typedef struct { + mach_msg_header_t not_header; ++ mach_msg_type_t not_port_type; /* MACH_MSG_TYPE_PORT_NAME */ ++ mach_port_t not_port; ++ mach_msg_type_t not_type; /* MACH_MSG_TYPE_INTEGER_32 */ ++ unsigned int not_count; ++} mach_no_senders_notification2_t; ++ ++typedef struct { ++ mach_msg_header_t not_header; + } mach_send_once_notification_t; + + typedef struct { +diff --git a/ipc/ipc_notify.c b/ipc/ipc_notify.c +index df5f68b..8556fee 100644 +--- a/ipc/ipc_notify.c ++++ b/ipc/ipc_notify.c +@@ -47,6 +47,7 @@ mach_port_deleted_notification_t ipc_notify_port_deleted_template; + mach_msg_accepted_notification_t ipc_notify_msg_accepted_template; + mach_port_destroyed_notification_t ipc_notify_port_destroyed_template; + mach_no_senders_notification_t ipc_notify_no_senders_template; ++mach_no_senders_notification2_t ipc_notify_no_senders2_template; + mach_send_once_notification_t ipc_notify_send_once_template; + mach_dead_name_notification_t ipc_notify_dead_name_template; + +@@ -175,6 +176,48 @@ ipc_notify_init_no_senders( + } + + /* ++ * Routine: ipc_notify_init_no_senders2 ++ * Purpose: ++ * Initialize a template for no-senders2 notifications. ++ */ ++ ++void ++ipc_notify_init_no_senders2( ++ mach_no_senders_notification2_t *n) ++{ ++ mach_msg_header_t *m = &n->not_header; ++ mach_msg_type_t *t; ++ ++ m->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0); ++ m->msgh_size = sizeof *n; ++ m->msgh_seqno = NOTIFY_MSGH_SEQNO; ++ m->msgh_local_port = MACH_PORT_NULL; ++ m->msgh_remote_port = MACH_PORT_NULL; ++ m->msgh_id = MACH_NOTIFY_NO_SENDERS; ++ ++ t = &n->not_port_type; ++ t->msgt_name = MACH_MSG_TYPE_PORT_NAME; ++ t->msgt_size = PORT_T_SIZE_IN_BITS; ++ t->msgt_number = 1; ++ t->msgt_inline = TRUE; ++ t->msgt_longform = FALSE; ++ t->msgt_deallocate = FALSE; ++ t->msgt_unused = 0; ++ ++ t = &n->not_type; ++ t->msgt_name = MACH_MSG_TYPE_INTEGER_32; ++ t->msgt_size = PORT_T_SIZE_IN_BITS; ++ t->msgt_number = 1; ++ t->msgt_inline = TRUE; ++ t->msgt_longform = FALSE; ++ t->msgt_deallocate = FALSE; ++ t->msgt_unused = 0; ++ ++ n->not_port = MACH_PORT_NULL; ++ n->not_count = 0; ++} ++ ++/* + * Routine: ipc_notify_init_send_once + * Purpose: + * Initialize a template for send-once notifications. +@@ -238,6 +281,7 @@ ipc_notify_init(void) + ipc_notify_init_msg_accepted(&ipc_notify_msg_accepted_template); + ipc_notify_init_port_destroyed(&ipc_notify_port_destroyed_template); + ipc_notify_init_no_senders(&ipc_notify_no_senders_template); ++ ipc_notify_init_no_senders2(&ipc_notify_no_senders2_template); + ipc_notify_init_send_once(&ipc_notify_send_once_template); + ipc_notify_init_dead_name(&ipc_notify_dead_name_template); + } +@@ -366,6 +410,11 @@ ipc_notify_no_senders( + ipc_kmsg_t kmsg; + mach_no_senders_notification_t *n; + ++ if (NSREQUEST_HAS_FLAG (port, NSREQUEST_FLAG_NO_SENDERS2)) { ++ ipc_notify_no_senders2 (NSREQUEST_IPC_PORT (port), mscount); ++ return; ++ } ++ + kmsg = ikm_alloc(sizeof *n); + if (kmsg == IKM_NULL) { + printf("dropped no-senders (0x%p, %u)\n", port, mscount); +@@ -384,6 +433,41 @@ ipc_notify_no_senders( + } + + /* ++ * Routine: ipc_notify_no_senders2 ++ * Purpose: ++ * Send a no-senders2 notification. ++ * Conditions: ++ * Nothing locked. ++ * Consumes a ref/soright for port. ++ */ ++ ++void ++ipc_notify_no_senders2( ++ ipc_port_t port, ++ mach_port_mscount_t mscount) ++{ ++ ipc_kmsg_t kmsg; ++ mach_no_senders_notification2_t *n; ++ ++ kmsg = ikm_alloc(sizeof *n); ++ if (kmsg == IKM_NULL) { ++ printf("dropped no-senders (0x%p, %u)\n", port, mscount); ++ ipc_port_release_sonce(port); ++ return; ++ } ++ ++ ikm_init(kmsg, sizeof *n); ++ n = (mach_no_senders_notification2_t *) &kmsg->ikm_header; ++ *n = ipc_notify_no_senders2_template; ++ ++ n->not_header.msgh_remote_port = (mach_port_t) port; ++ n->not_count = mscount; ++ n->not_port = port->ip_receiver_name; ++ ++ ipc_mqueue_send_always(kmsg); ++} ++ ++/* + * Routine: ipc_notify_send_once + * Purpose: + * Send a send-once notification. +diff --git a/ipc/ipc_notify.h b/ipc/ipc_notify.h +index 789bd23..b1fa090 100644 +--- a/ipc/ipc_notify.h ++++ b/ipc/ipc_notify.h +@@ -50,6 +50,20 @@ extern void + ipc_notify_no_senders(ipc_port_t, mach_port_mscount_t); + + extern void ++ipc_notify_no_senders2 (ipc_port_t, mach_port_mscount_t); ++ ++/* No-senders notifications come in two flavors. We use the least ++ significant bit to indicate that the new flavor was requested. */ ++#define NSREQUEST_FLAG_NO_SENDERS2 0x1 ++#define NSREQUEST_FLAG_MASK 0x1 ++#define NSREQUEST_IPC_PORT(X) \ ++ ((ipc_port_t) ((unsigned long) (X) &~ NSREQUEST_FLAG_MASK)) ++#define NSREQUEST_HAS_FLAG(X, F) \ ++ ((unsigned long) (X) & F) ++#define NSREQUEST_SET_FLAG(X, F) \ ++ ((ipc_port_t) ((unsigned long) (X) | F)) ++ ++extern void + ipc_notify_send_once(ipc_port_t); + + extern void +diff --git a/ipc/ipc_port.c b/ipc/ipc_port.c +index 89a5d67..8817c49 100644 +--- a/ipc/ipc_port.c ++++ b/ipc/ipc_port.c +@@ -290,7 +290,7 @@ ipc_port_pdrequest( + } + + /* +- * Routine: ipc_port_nsrequest ++ * Routine: ipc_port_nsrequest2 + * Purpose: + * Make a no-senders request, returning the + * previously registered send-once right. +@@ -302,8 +302,9 @@ ipc_port_pdrequest( + */ + + void +-ipc_port_nsrequest( ++ipc_port_nsrequest2( + ipc_port_t port, ++ boolean_t new_style, + mach_port_mscount_t sync, + ipc_port_t notify, + ipc_port_t *previousp) +@@ -313,7 +314,7 @@ ipc_port_nsrequest( + + assert(ip_active(port)); + +- previous = port->ip_nsrequest; ++ previous = NSREQUEST_IPC_PORT (port->ip_nsrequest); + mscount = port->ip_mscount; + + if ((port->ip_srights == 0) && +@@ -323,7 +324,10 @@ ipc_port_nsrequest( + ip_unlock(port); + ipc_notify_no_senders(notify, mscount); + } else { +- port->ip_nsrequest = notify; ++ port->ip_nsrequest = new_style ++ ? NSREQUEST_SET_FLAG (notify, ++ NSREQUEST_FLAG_NO_SENDERS2) ++ : notify; + ip_unlock(port); + } + +@@ -331,6 +335,28 @@ ipc_port_nsrequest( + } + + /* ++ * Routine: ipc_port_nsrequest ++ * Purpose: ++ * Make a no-senders request, returning the ++ * previously registered send-once right. ++ * Just cancels the previous request if notify is IP_NULL. ++ * Conditions: ++ * The port is locked and active. It is unlocked. ++ * Consumes a ref for notify (if non-null), and ++ * returns previous with a ref (if non-null). ++ */ ++ ++void ++ipc_port_nsrequest( ++ ipc_port_t port, ++ mach_port_mscount_t sync, ++ ipc_port_t notify, ++ ipc_port_t *previousp) ++{ ++ ipc_port_nsrequest2 (port, FALSE, sync, notify, previousp); ++} ++ ++/* + * Routine: ipc_port_set_qlimit + * Purpose: + * Changes a port's queue limit; the maximum number +@@ -698,7 +724,7 @@ ipc_port_destroy( + + /* throw away no-senders request */ + +- nsrequest = port->ip_nsrequest; ++ nsrequest = NSREQUEST_IPC_PORT (port->ip_nsrequest); + if (nsrequest != IP_NULL) + ipc_notify_send_once(nsrequest); /* consumes ref */ + +diff --git a/ipc/ipc_port.h b/ipc/ipc_port.h +index 6914c71..e614ae8 100644 +--- a/ipc/ipc_port.h ++++ b/ipc/ipc_port.h +@@ -88,7 +88,7 @@ struct ipc_port { + mach_port_rights_t ip_srights; + mach_port_rights_t ip_sorights; + +- struct ipc_port *ip_nsrequest; ++ struct ipc_port *ip_nsrequest; /* flags in the LSBs */ + struct ipc_port *ip_pdrequest; + struct ipc_port_request *ip_dnrequests; + +@@ -245,6 +245,14 @@ extern void ipc_port_nsrequest( + ipc_port_t notify, + ipc_port_t *previousp); + ++/* Make a no-senders request, new version. */ ++extern void ipc_port_nsrequest2( ++ ipc_port_t port, ++ boolean_t new_style, ++ mach_port_mscount_t sync, ++ ipc_port_t notify, ++ ipc_port_t *previousp); ++ + /* Change a port's queue limit */ + extern void ipc_port_set_qlimit( + ipc_port_t port, +diff --git a/ipc/mach_port.c b/ipc/mach_port.c +index c7d9b81..ad10cd2 100644 +--- a/ipc/mach_port.c ++++ b/ipc/mach_port.c +@@ -1202,7 +1202,8 @@ mach_port_request_notification( + break; + } + +- case MACH_NOTIFY_NO_SENDERS: { ++ case MACH_NOTIFY_NO_SENDERS: ++ case MACH_NOTIFY_NO_SENDERS2: { + ipc_port_t port; + + kr = ipc_port_translate_receive(space, name, &port); +@@ -1210,7 +1211,8 @@ mach_port_request_notification( + return kr; + /* port is locked and active */ + +- ipc_port_nsrequest(port, sync, notify, previousp); ++ ipc_port_nsrequest2 (port, id == MACH_NOTIFY_NO_SENDERS2, ++ sync, notify, previousp); + /* port is unlocked */ + break; + } +-- +2.1.3 + |