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
					
				@ -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,9 +1302,10 @@ 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;
 | 
			
		||||
  if (done) {
 | 
			
		||||
	privp->s_asyntab = -1;
 | 
			
		||||
	privp->s_asynsize = 0;
 | 
			
		||||
  } else {
 | 
			
		||||
	set_sys_bit(priv(dst_ptr)->s_asyn_pending, privp->s_id);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user