int publish_fn(const pmix_proc_t *proc, const pmix_info_t info[], size_t ninfo, pmix_op_cbfunc_t cbfunc, void *cbdata) { size_t i; int found; pmix_test_info_t *new_info, *old_info; if (NULL == pmix_test_published_list) { pmix_test_published_list = PMIX_NEW(pmix_list_t); } for (i = 0; i < ninfo; i++) { found = 0; PMIX_LIST_FOREACH(old_info, pmix_test_published_list, pmix_test_info_t) { if (!strcmp(old_info->data.key, info[i].key)) { found = 1; break; } } if (!found) { new_info = PMIX_NEW(pmix_test_info_t); strncpy(new_info->data.key, info[i].key, strlen(info[i].key)+1); pmix_value_xfer(&new_info->data.value, (pmix_value_t*)&info[i].value); new_info->namespace_published = strdup(proc->nspace); new_info->rank_published = proc->rank; pmix_list_append(pmix_test_published_list, &new_info->super); } } if (NULL != cbfunc) { cbfunc(PMIX_SUCCESS, cbdata); } return PMIX_SUCCESS; }
int PMIx_Disconnect_nb(const pmix_proc_t procs[], size_t nprocs, pmix_op_cbfunc_t cbfunc, void *cbdata) { pmix_buffer_t *msg; pmix_cmd_t cmd = PMIX_DISCONNECTNB_CMD; int rc; pmix_cb_t *cb; pmix_output_verbose(2, pmix_globals.debug_output, "pmix: disconnect called"); if (pmix_client_globals.init_cntr <= 0) { return PMIX_ERR_INIT; } /* if we aren't connected, don't attempt to send */ if (!pmix_globals.connected) { return PMIX_ERR_UNREACH; } /* check for bozo input */ if (NULL == procs || 0 >= nprocs) { return PMIX_ERR_BAD_PARAM; } msg = PMIX_NEW(pmix_buffer_t); /* pack the cmd */ if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &cmd, 1, PMIX_CMD))) { PMIX_ERROR_LOG(rc); return rc; } /* pack the number of procs */ if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &nprocs, 1, PMIX_SIZE))) { PMIX_ERROR_LOG(rc); return rc; } if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, procs, nprocs, PMIX_PROC))) { PMIX_ERROR_LOG(rc); return rc; } /* create a callback object as we need to pass it to the * recv routine so we know which callback to use when * the return message is recvd */ cb = PMIX_NEW(pmix_cb_t); cb->op_cbfunc = cbfunc; cb->cbdata = cbdata; /* push the message into our event base to send to the server */ PMIX_ACTIVATE_SEND_RECV(&pmix_client_globals.myserver, msg, wait_cbfunc, cb); pmix_output_verbose(2, pmix_globals.debug_output, "pmix: disconnect completed"); return PMIX_SUCCESS; }
PMIX_EXPORT pmix_status_t PMIx_Fence_nb(const pmix_proc_t procs[], size_t nprocs, const pmix_info_t info[], size_t ninfo, pmix_op_cbfunc_t cbfunc, void *cbdata) { pmix_buffer_t *msg; pmix_cmd_t cmd = PMIX_FENCENB_CMD; pmix_status_t rc; pmix_cb_t *cb; pmix_proc_t rg, *rgs; size_t nrg; pmix_output_verbose(2, pmix_globals.debug_output, "pmix: fence_nb called"); if (pmix_globals.init_cntr <= 0) { return PMIX_ERR_INIT; } /* if we aren't connected, don't attempt to send */ if (!pmix_globals.connected) { return PMIX_ERR_UNREACH; } /* check for bozo input */ if (NULL == procs && 0 != nprocs) { return PMIX_ERR_BAD_PARAM; } /* if we are given a NULL proc, then the caller is referencing * all procs within our own nspace */ if (NULL == procs) { (void)strncpy(rg.nspace, pmix_globals.myid.nspace, PMIX_MAX_NSLEN); rg.rank = PMIX_RANK_WILDCARD; rgs = &rg; nrg = 1; } else { rgs = (pmix_proc_t*)procs; nrg = nprocs; } msg = PMIX_NEW(pmix_buffer_t); if (PMIX_SUCCESS != (rc = pack_fence(msg, cmd, rgs, nrg, info, ninfo))) { PMIX_RELEASE(msg); return rc; } /* create a callback object as we need to pass it to the * recv routine so we know which callback to use when * the return message is recvd */ cb = PMIX_NEW(pmix_cb_t); cb->op_cbfunc = cbfunc; cb->cbdata = cbdata; /* push the message into our event base to send to the server */ PMIX_ACTIVATE_SEND_RECV(&pmix_client_globals.myserver, msg, wait_cbfunc, cb); return PMIX_SUCCESS; }
PMIX_EXPORT pmix_status_t PMIx_Lookup(pmix_pdata_t pdata[], size_t ndata, const pmix_info_t info[], size_t ninfo) { pmix_status_t rc; pmix_cb_t *cb; char **keys = NULL; size_t i; PMIX_ACQUIRE_THREAD(&pmix_global_lock); pmix_output_verbose(2, pmix_globals.debug_output, "pmix: lookup called"); if (pmix_globals.init_cntr <= 0) { PMIX_RELEASE_THREAD(&pmix_global_lock); return PMIX_ERR_INIT; } /* if we aren't connected, don't attempt to send */ if (!pmix_globals.connected) { PMIX_RELEASE_THREAD(&pmix_global_lock); return PMIX_ERR_UNREACH; } PMIX_RELEASE_THREAD(&pmix_global_lock); /* bozo protection */ if (NULL == pdata) { return PMIX_ERR_BAD_PARAM; } /* transfer the pdata keys to the keys argv array */ for (i=0; i < ndata; i++) { if ('\0' != pdata[i].key[0]) { pmix_argv_append_nosize(&keys, pdata[i].key); } } /* create a callback object as we need to pass it to the * recv routine so we know which callback to use when * the return message is recvd */ cb = PMIX_NEW(pmix_cb_t); cb->cbdata = (void*)pdata; cb->nvals = ndata; if (PMIX_SUCCESS != (rc = PMIx_Lookup_nb(keys, info, ninfo, lookup_cbfunc, cb))) { PMIX_RELEASE(cb); pmix_argv_free(keys); return rc; } /* wait for the server to ack our request */ PMIX_WAIT_THREAD(&cb->lock); /* the data has been stored in the info array by lookup_cbfunc, so * nothing more for us to do */ rc = cb->status; PMIX_RELEASE(cb); return rc; }
int PMIx_Disconnect(const pmix_proc_t procs[], size_t nprocs) { int rc; pmix_cb_t *cb; if (pmix_client_globals.init_cntr <= 0) { return PMIX_ERR_INIT; } /* if we aren't connected, don't attempt to send */ if (!pmix_globals.connected) { return PMIX_ERR_UNREACH; } /* create a callback object as we need to pass it to the * recv routine so we know which callback to use when * the return message is recvd */ cb = PMIX_NEW(pmix_cb_t); cb->active = true; if (PMIX_SUCCESS != (rc = PMIx_Disconnect_nb(procs, nprocs, op_cbfunc, cb))) { PMIX_RELEASE(cb); return rc; } /* wait for the connect to complete */ PMIX_WAIT_FOR_COMPLETION(cb->active); rc = cb->status; PMIX_RELEASE(cb); pmix_output_verbose(2, pmix_globals.debug_output, "pmix: disconnect completed"); return rc; }
pmix_status_t pmix_add_errhandler(pmix_notification_fn_t err, pmix_info_t *info, int ninfo, int *index) { int i; pmix_status_t rc = PMIX_SUCCESS; pmix_error_reg_info_t *errreg; errreg = PMIX_NEW(pmix_error_reg_info_t); errreg->errhandler = err; errreg->ninfo = ninfo; if (NULL != info && 0 < ninfo) { PMIX_INFO_CREATE(errreg->info, ninfo); for (i=0; i < ninfo; i++) { (void)strncpy(errreg->info[i].key, info[i].key, PMIX_MAX_KEYLEN); pmix_value_xfer(&errreg->info[i].value, &info[i].value); } } *index = pmix_pointer_array_add(&pmix_globals.errregs, errreg); pmix_output_verbose(2, pmix_globals.debug_output, "pmix_add_errhandler index =%d", *index); if (*index < 0) { PMIX_RELEASE(errreg); rc = PMIX_ERROR; } return rc; }
PMIX_EXPORT pmix_status_t PMIx_Unpublish(char **keys, const pmix_info_t info[], size_t ninfo) { pmix_status_t rc; pmix_cb_t *cb; pmix_output_verbose(2, pmix_globals.debug_output, "pmix: unpublish called"); /* create a callback object as we need to pass it to the * recv routine so we know which callback to use when * the return message is recvd */ cb = PMIX_NEW(pmix_cb_t); cb->active = true; /* push the message into our event base to send to the server */ if (PMIX_SUCCESS != (rc = PMIx_Unpublish_nb(keys, info, ninfo, op_cbfunc, cb))) { PMIX_RELEASE(cb); return rc; } /* wait for the server to ack our request */ PMIX_WAIT_FOR_COMPLETION(cb->active); rc = cb->status; PMIX_RELEASE(cb); return rc; }
static void save_value(const char *name, const char *value) { pmix_mca_base_var_file_value_t *fv; bool found = false; /* First traverse through the list and ensure that we don't already have a param of this name. If we do, just replace the value. */ PMIX_LIST_FOREACH(fv, _param_list, pmix_mca_base_var_file_value_t) { if (0 == strcmp(name, fv->mbvfv_var)) { if (NULL != fv->mbvfv_value) { free (fv->mbvfv_value); } found = true; break; } } if (!found) { /* We didn't already have the param, so append it to the list */ fv = PMIX_NEW(pmix_mca_base_var_file_value_t); if (NULL == fv) { return; } fv->mbvfv_var = strdup(name); pmix_list_append(_param_list, &fv->super); } fv->mbvfv_value = value ? strdup(value) : NULL; fv->mbvfv_file = file_being_read; fv->mbvfv_lineno = pmix_util_keyval_parse_lineno; }
PMIX_EXPORT pmix_status_t PMIx_Publish(const pmix_info_t info[], size_t ninfo) { pmix_status_t rc; pmix_cb_t *cb; pmix_output_verbose(2, pmix_globals.debug_output, "pmix: publish called"); if (pmix_globals.init_cntr <= 0) { return PMIX_ERR_INIT; } /* if we aren't connected, don't attempt to send */ if (!pmix_globals.connected) { return PMIX_ERR_UNREACH; } /* create a callback object to let us know when it is done */ cb = PMIX_NEW(pmix_cb_t); cb->active = true; if (PMIX_SUCCESS != (rc = PMIx_Publish_nb(info, ninfo, op_cbfunc, cb))) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(cb); return rc; } /* wait for the server to ack our request */ PMIX_WAIT_FOR_COMPLETION(cb->active); rc = (pmix_status_t)cb->status; PMIX_RELEASE(cb); return rc; }
int pmix_bfrop_copy_buf(pmix_buffer_t **dest, pmix_buffer_t *src, pmix_data_type_t type) { *dest = PMIX_NEW(pmix_buffer_t); pmix_bfrop.copy_payload(*dest, src); return PMIX_SUCCESS; }
static pmix_status_t setup_app(char *nspace, pmix_list_t *ilist) { uint64_t unique_key[2]; char *string_key, *cs_env; int fd_rand; size_t bytes_read; pmix_kval_t *kv; /* put the number here - or else create an appropriate string. this just needs to * eventually be a string variable */ if(-1 == (fd_rand = open("/dev/urandom", O_RDONLY))) { transports_use_rand(unique_key); } else { bytes_read = read(fd_rand, (char *) unique_key, 16); if(bytes_read != 16) { transports_use_rand(unique_key); } close(fd_rand); } if (NULL == (string_key = transports_print(unique_key))) { PMIX_ERROR_LOG(PMIX_ERR_OUT_OF_RESOURCE); return PMIX_ERR_OUT_OF_RESOURCE; } if (PMIX_SUCCESS != pmix_mca_base_var_env_name("pmix_precondition_transports", &cs_env)) { PMIX_ERROR_LOG(PMIX_ERR_OUT_OF_RESOURCE); free(string_key); return PMIX_ERR_OUT_OF_RESOURCE; } kv = PMIX_NEW(pmix_kval_t); if (NULL == kv) { free(string_key); free(cs_env); return PMIX_ERR_OUT_OF_RESOURCE; } kv->key = strdup(PMIX_SET_ENVAR); kv->value = (pmix_value_t*)malloc(sizeof(pmix_value_t)); if (NULL == kv->value) { free(string_key); free(cs_env); PMIX_RELEASE(kv); return PMIX_ERR_OUT_OF_RESOURCE; } kv->value->type = PMIX_STRING; if (0 > asprintf(&kv->value->data.string, "%s=%s", cs_env, string_key)) { free(string_key); free(cs_env); PMIX_RELEASE(kv); return PMIX_ERR_OUT_OF_RESOURCE; } pmix_list_append(ilist, &kv->super); free(cs_env); free(string_key); return PMIX_SUCCESS; }
static void query_cbfunc(struct pmix_peer_t *peer, pmix_ptl_hdr_t *hdr, pmix_buffer_t *buf, void *cbdata) { pmix_query_caddy_t *cd = (pmix_query_caddy_t*)cbdata; pmix_status_t rc; pmix_shift_caddy_t *results; int cnt; pmix_output_verbose(2, pmix_globals.debug_output, "pmix:query cback from server"); results = PMIX_NEW(pmix_shift_caddy_t); /* unpack the status */ cnt = 1; PMIX_BFROPS_UNPACK(rc, peer, buf, &results->status, &cnt, PMIX_STATUS); if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); results->status = rc; goto complete; } if (PMIX_SUCCESS != results->status) { goto complete; } /* unpack any returned data */ cnt = 1; PMIX_BFROPS_UNPACK(rc, peer, buf, &results->ninfo, &cnt, PMIX_SIZE); if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); results->status = rc; goto complete; } if (0 < results->ninfo) { PMIX_INFO_CREATE(results->info, results->ninfo); cnt = results->ninfo; PMIX_BFROPS_UNPACK(rc, peer, buf, results->info, &cnt, PMIX_INFO); if (PMIX_SUCCESS != rc) { PMIX_ERROR_LOG(rc); results->status = rc; goto complete; } } complete: pmix_output_verbose(2, pmix_globals.debug_output, "pmix:query cback from server releasing"); /* release the caller */ if (NULL != cd->cbfunc) { cd->cbfunc(results->status, results->info, results->ninfo, cd->cbdata, relcbfunc, results); } PMIX_RELEASE(cd); }
int PMIx_Lookup(pmix_data_range_t scope, const pmix_info_t info[], size_t ninfo, pmix_pdata_t pdata[], size_t ndata) { int rc; pmix_cb_t *cb; char **keys = NULL; size_t i; pmix_output_verbose(2, pmix_globals.debug_output, "pmix: lookup called"); /* bozo protection */ if (NULL == pdata) { return PMIX_ERR_BAD_PARAM; } /* transfer the pdata keys to the keys argv array */ for (i=0; i < ndata; i++) { if ('\0' != pdata[i].key[0]) { pmix_argv_append_nosize(&keys, pdata[i].key); } } /* create a callback object as we need to pass it to the * recv routine so we know which callback to use when * the return message is recvd */ cb = PMIX_NEW(pmix_cb_t); cb->cbdata = (void*)pdata; cb->nvals = ndata; cb->active = true; if (PMIX_SUCCESS != (rc = PMIx_Lookup_nb(scope, keys, info, ninfo, lookup_cbfunc, cb))) { PMIX_RELEASE(cb); pmix_argv_free(keys); return rc; } /* wait for the server to ack our request */ PMIX_WAIT_FOR_COMPLETION(cb->active); /* the data has been stored in the info array by lookup_cbfunc, so * nothing more for us to do */ rc = cb->status; PMIX_RELEASE(cb); return rc; }
static void pmix_usock_send(int sd, short args, void *cbdata) { pmix_ptl_queue_t *queue = (pmix_ptl_queue_t*)cbdata; pmix_ptl_send_t *snd; /* acquire the object */ PMIX_ACQUIRE_OBJECT(queue); if (NULL == queue->peer || queue->peer->sd < 0 || NULL == queue->peer->info || NULL == queue->peer->nptr) { /* this peer has lost connection */ PMIX_RELEASE(queue); /* ensure we post the object before another thread * picks it back up */ PMIX_POST_OBJECT(queue); return; } pmix_output_verbose(2, pmix_ptl_base_framework.framework_output, "[%s:%d] send to %s:%u on tag %d", __FILE__, __LINE__, (queue->peer)->info->pname.nspace, (queue->peer)->info->pname.rank, (queue->tag)); snd = PMIX_NEW(pmix_ptl_send_t); snd->hdr.pindex = htonl(pmix_globals.pindex); snd->hdr.tag = htonl(queue->tag); snd->hdr.nbytes = htonl((queue->buf)->bytes_used); snd->data = (queue->buf); /* always start with the header */ snd->sdptr = (char*)&snd->hdr; snd->sdbytes = sizeof(pmix_ptl_hdr_t); /* if there is no message on-deck, put this one there */ if (NULL == (queue->peer)->send_msg) { (queue->peer)->send_msg = snd; } else { /* add it to the queue */ pmix_list_append(&(queue->peer)->send_queue, &snd->super); } /* ensure the send event is active */ if (!(queue->peer)->send_ev_active) { (queue->peer)->send_ev_active = true; PMIX_POST_OBJECT(queue->peer); pmix_event_add(&(queue->peer)->send_event, 0); } PMIX_RELEASE(queue); PMIX_POST_OBJECT(snd); }
PMIX_EXPORT pmix_status_t PMIx_Fence(const pmix_proc_t procs[], size_t nprocs, const pmix_info_t info[], size_t ninfo) { pmix_cb_t *cb; pmix_status_t rc; PMIX_ACQUIRE_THREAD(&pmix_global_lock); pmix_output_verbose(2, pmix_globals.debug_output, "pmix: executing fence"); if (pmix_globals.init_cntr <= 0) { PMIX_RELEASE_THREAD(&pmix_global_lock); return PMIX_ERR_INIT; } /* if we aren't connected, don't attempt to send */ if (!pmix_globals.connected) { PMIX_RELEASE_THREAD(&pmix_global_lock); return PMIX_ERR_UNREACH; } PMIX_RELEASE_THREAD(&pmix_global_lock); /* create a callback object as we need to pass it to the * recv routine so we know which callback to use when * the return message is recvd */ cb = PMIX_NEW(pmix_cb_t); /* push the message into our event base to send to the server */ if (PMIX_SUCCESS != (rc = PMIx_Fence_nb(procs, nprocs, info, ninfo, op_cbfunc, cb))) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(cb); return rc; } /* wait for the fence to complete */ PMIX_WAIT_THREAD(&cb->lock); rc = cb->status; PMIX_RELEASE(cb); pmix_output_verbose(2, pmix_globals.debug_output, "pmix: fence released"); return rc; }
int pmix_bfrop_copy_kval(pmix_kval_t **dest, pmix_kval_t *src, pmix_data_type_t type) { pmix_kval_t *p; /* create the new object */ *dest = PMIX_NEW(pmix_kval_t); if (NULL == *dest) { return PMIX_ERR_OUT_OF_RESOURCE; } p = *dest; /* copy the type */ p->value->type = src->value->type; /* copy the data */ return pmix_value_xfer(p->value, src->value); }
pmix_status_t pmix_add_errhandler(pmix_notification_fn_t err, pmix_info_t *info, int ninfo, int *index) { int i; pmix_error_reg_info_t *errreg; if (0 != *index) { /* overwrite an existing entry */ errreg = (pmix_error_reg_info_t*)pmix_pointer_array_get_item(&pmix_globals.errregs, *index); if (NULL == errreg) { return PMIX_ERR_NOT_FOUND; } errreg->errhandler = err; PMIX_INFO_FREE(errreg->info, errreg->ninfo); errreg->ninfo = ninfo; } else { errreg = PMIX_NEW(pmix_error_reg_info_t); errreg->errhandler = err; errreg->ninfo = ninfo; *index = pmix_pointer_array_add(&pmix_globals.errregs, errreg); pmix_output_verbose(2, pmix_globals.debug_output, "pmix_add_errhandler index =%d", *index); if (*index < 0) { PMIX_RELEASE(errreg); return PMIX_ERROR; } } /* sadly, we have to copy the info objects as we cannot * rely on them to remain in-memory */ if (NULL != info && 0 < ninfo) { PMIX_INFO_CREATE(errreg->info, ninfo); for (i=0; i < ninfo; i++) { /* if this is a specific, single errhandler, then * mark it accordingly */ if (0 == strncmp(info[i].key, PMIX_ERROR_NAME, PMIX_MAX_KEYLEN)) { errreg->sglhdlr = true; } (void)strncpy(errreg->info[i].key, info[i].key, PMIX_MAX_KEYLEN); pmix_value_xfer(&errreg->info[i].value, &info[i].value); } } return PMIX_SUCCESS; }
static pmix_status_t send_oneway(struct pmix_peer_t *peer, pmix_buffer_t *bfr, pmix_ptl_tag_t tag) { pmix_ptl_queue_t *q; pmix_peer_t *pr = (pmix_peer_t*)peer; /* we have to transfer this to an event for thread * safety as we need to post this message on the * peer's send queue */ q = PMIX_NEW(pmix_ptl_queue_t); PMIX_RETAIN(pr); q->peer = pr; q->buf = bfr; q->tag = tag; PMIX_THREADSHIFT(q, pmix_ptl_base_send); return PMIX_SUCCESS; }
pmix_status_t pmix_add_errhandler(pmix_notification_fn_t err, pmix_info_t *info, int ninfo, int *index) { int i; pmix_status_t rc = PMIX_SUCCESS; pmix_error_reg_info_t *errreg = PMIX_NEW(pmix_error_reg_info_t); errreg->errhandler = err; errreg->ninfo = ninfo; PMIX_INFO_CREATE(errreg->info, ninfo); for (i=0; i < ninfo; i++) { memcpy(errreg->info[i].key, info[i].key, PMIX_MAX_KEYLEN); pmix_value_xfer(&errreg->info[i].value, &info[i].value); } *index = pmix_pointer_array_add (&pmix_globals.errregs, errreg); if (-1 == *index) rc = PMIX_ERROR; return rc; }
PMIX_EXPORT pmix_status_t PMIx_Spawn(const pmix_info_t job_info[], size_t ninfo, const pmix_app_t apps[], size_t napps, char nspace[]) { pmix_status_t rc; pmix_cb_t *cb; pmix_output_verbose(2, pmix_globals.debug_output, "pmix: spawn called"); if (pmix_globals.init_cntr <= 0) { return PMIX_ERR_INIT; } /* if we aren't connected, don't attempt to send */ if (!pmix_globals.connected) { return PMIX_ERR_UNREACH; } /* ensure the nspace (if provided) is initialized */ if (NULL != nspace) { memset(nspace, 0, PMIX_MAX_NSLEN+1); } /* create a callback object */ cb = PMIX_NEW(pmix_cb_t); cb->active = true; if (PMIX_SUCCESS != (rc = PMIx_Spawn_nb(job_info, ninfo, apps, napps, spawn_cbfunc, cb))) { PMIX_RELEASE(cb); return rc; } /* wait for the result */ PMIX_WAIT_FOR_COMPLETION(cb->active); rc = cb->status; if (NULL != nspace) { (void)strncpy(nspace, cb->nspace, PMIX_MAX_NSLEN); } PMIX_RELEASE(cb); return rc; }
static pmix_status_t send_recv(struct pmix_peer_t *peer, pmix_buffer_t *bfr, pmix_ptl_cbfunc_t cbfunc, void *cbdata) { pmix_ptl_sr_t *ms; pmix_output_verbose(5, pmix_globals.debug_output, "[%s:%d] post send to server", __FILE__, __LINE__); ms = PMIX_NEW(pmix_ptl_sr_t); ms->peer = peer; ms->bfr = bfr; ms->cbfunc = cbfunc; ms->cbdata = cbdata; PMIX_THREADSHIFT(ms, pmix_ptl_base_send_recv); return PMIX_SUCCESS; }
PMIX_EXPORT pmix_status_t PMIx_Unpublish(char **keys, const pmix_info_t info[], size_t ninfo) { pmix_status_t rc; pmix_cb_t *cb; PMIX_ACQUIRE_THREAD(&pmix_global_lock); pmix_output_verbose(2, pmix_globals.debug_output, "pmix: unpublish called"); if (pmix_globals.init_cntr <= 0) { PMIX_RELEASE_THREAD(&pmix_global_lock); return PMIX_ERR_INIT; } /* if we aren't connected, don't attempt to send */ if (!pmix_globals.connected) { PMIX_RELEASE_THREAD(&pmix_global_lock); return PMIX_ERR_UNREACH; } PMIX_RELEASE_THREAD(&pmix_global_lock); /* create a callback object as we need to pass it to the * recv routine so we know which callback to use when * the return message is recvd */ cb = PMIX_NEW(pmix_cb_t); /* push the message into our event base to send to the server */ if (PMIX_SUCCESS != (rc = PMIx_Unpublish_nb(keys, info, ninfo, op_cbfunc, cb))) { PMIX_RELEASE(cb); return rc; } /* wait for the server to ack our request */ PMIX_WAIT_THREAD(&cb->lock); rc = cb->status; PMIX_RELEASE(cb); return rc; }
static pmix_status_t send_recv(struct pmix_peer_t *peer, pmix_buffer_t *bfr, pmix_ptl_cbfunc_t cbfunc, void *cbdata) { pmix_ptl_sr_t *ms; pmix_output_verbose(5, pmix_globals.debug_output, "[%s:%d] post send to server", __FILE__, __LINE__); ms = PMIX_NEW(pmix_ptl_sr_t); ms->peer = peer; ms->bfr = bfr; ms->cbfunc = cbfunc; ms->cbdata = cbdata; pmix_event_assign(&ms->ev, pmix_globals.evbase, -1, EV_WRITE, pmix_ptl_base_send_recv, ms); pmix_event_active(&ms->ev, EV_WRITE, 1); return PMIX_SUCCESS; }
static pmix_status_t send_oneway(struct pmix_peer_t *peer, pmix_buffer_t *bfr, pmix_ptl_tag_t tag) { pmix_ptl_queue_t *q; pmix_peer_t *pr = (pmix_peer_t*)peer; /* we have to transfer this to an event for thread * safety as we need to post this message on the * peer's send queue */ q = PMIX_NEW(pmix_ptl_queue_t); PMIX_RETAIN(pr); q->peer = peer; q->buf = bfr; q->tag = tag; pmix_event_assign(&q->ev, pmix_globals.evbase, -1, EV_WRITE, pmix_ptl_base_send, q); pmix_event_active(&q->ev, EV_WRITE, 1); return PMIX_SUCCESS; }
static pmix_status_t send_recv(struct pmix_peer_t *peer, pmix_buffer_t *bfr, pmix_ptl_cbfunc_t cbfunc, void *cbdata) { pmix_ptl_sr_t *ms; pmix_peer_t *pr = (pmix_peer_t*)peer; pmix_output_verbose(2, pmix_ptl_base_framework.framework_output, "[%s:%d] post send to server", __FILE__, __LINE__); ms = PMIX_NEW(pmix_ptl_sr_t); PMIX_RETAIN(pr); ms->peer = pr; ms->bfr = bfr; ms->cbfunc = cbfunc; ms->cbdata = cbdata; PMIX_THREADSHIFT(ms, pmix_usock_send_recv); return PMIX_SUCCESS; }
void pmix_usock_init(pmix_usock_cbfunc_t cbfunc) { pmix_usock_posted_recv_t *req; /* setup the usock globals */ PMIX_CONSTRUCT(&pmix_usock_globals.posted_recvs, pmix_list_t); /* if a cbfunc was given, post a persistent recv * for the special 0 tag so the client can recv * error notifications from the server */ if (NULL != cbfunc) { req = PMIX_NEW(pmix_usock_posted_recv_t); req->tag = 0; req->cbfunc = cbfunc; pmix_output_verbose(5, pmix_globals.debug_output, "posting notification recv on tag %d", req->tag); /* add it to the list of recvs - we cannot have unexpected messages * in this subsystem as the server never sends us something that * we didn't previously request */ pmix_list_prepend(&pmix_usock_globals.posted_recvs, &req->super); } }
pmix_status_t pmix_bfrop_unpack_buf(pmix_buffer_t *buffer, void *dest, int32_t *num_vals, pmix_data_type_t type) { pmix_buffer_t **ptr; int32_t i, n, m; pmix_status_t ret; size_t nbytes; ptr = (pmix_buffer_t **) dest; n = *num_vals; for (i = 0; i < n; ++i) { /* allocate the new object */ ptr[i] = PMIX_NEW(pmix_buffer_t); if (NULL == ptr[i]) { return PMIX_ERR_OUT_OF_RESOURCE; } /* unpack the number of bytes */ m=1; if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_sizet(buffer, &nbytes, &m, PMIX_SIZE))) { return ret; } m = nbytes; /* setup the buffer's data region */ if (0 < nbytes) { ptr[i]->base_ptr = (char*)malloc(nbytes); /* unpack the bytes */ if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_byte(buffer, ptr[i]->base_ptr, &m, PMIX_BYTE))) { return ret; } } ptr[i]->pack_ptr = ptr[i]->base_ptr + m; ptr[i]->unpack_ptr = ptr[i]->base_ptr; ptr[i]->bytes_allocated = nbytes; ptr[i]->bytes_used = m; } return PMIX_SUCCESS; }
PMIX_EXPORT pmix_status_t PMIx_Unpublish_nb(char **keys, const pmix_info_t info[], size_t ninfo, pmix_op_cbfunc_t cbfunc, void *cbdata) { pmix_buffer_t *msg; pmix_cmd_t cmd = PMIX_UNPUBLISHNB_CMD; pmix_status_t rc; pmix_cb_t *cb; size_t i, j; pmix_output_verbose(2, pmix_globals.debug_output, "pmix: unpublish called"); if (pmix_globals.init_cntr <= 0) { return PMIX_ERR_INIT; } /* create the unpublish cmd */ msg = PMIX_NEW(pmix_buffer_t); /* pack the cmd */ if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &cmd, 1, PMIX_CMD))) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } /* pack our effective userid - will be used to constrain lookup */ if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &pmix_globals.uid, 1, PMIX_UINT32))) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } /* pack the number of keys */ i = pmix_argv_count(keys); if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &i, 1, PMIX_SIZE))) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } if (0 < i) { for (j=0; j < i; j++) { if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &keys[j], 1, PMIX_STRING))) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } } } /* pass the number of info structs - needed on remote end so * space can be malloc'd for the values */ if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &ninfo, 1, PMIX_SIZE))) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } /* pack the info structs */ if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, info, ninfo, PMIX_INFO))) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } /* create a callback object */ cb = PMIX_NEW(pmix_cb_t); cb->op_cbfunc = cbfunc; cb->cbdata = cbdata; cb->active = true; /* send to the server */ if (PMIX_SUCCESS != (rc = pmix_ptl.send_recv(&pmix_client_globals.myserver, msg, wait_cbfunc, (void*)cb))){ PMIX_RELEASE(msg); PMIX_RELEASE(cb); } return rc; }
PMIX_EXPORT pmix_status_t PMIx_Lookup_nb(char **keys, const pmix_info_t info[], size_t ninfo, pmix_lookup_cbfunc_t cbfunc, void *cbdata) { pmix_buffer_t *msg; pmix_cmd_t cmd = PMIX_LOOKUPNB_CMD; pmix_status_t rc; pmix_cb_t *cb; size_t nkeys, n; pmix_output_verbose(2, pmix_globals.debug_output, "pmix: lookup called"); if (pmix_globals.init_cntr <= 0) { return PMIX_ERR_INIT; } /* check for bozo cases */ if (NULL == keys) { return PMIX_ERR_BAD_PARAM; } /* create the lookup cmd */ msg = PMIX_NEW(pmix_buffer_t); /* pack the cmd */ if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &cmd, 1, PMIX_CMD))) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } /* pack our effective userid - will be used to constrain lookup */ if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &pmix_globals.uid, 1, PMIX_UINT32))) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } /* pack the keys */ nkeys = pmix_argv_count(keys); if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &nkeys, 1, PMIX_SIZE))) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } if (0 < nkeys) { for (n=0; n < nkeys; n++) { if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &keys[n], 1, PMIX_STRING))) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } } } /* pass the number of info structs - needed on remote end so * space can be malloc'd for the values */ if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &ninfo, 1, PMIX_SIZE))) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } /* pack the info structs */ if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, info, ninfo, PMIX_INFO))) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } /* create a callback object as we need to pass it to the * recv routine so we know which callback to use when * the return message is recvd */ cb = PMIX_NEW(pmix_cb_t); cb->lookup_cbfunc = cbfunc; cb->cbdata = cbdata; /* send to the server */ if (PMIX_SUCCESS != (rc = pmix_ptl.send_recv(&pmix_client_globals.myserver, msg, wait_lookup_cbfunc, (void*)cb))){ PMIX_RELEASE(msg); PMIX_RELEASE(cb); } return rc; }
PMIX_EXPORT pmix_status_t PMIx_Publish_nb(const pmix_info_t info[], size_t ninfo, pmix_op_cbfunc_t cbfunc, void *cbdata) { pmix_buffer_t *msg; pmix_cmd_t cmd = PMIX_PUBLISHNB_CMD; pmix_status_t rc; pmix_cb_t *cb; pmix_output_verbose(2, pmix_globals.debug_output, "pmix: publish called"); if (pmix_globals.init_cntr <= 0) { return PMIX_ERR_INIT; } /* if we aren't connected, don't attempt to send */ if (!pmix_globals.connected) { return PMIX_ERR_UNREACH; } /* check for bozo cases */ if (NULL == info) { /* nothing to publish */ PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM); return PMIX_ERR_BAD_PARAM; } /* create the publish cmd */ msg = PMIX_NEW(pmix_buffer_t); /* pack the cmd */ if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &cmd, 1, PMIX_CMD))) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } /* pack our effective userid - will be used to constrain lookup */ if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &pmix_globals.uid, 1, PMIX_UINT32))) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } /* pass the number of info structs - needed on remote end so * space can be malloc'd for the values */ if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, &ninfo, 1, PMIX_SIZE))) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } /* pack the info structs */ if (PMIX_SUCCESS != (rc = pmix_bfrop.pack(msg, info, ninfo, PMIX_INFO))) { PMIX_ERROR_LOG(rc); PMIX_RELEASE(msg); return rc; } /* create a callback object as we need to pass it to the * recv routine so we know which callback to use when * the return message is recvd */ cb = PMIX_NEW(pmix_cb_t); cb->op_cbfunc = cbfunc; cb->cbdata = cbdata; cb->active = true; /* push the message into our event base to send to the server */ if (PMIX_SUCCESS != (rc = pmix_ptl.send_recv(&pmix_client_globals.myserver, msg, wait_cbfunc, (void*)cb))){ PMIX_RELEASE(msg); PMIX_RELEASE(cb); } return rc; }