Kernel: try_async/try_one fixes
- skip processes that are not asynsending to the target - do not clear whole asynsend table upon IPC permission error - be more accepting when one table entry is bogus later on
This commit is contained in:
parent
afb8067c4f
commit
46cee00ad8
1 changed files with 16 additions and 11 deletions
|
@ -1186,12 +1186,18 @@ struct proc *caller_ptr;
|
||||||
int r;
|
int r;
|
||||||
struct priv *privp;
|
struct priv *privp;
|
||||||
struct proc *src_ptr;
|
struct proc *src_ptr;
|
||||||
|
sys_map_t *map;
|
||||||
|
|
||||||
|
map = &priv(caller_ptr)->s_asyn_pending;
|
||||||
|
|
||||||
/* Try all privilege structures */
|
/* Try all privilege structures */
|
||||||
for (privp = BEG_PRIV_ADDR; privp < END_PRIV_ADDR; ++privp) {
|
for (privp = BEG_PRIV_ADDR; privp < END_PRIV_ADDR; ++privp) {
|
||||||
if (privp->s_proc_nr == NONE)
|
if (privp->s_proc_nr == NONE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (!get_sys_bit(*map, privp->s_id))
|
||||||
|
continue;
|
||||||
|
|
||||||
src_ptr = proc_addr(privp->s_proc_nr);
|
src_ptr = proc_addr(privp->s_proc_nr);
|
||||||
|
|
||||||
assert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG));
|
assert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG));
|
||||||
|
@ -1224,8 +1230,6 @@ PRIVATE int try_one(struct proc *src_ptr, struct proc *dst_ptr)
|
||||||
table_v = privp->s_asyntab;
|
table_v = privp->s_asyntab;
|
||||||
|
|
||||||
/* Clear table pending message flag. We're done unless we're not. */
|
/* Clear table pending message flag. We're done unless we're not. */
|
||||||
privp->s_asyntab = -1;
|
|
||||||
privp->s_asynsize = 0;
|
|
||||||
unset_sys_bit(priv(dst_ptr)->s_asyn_pending, privp->s_id);
|
unset_sys_bit(priv(dst_ptr)->s_asyn_pending, privp->s_id);
|
||||||
|
|
||||||
if (size == 0) return(EAGAIN);
|
if (size == 0) return(EAGAIN);
|
||||||
|
@ -1234,13 +1238,13 @@ PRIVATE int try_one(struct proc *src_ptr, struct proc *dst_ptr)
|
||||||
caller_ptr = src_ptr; /* Needed for A_ macros later on */
|
caller_ptr = src_ptr; /* Needed for A_ macros later on */
|
||||||
|
|
||||||
/* Scan the table */
|
/* Scan the table */
|
||||||
do_notify = FALSE; /* XXX: this doesn't do anything? */
|
do_notify = FALSE;
|
||||||
done = TRUE;
|
done = TRUE;
|
||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++) {
|
||||||
/* Process each entry in the table and store the result in the table.
|
/* Process each entry in the table and store the result in the table.
|
||||||
* If we're done handling a message, copy the result to the sender.
|
* If we're done handling a message, copy the result to the sender.
|
||||||
* Some checks done in mini_senda are duplicated here, as the sender
|
* Some checks done in mini_senda are duplicated here, as the sender
|
||||||
* could've altered the contents of the table in the mean time.
|
* could've altered the contents of the table in the meantime.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Copy message to kernel */
|
/* Copy message to kernel */
|
||||||
|
@ -1257,9 +1261,6 @@ PRIVATE int try_one(struct proc *src_ptr, struct proc *dst_ptr)
|
||||||
r = EINVAL;
|
r = EINVAL;
|
||||||
else if (flags & AMF_DONE) continue; /* Already done processing */
|
else if (flags & AMF_DONE) continue; /* Already done processing */
|
||||||
|
|
||||||
if (r == EINVAL)
|
|
||||||
goto store_result;
|
|
||||||
|
|
||||||
/* Clear done flag. The sender is done sending when all messages in the
|
/* Clear done flag. The sender is done sending when all messages in the
|
||||||
* table are marked done or empty. However, we will know that only
|
* table are marked done or empty. However, we will know that only
|
||||||
* the next time we enter this function or when the sender decides to
|
* the next time we enter this function or when the sender decides to
|
||||||
|
@ -1268,6 +1269,9 @@ PRIVATE int try_one(struct proc *src_ptr, struct proc *dst_ptr)
|
||||||
*/
|
*/
|
||||||
done = FALSE;
|
done = FALSE;
|
||||||
|
|
||||||
|
if (r == EINVAL)
|
||||||
|
goto store_result;
|
||||||
|
|
||||||
/* Message must be directed at receiving end */
|
/* Message must be directed at receiving end */
|
||||||
if (dst != dst_ptr->p_endpoint) continue;
|
if (dst != dst_ptr->p_endpoint) continue;
|
||||||
|
|
||||||
|
@ -1298,10 +1302,11 @@ store_result:
|
||||||
if (do_notify)
|
if (do_notify)
|
||||||
mini_notify(proc_addr(ASYNCM), src_ptr->p_endpoint);
|
mini_notify(proc_addr(ASYNCM), src_ptr->p_endpoint);
|
||||||
|
|
||||||
if (!done) {
|
if (done) {
|
||||||
privp->s_asyntab = table_v;
|
privp->s_asyntab = -1;
|
||||||
privp->s_asynsize = size;
|
privp->s_asynsize = 0;
|
||||||
set_sys_bit(priv(dst_ptr)->s_asyn_pending, privp->s_id);
|
} else {
|
||||||
|
set_sys_bit(priv(dst_ptr)->s_asyn_pending, privp->s_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(r);
|
return(r);
|
||||||
|
|
Loading…
Reference in a new issue