1
1

Added mca_oob_recv_packed() which is a wrapper for oob_recv that recvs into a buffer that is hander to the user. No lowlevel changes.

(This will be used by GPR).
Todo: sends (easy) and nb recv (harder)

This commit was SVN r2070.
Этот коммит содержится в:
Graham Fagg 2004-08-11 21:07:16 +00:00
родитель 9ad929ecd7
Коммит 209bbbb6ad
2 изменённых файлов: 83 добавлений и 1 удалений

Просмотреть файл

@ -11,6 +11,7 @@
#include "mca/mca.h"
#include "mca/ns/ns.h"
#include <sys/uio.h>
#include "util/pack.h"
/*
@ -62,7 +63,7 @@ typedef enum {
*
* An example of usage - to determine the size of the next available message w/out receiving it:
*
* int size = mca_oob_recv(name, 0, 0, MSG_OOB_PEEK|MSG_OOB_TRUNC);
* int size = mca_oob_recv(name, 0, 0, MCA_OOB_TRUNC|MCA_OOB_PEEK);
*/
#define MCA_OOB_PEEK 0x01 /**< flag to oob_recv to allow caller to peek a portion of the next available
@ -198,6 +199,31 @@ int mca_oob_recv_ntoh(
int tag,
int flags);
/**
* Similiar to unix read(2)
*
* @param peer (IN) Opaque name of peer process or MCA_OOB_NAME_ANY for wildcard receive.
* @param buf (OUT) Array of iovecs describing user buffers and lengths.
* @param tag (IN) User defined tag for matching send/recv.
* @return OMPI error code (<0) on error or number of bytes actually received.
*
*
* This version of oob_recv is as above except it does NOT take a iovec list
* but instead hands back a ompi_buffer_t buffer with the message in it.
* The user is responsible for freeing this buffer with ompi_buffer_free()
* when finished.
*
*
*/
int mca_oob_recv_packed (
ompi_process_name_t* peer,
ompi_buffer_t *buf,
int tag);
/*
* Non-blocking versions of send/recv.
*/
@ -331,6 +357,11 @@ int mca_oob_recv_ntoh_nb(
void* cbdata);
/*
* functions for pack and unpack routines
*/

Просмотреть файл

@ -2,6 +2,8 @@
#include "mca/oob/base/base.h"
#include <netinet/in.h>
#include <string.h>
#include "util/pack.h"
/*
* Similiar to unix recv(2)
@ -97,3 +99,52 @@ int mca_oob_recv_ntoh(
return rc;
}
/*
* Similiar to unix recv(2)
*
* @param peer (IN) Opaque name of peer process or MCA_OOB_NAME_ANY for wildcard receive.
* @param buffer (OUT) Buffer that the OOB creates to recv this message...
* @param tag (IN) User defined tag for matching send/recv.
* iovec array without removing the message from the queue.
* @return OMPI error code (<0) on error or number of bytes actually received.
*/
int mca_oob_recv_packed (ompi_process_name_t* peer, ompi_buffer_t *buf, int tag)
{
/* ok, this routine is a bit of a cow */
/* the oob_recv actually needs the real target buffers in advance */
/* this forces a three stage method */
/* first we need to peek the size we will need */
/* then we allocate a buffer of the correct size and then */
/* we post a recv with the matching iov :) */
/* and we hope that someone inbtween has not posted a recv */
/* that matches. */
/* To avoid any RACE we NEED to change the OOB lowlevel to */
/* alloc the buffer for us.. as per original design. */
/* Or do locking on all recv posting between the peek and recv! GEF */
uint32_t insize;
int rc;
struct iovec msg[1];
ompi_buffer_t tmpbuf;
void *targetptr;
insize = mca_oob.oob_recv(peer, NULL, 0, tag, MCA_OOB_PEEK|MCA_OOB_TRUNC);
if (OMPI_ERROR==insize) { return (rc); }
rc = ompi_buffer_init (&tmpbuf, insize);
if (OMPI_ERROR==rc) { return (rc); }
rc = ompi_buffer_get_ptrs (tmpbuf, &targetptr, NULL, NULL);
if (OMPI_ERROR==rc) { return (rc); }
/* now update the second IOV */
msg[0].iov_base = (char*) targetptr;
msg[0].iov_len = insize;
rc = mca_oob.oob_recv(peer, msg, 1, tag, 0);
if (OMPI_ERROR!=rc) *buf = tmpbuf;
return (rc);
}