Kernel: fix notification delivery to non-ANY receivers
This commit is contained in:
parent
561acfb618
commit
efca30b081
@ -796,8 +796,7 @@ PRIVATE int mini_receive(struct proc * caller_ptr,
|
|||||||
*/
|
*/
|
||||||
register struct proc **xpp;
|
register struct proc **xpp;
|
||||||
sys_map_t *map;
|
sys_map_t *map;
|
||||||
bitchunk_t *chunk;
|
int i, r, src_id, found, src_proc_nr, src_p;
|
||||||
int i, r, src_id, src_proc_nr, src_p;
|
|
||||||
|
|
||||||
assert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG));
|
assert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG));
|
||||||
|
|
||||||
@ -823,24 +822,38 @@ PRIVATE int mini_receive(struct proc * caller_ptr,
|
|||||||
|
|
||||||
/* Check if there are pending notifications, except for SENDREC. */
|
/* Check if there are pending notifications, except for SENDREC. */
|
||||||
if (! (caller_ptr->p_misc_flags & MF_REPLY_PEND)) {
|
if (! (caller_ptr->p_misc_flags & MF_REPLY_PEND)) {
|
||||||
|
|
||||||
map = &priv(caller_ptr)->s_notify_pending;
|
map = &priv(caller_ptr)->s_notify_pending;
|
||||||
for (chunk=&map->chunk[0]; chunk<&map->chunk[NR_SYS_CHUNKS]; chunk++) {
|
|
||||||
|
/* Either check a specific bit in the pending notifications mask, or
|
||||||
|
* find the first bit set in it (if any), depending on whether the
|
||||||
|
* receive was called on a specific source endpoint.
|
||||||
|
*/
|
||||||
|
if (src_p != ANY) {
|
||||||
|
src_id = nr_to_id(src_p);
|
||||||
|
|
||||||
|
found = get_sys_bit(*map, src_id);
|
||||||
|
} else {
|
||||||
|
for (src_id = 0; src_id < NR_SYS_PROCS; src_id += BITCHUNK_BITS) {
|
||||||
|
if (get_sys_bits(*map, src_id) != 0) {
|
||||||
|
while (!get_sys_bit(*map, src_id)) src_id++;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
found = (src_id < NR_SYS_PROCS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
endpoint_t hisep;
|
endpoint_t hisep;
|
||||||
|
|
||||||
/* Find a pending notification from the requested source. */
|
|
||||||
if (! *chunk) continue; /* no bits in chunk */
|
|
||||||
for (i=0; ! (*chunk & (1<<i)); ++i) {} /* look up the bit */
|
|
||||||
src_id = (chunk - &map->chunk[0]) * BITCHUNK_BITS + i;
|
|
||||||
if (src_id >= NR_SYS_PROCS) break; /* out of range */
|
|
||||||
src_proc_nr = id_to_nr(src_id); /* get source proc */
|
src_proc_nr = id_to_nr(src_id); /* get source proc */
|
||||||
#if DEBUG_ENABLE_IPC_WARNINGS
|
#if DEBUG_ENABLE_IPC_WARNINGS
|
||||||
if(src_proc_nr == NONE) {
|
if(src_proc_nr == NONE) {
|
||||||
printf("mini_receive: sending notify from NONE\n");
|
printf("mini_receive: sending notify from NONE\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (src_e!=ANY && src_p != src_proc_nr) continue;/* source not ok */
|
unset_sys_bit(*map, src_id); /* no longer pending */
|
||||||
*chunk &= ~(1 << i); /* no longer pending */
|
|
||||||
|
|
||||||
/* Found a suitable source, deliver the notification message. */
|
/* Found a suitable source, deliver the notification message. */
|
||||||
hisep = proc_addr(src_proc_nr)->p_endpoint;
|
hisep = proc_addr(src_proc_nr)->p_endpoint;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user