]> Zhao Yanbai Git Server - minix.git/commitdiff
Kernel: try_async/try_one fixes
authorDavid van Moolenbroek <david@minix3.org>
Mon, 18 Apr 2011 22:56:34 +0000 (22:56 +0000)
committerDavid van Moolenbroek <david@minix3.org>
Mon, 18 Apr 2011 22:56:34 +0000 (22:56 +0000)
- 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

kernel/proc.c

index f91ff75554844aeeba7fa0b25e317929ec573f49..fa374f12b72dc0d84bb49b0a42e9d35596968921 100644 (file)
@@ -1186,12 +1186,18 @@ struct proc *caller_ptr;
   int r;
   struct priv *privp;
   struct proc *src_ptr;
+  sys_map_t *map;
+
+  map = &priv(caller_ptr)->s_asyn_pending;
 
   /* Try all privilege structures */
   for (privp = BEG_PRIV_ADDR; privp < END_PRIV_ADDR; ++privp)  {
        if (privp->s_proc_nr == NONE)
                continue;
 
+       if (!get_sys_bit(*map, privp->s_id)) 
+               continue;
+
        src_ptr = proc_addr(privp->s_proc_nr);
 
        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;
 
   /* 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);
 
   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 */
 
   /* Scan the table */
-  do_notify = FALSE;   /* XXX: this doesn't do anything? */
+  do_notify = FALSE;
   done = TRUE;
   for (i = 0; i < size; i++) {
        /* 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.
         * 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 */
@@ -1257,9 +1261,6 @@ PRIVATE int try_one(struct proc *src_ptr, struct proc *dst_ptr)
                r = EINVAL; 
        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
         * 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
@@ -1268,6 +1269,9 @@ PRIVATE int try_one(struct proc *src_ptr, struct proc *dst_ptr)
         */
        done = FALSE;
 
+       if (r == EINVAL)
+               goto store_result;
+
        /* Message must be directed at receiving end */
        if (dst != dst_ptr->p_endpoint) continue;
 
@@ -1298,10 +1302,11 @@ store_result:
   if (do_notify) 
        mini_notify(proc_addr(ASYNCM), src_ptr->p_endpoint);
 
-  if (!done) {
-       privp->s_asyntab = table_v;
-       privp->s_asynsize = size;
-       set_sys_bit(priv(dst_ptr)->s_asyn_pending, privp->s_id);
+  if (done) {
+       privp->s_asyntab = -1;
+       privp->s_asynsize = 0;
+  } else {
+       set_sys_bit(priv(dst_ptr)->s_asyn_pending, privp->s_id);
   }
 
   return(r);