/******** DATA EXCHANGE ********/ static void lookup_cbfunc(int status, opal_list_t *data, void *cbdata) { struct lookup_caddy_t *cd = (struct lookup_caddy_t*)cbdata; cd->status = status; if (OPAL_SUCCESS == status && NULL != data) { opal_pmix_pdata_t *p = (opal_pmix_pdata_t*)opal_list_get_first(data); if (NULL != p) { cd->pdat->proc = p->proc; if (p->value.type == cd->pdat->value.type) { (void)opal_value_xfer(&cd->pdat->value, &p->value); } } } cd->active = false; }
int opal_pmix_base_exchange(opal_value_t *indat, opal_pmix_pdata_t *outdat, int timeout) { int rc; opal_list_t ilist, mlist; opal_value_t *info; opal_pmix_pdata_t *pdat; struct lookup_caddy_t caddy; char **keys; /* protect the incoming value */ opal_dss.copy((void**)&info, indat, OPAL_VALUE); OBJ_CONSTRUCT(&ilist, opal_list_t); opal_list_append(&ilist, &info->super); /* tell the server to delete upon read */ info = OBJ_NEW(opal_value_t); info->key = strdup(OPAL_PMIX_PERSISTENCE); info->type = OPAL_INT; info->data.integer = OPAL_PMIX_PERSIST_FIRST_READ; opal_list_append(&ilist, &info->super); /* publish it with "session" scope */ rc = opal_pmix.publish(&ilist); OPAL_LIST_DESTRUCT(&ilist); if (OPAL_SUCCESS != rc) { OPAL_ERROR_LOG(rc); return rc; } /* lookup the other side's info - if a non-blocking form * of lookup isn't available, then we use the blocking * form and trust that the underlying system will WAIT * until the other side publishes its data */ OBJ_CONSTRUCT(&ilist, opal_list_t); pdat = OBJ_NEW(opal_pmix_pdata_t); pdat->value.key = strdup(outdat->value.key); pdat->value.type = outdat->value.type; opal_list_append(&ilist, &pdat->super); /* setup the constraints */ OBJ_CONSTRUCT(&mlist, opal_list_t); /* tell it to wait for the data to arrive */ info = OBJ_NEW(opal_value_t); info->key = strdup(OPAL_PMIX_WAIT); info->type = OPAL_BOOL; info->data.flag = true; opal_list_append(&mlist, &info->super); /* pass along the given timeout as we don't know when * the other side will publish - it doesn't * have to be simultaneous */ info = OBJ_NEW(opal_value_t); info->key = strdup(OPAL_PMIX_TIMEOUT); info->type = OPAL_INT; info->data.integer = timeout; opal_list_append(&mlist, &info->super); /* if a non-blocking version of lookup isn't * available, then use the blocking version */ if (NULL == opal_pmix.lookup_nb) { rc = opal_pmix.lookup(&ilist, &mlist); OPAL_LIST_DESTRUCT(&mlist); if (OPAL_SUCCESS != rc) { OPAL_ERROR_LOG(rc); OPAL_LIST_DESTRUCT(&ilist); return rc; } } else { caddy.active = true; caddy.pdat = pdat; keys = NULL; opal_argv_append_nosize(&keys, pdat->value.key); rc = opal_pmix.lookup_nb(keys, &mlist, lookup_cbfunc, &caddy); if (OPAL_SUCCESS != rc) { OPAL_ERROR_LOG(rc); OPAL_LIST_DESTRUCT(&ilist); OPAL_LIST_DESTRUCT(&mlist); opal_argv_free(keys); return rc; } while (caddy.active) { usleep(10); } opal_argv_free(keys); OPAL_LIST_DESTRUCT(&mlist); if (OPAL_SUCCESS != caddy.status) { OPAL_ERROR_LOG(caddy.status); OPAL_LIST_DESTRUCT(&ilist); return caddy.status; } } /* pass back the result */ outdat->proc = pdat->proc; rc = opal_value_xfer(&outdat->value, &pdat->value); OPAL_LIST_DESTRUCT(&ilist); return rc; }
void pmix_server_keyval_client(int status, orte_process_name_t* sender, opal_buffer_t *buffer, orte_rml_tag_t tg, void *cbdata) { int rc, ret, room_num = -1; int32_t cnt; pmix_server_req_t *req=NULL; opal_list_t info; opal_value_t *iptr; opal_pmix_pdata_t *pdata; opal_process_name_t source; opal_output_verbose(1, orte_pmix_server_globals.output, "%s recvd lookup data return", ORTE_NAME_PRINT(ORTE_PROC_MY_NAME)); OBJ_CONSTRUCT(&info, opal_list_t); /* unpack the room number of the request tracker */ cnt = 1; if (OPAL_SUCCESS != (rc = opal_dss.unpack(buffer, &room_num, &cnt, OPAL_INT))) { ORTE_ERROR_LOG(rc); return; } /* unpack the status */ cnt = 1; if (OPAL_SUCCESS != (rc = opal_dss.unpack(buffer, &ret, &cnt, OPAL_INT))) { ORTE_ERROR_LOG(rc); ret = rc; goto release; } opal_output_verbose(5, orte_pmix_server_globals.output, "%s recvd lookup returned status %d", ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), ret); if (ORTE_SUCCESS == ret) { /* see if any data was included - not an error if the answer is no */ cnt = 1; while (OPAL_SUCCESS == opal_dss.unpack(buffer, &source, &cnt, OPAL_NAME)) { pdata = OBJ_NEW(opal_pmix_pdata_t); pdata->proc = source; if (OPAL_SUCCESS != (rc = opal_dss.unpack(buffer, &iptr, &cnt, OPAL_VALUE))) { ORTE_ERROR_LOG(rc); OBJ_RELEASE(pdata); continue; } opal_output_verbose(5, orte_pmix_server_globals.output, "%s recvd lookup returned data %s of type %d from source %s", ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), iptr->key, iptr->type, ORTE_NAME_PRINT(&source)); if (OPAL_SUCCESS != (rc = opal_value_xfer(&pdata->value, iptr))) { ORTE_ERROR_LOG(rc); OBJ_RELEASE(pdata); OBJ_RELEASE(iptr); continue; } OBJ_RELEASE(iptr); opal_list_append(&info, &pdata->super); } } release: if (0 <= room_num) { /* retrieve the tracker */ opal_hotel_checkout_and_return_occupant(&orte_pmix_server_globals.reqs, room_num, (void**)&req); } if (NULL != req) { /* pass down the response */ if (NULL != req->opcbfunc) { req->opcbfunc(ret, req->cbdata); } else if (NULL != req->lkcbfunc) { req->lkcbfunc(ret, &info, req->cbdata); } else { /* should not happen */ ORTE_ERROR_LOG(ORTE_ERR_NOT_SUPPORTED); } /* cleanup */ OPAL_LIST_DESTRUCT(&info); OBJ_RELEASE(req); } }