Reduce the number of copies done by the kernel when handling retrieval and
delivery of asynchronous messages.
This commit is contained in:
parent
8200e91073
commit
9db2311b22
319
kernel/proc.c
319
kernel/proc.c
@ -875,8 +875,7 @@ PRIVATE int mini_receive(struct proc * caller_ptr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check if there are pending senda(). */
|
/* Check if there are pending senda(). */
|
||||||
if (caller_ptr->p_misc_flags & MF_ASYNMSG)
|
if (caller_ptr->p_misc_flags & MF_ASYNMSG) {
|
||||||
{
|
|
||||||
if (src_e != ANY)
|
if (src_e != ANY)
|
||||||
r = try_one(proc_addr(src_p), caller_ptr, NULL);
|
r = try_one(proc_addr(src_p), caller_ptr, NULL);
|
||||||
else
|
else
|
||||||
@ -1009,7 +1008,7 @@ PUBLIC int mini_notify(
|
|||||||
"(%d/%d, tab 0x%lx)\n",__FILE__,__LINE__, \
|
"(%d/%d, tab 0x%lx)\n",__FILE__,__LINE__, \
|
||||||
field, caller->p_name, entry, priv(caller)->s_asynsize, priv(caller)->s_asyntab)
|
field, caller->p_name, entry, priv(caller)->s_asynsize, priv(caller)->s_asyntab)
|
||||||
|
|
||||||
#define A_RETRIEVE(entry, field) \
|
#define A_RETR_FLD(entry, field) \
|
||||||
if(data_copy(caller_ptr->p_endpoint, \
|
if(data_copy(caller_ptr->p_endpoint, \
|
||||||
table_v + (entry)*sizeof(asynmsg_t) + offsetof(struct asynmsg,field),\
|
table_v + (entry)*sizeof(asynmsg_t) + offsetof(struct asynmsg,field),\
|
||||||
KERNEL, (vir_bytes) &tabent.field, \
|
KERNEL, (vir_bytes) &tabent.field, \
|
||||||
@ -1018,7 +1017,17 @@ field, caller->p_name, entry, priv(caller)->s_asynsize, priv(caller)->s_asyntab)
|
|||||||
return EFAULT; \
|
return EFAULT; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define A_INSERT(entry, field) \
|
#define A_RETR(entry) do { \
|
||||||
|
if (data_copy( \
|
||||||
|
caller_ptr->p_endpoint, table_v + (entry)*sizeof(asynmsg_t),\
|
||||||
|
KERNEL, (vir_bytes) &tabent, \
|
||||||
|
sizeof(tabent)) != OK) { \
|
||||||
|
ASCOMPLAIN(caller_ptr, entry, "message entry"); \
|
||||||
|
return(EFAULT); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define A_INSRT_FLD(entry, field) \
|
||||||
if(data_copy(KERNEL, (vir_bytes) &tabent.field, \
|
if(data_copy(KERNEL, (vir_bytes) &tabent.field, \
|
||||||
caller_ptr->p_endpoint, \
|
caller_ptr->p_endpoint, \
|
||||||
table_v + (entry)*sizeof(asynmsg_t) + offsetof(struct asynmsg,field),\
|
table_v + (entry)*sizeof(asynmsg_t) + offsetof(struct asynmsg,field),\
|
||||||
@ -1027,35 +1036,39 @@ field, caller->p_name, entry, priv(caller)->s_asynsize, priv(caller)->s_asyntab)
|
|||||||
return EFAULT; \
|
return EFAULT; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define A_INSRT(entry) do { \
|
||||||
|
if (data_copy(KERNEL, (vir_bytes) &tabent, \
|
||||||
|
caller_ptr->p_endpoint, table_v + (entry)*sizeof(asynmsg_t),\
|
||||||
|
sizeof(tabent)) != OK) { \
|
||||||
|
ASCOMPLAIN(caller_ptr, entry, "message entry"); \
|
||||||
|
return(EFAULT); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* mini_senda *
|
* mini_senda *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PRIVATE int mini_senda(struct proc *caller_ptr, asynmsg_t *table, size_t size)
|
PRIVATE int mini_senda(struct proc *caller_ptr, asynmsg_t *table, size_t size)
|
||||||
{
|
{
|
||||||
int i, dst_p, done, do_notify;
|
int r = OK, i, dst_p, done, do_notify;
|
||||||
unsigned flags;
|
unsigned flags;
|
||||||
|
endpoint_t dst;
|
||||||
struct proc *dst_ptr;
|
struct proc *dst_ptr;
|
||||||
struct priv *privp;
|
struct priv *privp;
|
||||||
asynmsg_t tabent;
|
asynmsg_t tabent;
|
||||||
const vir_bytes table_v = (vir_bytes) table;
|
const vir_bytes table_v = (vir_bytes) table;
|
||||||
|
|
||||||
privp = priv(caller_ptr);
|
privp = priv(caller_ptr);
|
||||||
if (!(privp->s_flags & SYS_PROC))
|
if (!(privp->s_flags & SYS_PROC)) {
|
||||||
{
|
printf( "mini_senda: warning caller has no privilege structure\n");
|
||||||
printf(
|
return(EPERM);
|
||||||
"mini_senda: warning caller has no privilege structure\n");
|
|
||||||
return EPERM;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear table */
|
/* Clear table */
|
||||||
privp->s_asyntab = -1;
|
privp->s_asyntab = -1;
|
||||||
privp->s_asynsize = 0;
|
privp->s_asynsize = 0;
|
||||||
|
|
||||||
if (size == 0)
|
if (size == 0) return(OK); /* Nothing to do, just return */
|
||||||
{
|
|
||||||
/* Nothing to do, just return */
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Limit size to something reasonable. An arbitrary choice is 16
|
/* Limit size to something reasonable. An arbitrary choice is 16
|
||||||
* times the number of process table entries.
|
* times the number of process table entries.
|
||||||
@ -1063,143 +1076,82 @@ PRIVATE int mini_senda(struct proc *caller_ptr, asynmsg_t *table, size_t size)
|
|||||||
* (this check has been duplicated in sys_call but is left here
|
* (this check has been duplicated in sys_call but is left here
|
||||||
* as a sanity check)
|
* as a sanity check)
|
||||||
*/
|
*/
|
||||||
if (size > 16*(NR_TASKS + NR_PROCS))
|
if (size > 16*(NR_TASKS + NR_PROCS)) return(EDOM);
|
||||||
{
|
|
||||||
return EDOM;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Scan the table */
|
/* Scan the table */
|
||||||
do_notify= FALSE;
|
do_notify = FALSE; /* XXX: this doesn't do anything? */
|
||||||
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.
|
||||||
|
* If we're done handling a message, copy the result to the sender. */
|
||||||
|
int pending_recv = FALSE;
|
||||||
|
|
||||||
/* Read status word */
|
/* Copy message to kernel */
|
||||||
A_RETRIEVE(i, flags);
|
A_RETR(i);
|
||||||
flags = tabent.flags;
|
flags = tabent.flags;
|
||||||
|
dst = tabent.dst;
|
||||||
|
|
||||||
/* Skip empty entries */
|
if (flags == 0) continue; /* Skip empty entries */
|
||||||
if (flags == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Check for reserved bits in the flags field */
|
/* 'flags' field must contain only valid bits */
|
||||||
if (flags & ~(AMF_VALID|AMF_DONE|AMF_NOTIFY|AMF_NOREPLY) ||
|
if (flags & ~(AMF_VALID|AMF_DONE|AMF_NOTIFY|AMF_NOREPLY))
|
||||||
!(flags & AMF_VALID))
|
return(EINVAL);
|
||||||
{
|
if (!(flags & AMF_VALID)) return(EINVAL); /* Must contain message */
|
||||||
return EINVAL;
|
if (flags & AMF_DONE) continue; /* Already done processing */
|
||||||
}
|
|
||||||
|
|
||||||
/* Skip entry if AMF_DONE is already set */
|
|
||||||
if (flags & AMF_DONE)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Get destination */
|
|
||||||
A_RETRIEVE(i, dst);
|
|
||||||
|
|
||||||
if (!isokendpt(tabent.dst, &dst_p))
|
if (!isokendpt(tabent.dst, &dst_p))
|
||||||
{
|
r = EDEADSRCDST; /* Bad destination, report the error */
|
||||||
/* Bad destination, report the error */
|
else if (iskerneln(dst_p))
|
||||||
tabent.result= EDEADSRCDST;
|
r = ECALLDENIED; /* Asyn sends to the kernel are not allowed */
|
||||||
A_INSERT(i, result);
|
else if (!may_send_to(caller_ptr, dst_p))
|
||||||
tabent.flags= flags | AMF_DONE;
|
r = ECALLDENIED; /* Send denied by IPC mask */
|
||||||
A_INSERT(i, flags);
|
else /* r == OK */
|
||||||
|
|
||||||
if (flags & AMF_NOTIFY)
|
|
||||||
do_notify= 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iskerneln(dst_p))
|
|
||||||
{
|
|
||||||
/* Asynchronous sends to the kernel are not allowed */
|
|
||||||
tabent.result= ECALLDENIED;
|
|
||||||
A_INSERT(i, result);
|
|
||||||
tabent.flags= flags | AMF_DONE;
|
|
||||||
A_INSERT(i, flags);
|
|
||||||
|
|
||||||
if (flags & AMF_NOTIFY)
|
|
||||||
do_notify= 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!may_send_to(caller_ptr, dst_p))
|
|
||||||
{
|
|
||||||
/* Send denied by IPC mask */
|
|
||||||
tabent.result= ECALLDENIED;
|
|
||||||
A_INSERT(i, result);
|
|
||||||
tabent.flags= flags | AMF_DONE;
|
|
||||||
A_INSERT(i, flags);
|
|
||||||
|
|
||||||
if (flags & AMF_NOTIFY)
|
|
||||||
do_notify= 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
printf("mini_senda: entry[%d]: flags 0x%x dst %d/%d\n",
|
|
||||||
i, tabent.flags, tabent.dst, dst_p);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dst_ptr = proc_addr(dst_p);
|
dst_ptr = proc_addr(dst_p);
|
||||||
|
|
||||||
/* RTS_NO_ENDPOINT should be removed */
|
/* XXX: RTS_NO_ENDPOINT should be removed */
|
||||||
if (RTS_ISSET(dst_ptr, RTS_NO_ENDPOINT))
|
if (r == OK && RTS_ISSET(dst_ptr, RTS_NO_ENDPOINT)) {
|
||||||
{
|
r = EDEADSRCDST;
|
||||||
tabent.result= EDEADSRCDST;
|
|
||||||
A_INSERT(i, result);
|
|
||||||
tabent.flags= flags | AMF_DONE;
|
|
||||||
A_INSERT(i, flags);
|
|
||||||
|
|
||||||
if (flags & AMF_NOTIFY)
|
|
||||||
do_notify= TRUE;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if 'dst' is blocked waiting for this message.
|
/* Check if 'dst' is blocked waiting for this message.
|
||||||
* If AMF_NOREPLY is set, do not satisfy the receiving part of
|
* If AMF_NOREPLY is set, do not satisfy the receiving part of
|
||||||
* a SENDREC.
|
* a SENDREC.
|
||||||
*/
|
*/
|
||||||
if (WILLRECEIVE(dst_ptr, caller_ptr->p_endpoint) &&
|
if (r == OK && WILLRECEIVE(dst_ptr, caller_ptr->p_endpoint) &&
|
||||||
(!(flags & AMF_NOREPLY) ||
|
(!(flags&AMF_NOREPLY) || !(dst_ptr->p_misc_flags&MF_REPLY_PEND))) {
|
||||||
!(dst_ptr->p_misc_flags & MF_REPLY_PEND)))
|
|
||||||
{
|
|
||||||
/* Destination is indeed waiting for this message. */
|
/* Destination is indeed waiting for this message. */
|
||||||
/* Copy message from sender. */
|
dst_ptr->p_delivermsg = tabent.msg;
|
||||||
if(copy_msg_from_user(caller_ptr, &table[i].msg,
|
|
||||||
&dst_ptr->p_delivermsg))
|
|
||||||
tabent.result = EFAULT;
|
|
||||||
else {
|
|
||||||
dst_ptr->p_delivermsg.m_source = caller_ptr->p_endpoint;
|
dst_ptr->p_delivermsg.m_source = caller_ptr->p_endpoint;
|
||||||
dst_ptr->p_misc_flags |= MF_DELIVERMSG;
|
dst_ptr->p_misc_flags |= MF_DELIVERMSG;
|
||||||
IPC_STATUS_ADD_CALL(dst_ptr, SENDA);
|
IPC_STATUS_ADD_CALL(dst_ptr, SENDA);
|
||||||
RTS_UNSET(dst_ptr, RTS_RECEIVING);
|
RTS_UNSET(dst_ptr, RTS_RECEIVING);
|
||||||
tabent.result = OK;
|
} else if (r == OK) {
|
||||||
}
|
|
||||||
|
|
||||||
A_INSERT(i, result);
|
|
||||||
tabent.flags= flags | AMF_DONE;
|
|
||||||
A_INSERT(i, flags);
|
|
||||||
|
|
||||||
if (flags & AMF_NOTIFY)
|
|
||||||
do_notify= 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Should inform receiver that something is pending */
|
/* Should inform receiver that something is pending */
|
||||||
dst_ptr->p_misc_flags |= MF_ASYNMSG;
|
dst_ptr->p_misc_flags |= MF_ASYNMSG;
|
||||||
|
pending_recv = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pending_recv) flags |= AMF_DONE; /* Done handling message */
|
||||||
|
|
||||||
|
/* Store results */
|
||||||
|
tabent.result = r;
|
||||||
|
tabent.flags = flags;
|
||||||
|
if (flags & AMF_DONE) {
|
||||||
|
if (r != EDEADSRCDST && (flags & AMF_NOTIFY))
|
||||||
|
do_notify = TRUE; /* XXX: ? */
|
||||||
|
A_INSRT(i); /* Copy results to caller */
|
||||||
|
} else
|
||||||
done = FALSE;
|
done = FALSE;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (do_notify)
|
if (do_notify) printf("mini_senda: should notify caller\n"); /* XXX: ? */
|
||||||
printf("mini_senda: should notify caller\n");
|
|
||||||
if (!done)
|
if (!done) {
|
||||||
{
|
|
||||||
privp->s_asyntab = (vir_bytes) table;
|
privp->s_asyntab = (vir_bytes) table;
|
||||||
privp->s_asynsize = size;
|
privp->s_asynsize = size;
|
||||||
}
|
}
|
||||||
return OK;
|
|
||||||
|
return(OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1215,8 +1167,7 @@ struct proc *caller_ptr;
|
|||||||
int postponed = FALSE;
|
int postponed = FALSE;
|
||||||
|
|
||||||
/* 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;
|
||||||
|
|
||||||
@ -1225,14 +1176,14 @@ struct proc *caller_ptr;
|
|||||||
assert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG));
|
assert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG));
|
||||||
r = try_one(src_ptr, caller_ptr, &postponed);
|
r = try_one(src_ptr, caller_ptr, &postponed);
|
||||||
if (r == OK)
|
if (r == OK)
|
||||||
return r;
|
return(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Nothing found, clear MF_ASYNMSG unless messages were postponed */
|
/* Nothing found, clear MF_ASYNMSG unless messages were postponed */
|
||||||
if (postponed == FALSE)
|
if (postponed == FALSE)
|
||||||
caller_ptr->p_misc_flags &= ~MF_ASYNMSG;
|
caller_ptr->p_misc_flags &= ~MF_ASYNMSG;
|
||||||
|
|
||||||
return ESRCH;
|
return(ESRCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1241,103 +1192,97 @@ struct proc *caller_ptr;
|
|||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PRIVATE int try_one(struct proc *src_ptr, struct proc *dst_ptr, int *postponed)
|
PRIVATE int try_one(struct proc *src_ptr, struct proc *dst_ptr, int *postponed)
|
||||||
{
|
{
|
||||||
int i, done;
|
int r = EAGAIN, i, done, do_notify, pending_recv = FALSE;
|
||||||
unsigned flags;
|
unsigned flags;
|
||||||
size_t size;
|
size_t size;
|
||||||
endpoint_t dst_e;
|
endpoint_t dst;
|
||||||
|
struct proc *caller_ptr;
|
||||||
struct priv *privp;
|
struct priv *privp;
|
||||||
asynmsg_t tabent;
|
asynmsg_t tabent;
|
||||||
vir_bytes table_v;
|
vir_bytes table_v;
|
||||||
struct proc *caller_ptr;
|
|
||||||
|
|
||||||
privp = priv(src_ptr);
|
privp = priv(src_ptr);
|
||||||
|
if (!(privp->s_flags & SYS_PROC)) return(EPERM);
|
||||||
/* Basic validity checks */
|
|
||||||
if (privp->s_id == USER_PRIV_ID) return EAGAIN;
|
|
||||||
if (privp->s_asynsize == 0) return EAGAIN;
|
|
||||||
if (!may_send_to(src_ptr, proc_nr(dst_ptr))) return EAGAIN;
|
|
||||||
|
|
||||||
size = privp->s_asynsize;
|
size = privp->s_asynsize;
|
||||||
table_v = privp->s_asyntab;
|
table_v = privp->s_asyntab;
|
||||||
|
|
||||||
|
/* Clear table */
|
||||||
|
privp->s_asyntab = -1;
|
||||||
|
privp->s_asynsize = 0;
|
||||||
|
|
||||||
|
if (size == 0) return(EAGAIN);
|
||||||
|
if (!may_send_to(src_ptr, proc_nr(dst_ptr))) return(EAGAIN);
|
||||||
|
|
||||||
caller_ptr = src_ptr;
|
caller_ptr = src_ptr;
|
||||||
|
|
||||||
dst_e= dst_ptr->p_endpoint;
|
|
||||||
|
|
||||||
/* Scan the table */
|
/* Scan the table */
|
||||||
|
do_notify = FALSE; /* XXX: this doesn't do anything? */
|
||||||
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.
|
||||||
/* Read status word */
|
* If we're done handling a message, copy the result to the sender.
|
||||||
A_RETRIEVE(i, flags);
|
* Some checks done in mini_senda are duplicated here, as the sender
|
||||||
|
* could've altered the contents of the table in the mean time.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copy message to kernel */
|
||||||
|
A_RETR(i);
|
||||||
flags = tabent.flags;
|
flags = tabent.flags;
|
||||||
|
dst = tabent.dst;
|
||||||
|
|
||||||
/* Skip empty entries */
|
if (flags == 0) continue; /* Skip empty entries */
|
||||||
if (flags == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for reserved bits in the flags field */
|
/* 'flags' field must contain only valid bits */
|
||||||
if (flags & ~(AMF_VALID|AMF_DONE|AMF_NOTIFY|AMF_NOREPLY) ||
|
if (flags & ~(AMF_VALID|AMF_DONE|AMF_NOTIFY|AMF_NOREPLY))
|
||||||
!(flags & AMF_VALID))
|
return(EINVAL);
|
||||||
{
|
if (!(flags & AMF_VALID)) return(EINVAL); /* Must contain message */
|
||||||
printf("try_one: bad bits in table\n");
|
if (flags & AMF_DONE) continue; /* Already done processing */
|
||||||
privp->s_asynsize= 0;
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Skip entry is AMF_DONE is already set */
|
/* Clear done flag. The sender is done sending when all messages in the
|
||||||
if (flags & AMF_DONE)
|
* 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
|
||||||
continue;
|
* send additional asynchronous messages and manages to deliver them
|
||||||
}
|
* all.
|
||||||
|
|
||||||
/* Clear done. We are done when all entries are either empty
|
|
||||||
* or done at the start of the call.
|
|
||||||
*/
|
*/
|
||||||
done = FALSE;
|
done = FALSE;
|
||||||
|
|
||||||
/* Get destination */
|
/* Message must be directed at receiving end */
|
||||||
A_RETRIEVE(i, dst);
|
if (dst != dst_ptr->p_endpoint) continue;
|
||||||
|
|
||||||
if (tabent.dst != dst_e)
|
/* If AMF_NOREPLY is set, then this message is not a reply to a
|
||||||
{
|
* SENDREC and thus should not satisfy the receiving part of the
|
||||||
continue;
|
* SENDREC. This message is to be delivered later.
|
||||||
}
|
|
||||||
|
|
||||||
/* If AMF_NOREPLY is set, do not satisfy the receiving part of
|
|
||||||
* a SENDREC. Do not unset MF_ASYNMSG later because of this,
|
|
||||||
* though: this message is still to be delivered later.
|
|
||||||
*/
|
*/
|
||||||
if ((flags & AMF_NOREPLY) &&
|
if ((flags & AMF_NOREPLY) && (dst_ptr->p_misc_flags & MF_REPLY_PEND)) {
|
||||||
(dst_ptr->p_misc_flags & MF_REPLY_PEND))
|
|
||||||
{
|
|
||||||
if (postponed != NULL)
|
if (postponed != NULL)
|
||||||
*postponed = TRUE;
|
*postponed = TRUE;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Deliver message */
|
/* Destination is ready to receive the message; deliver it */
|
||||||
A_RETRIEVE(i, msg);
|
|
||||||
dst_ptr->p_delivermsg = tabent.msg;
|
dst_ptr->p_delivermsg = tabent.msg;
|
||||||
dst_ptr->p_delivermsg.m_source = src_ptr->p_endpoint;
|
dst_ptr->p_delivermsg.m_source = src_ptr->p_endpoint;
|
||||||
dst_ptr->p_misc_flags |= MF_DELIVERMSG;
|
dst_ptr->p_misc_flags |= MF_DELIVERMSG;
|
||||||
|
|
||||||
|
/* Store results for sender */
|
||||||
tabent.result = OK;
|
tabent.result = OK;
|
||||||
A_INSERT(i, result);
|
|
||||||
tabent.flags = flags | AMF_DONE;
|
tabent.flags = flags | AMF_DONE;
|
||||||
A_INSERT(i, flags);
|
if (flags & AMF_NOTIFY) do_notify = TRUE; /* XXX: ? */
|
||||||
|
A_INSRT(i); /* Copy results to sender */
|
||||||
|
|
||||||
if (flags & AMF_NOTIFY)
|
r = OK;
|
||||||
{
|
break;
|
||||||
printf("try_one: should notify caller\n");
|
|
||||||
}
|
}
|
||||||
return OK;
|
|
||||||
|
if (do_notify) printf("mini_senda: should notify caller\n"); /* XXX: ? */
|
||||||
|
|
||||||
|
if (!done) {
|
||||||
|
privp->s_asyntab = table_v;
|
||||||
|
privp->s_asynsize = size;
|
||||||
}
|
}
|
||||||
if (done)
|
|
||||||
privp->s_asynsize= 0;
|
return(r);
|
||||||
return EAGAIN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user