root/opal/mca/pmix/pmix4x/pmix4x_client.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. errreg_cbfunc
  2. pmix4x_client_init
  3. dereg_cbfunc
  4. pmix4x_client_finalize
  5. pmix4x_tool_init
  6. pmix4x_tool_fini
  7. pmix4x_initialized
  8. pmix4x_abort
  9. pmix4x_store_local
  10. pmix4x_commit
  11. opcbfunc
  12. pmix4x_fence
  13. pmix4x_fencenb
  14. pmix4x_put
  15. pmix4x_get
  16. val_cbfunc
  17. pmix4x_getnb
  18. pmix4x_publish
  19. pmix4x_publishnb
  20. pmix4x_lookup
  21. lk_cbfunc
  22. pmix4x_lookupnb
  23. pmix4x_unpublish
  24. pmix4x_unpublishnb
  25. pmix4x_spawn
  26. spcbfunc
  27. pmix4x_spawnnb
  28. pmix4x_connect
  29. pmix4x_connectnb
  30. pmix4x_disconnect
  31. pmix4x_disconnectnb
  32. pmix4x_resolve_peers
  33. pmix4x_resolve_nodes
  34. relcbfunc
  35. infocbfunc
  36. pmix4x_allocate
  37. pmix4x_job_control

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2014-2018 Intel, Inc. All rights reserved.
   4  * Copyright (c) 2014-2017 Research Organization for Information Science
   5  *                         and Technology (RIST). All rights reserved.
   6  * Copyright (c) 2014-2017 Mellanox Technologies, Inc.
   7  *                         All rights reserved.
   8  * Copyright (c) 2016      Cisco Systems, Inc.  All rights reserved.
   9  * Copyright (c) 2016      Los Alamos National Security, LLC. All rights
  10  *                         reserved.
  11  * Copyright (c) 2017-2018 The University of Tennessee and The University
  12  *                         of Tennessee Research Foundation.  All rights
  13  *                         reserved.
  14  * Copyright (c) 2019      IBM Corporation.  All rights reserved.
  15  * $COPYRIGHT$
  16  *
  17  * Additional copyrights may follow
  18  *
  19  * $HEADER$
  20  */
  21 
  22 #include "opal_config.h"
  23 #include "opal/constants.h"
  24 #include "opal/types.h"
  25 
  26 #ifdef HAVE_STRING_H
  27 #include <string.h>
  28 #endif
  29 #ifdef HAVE_UNISTD_H
  30 #include <unistd.h>
  31 #endif
  32 
  33 #include "opal/hash_string.h"
  34 #include "opal/threads/threads.h"
  35 #include "opal/util/argv.h"
  36 #include "opal/util/opal_environ.h"
  37 #include "opal/util/proc.h"
  38 #include "opal/util/show_help.h"
  39 
  40 #include "opal/mca/pmix/base/base.h"
  41 #include "pmix4x.h"
  42 #include "pmix.h"
  43 #include "pmix_tool.h"
  44 
  45 static char *dbgvalue=NULL;
  46 
  47 static void errreg_cbfunc (pmix_status_t status,
  48                            size_t errhandler_ref,
  49                            void *cbdata)
  50 {
  51     opal_pmix4x_event_t *event = (opal_pmix4x_event_t*)cbdata;
  52 
  53     OPAL_ACQUIRE_OBJECT(event);
  54 
  55     event->index = errhandler_ref;
  56     opal_output_verbose(5, opal_pmix_base_framework.framework_output,
  57                         "PMIX client errreg_cbfunc - error handler registered status=%d, reference=%lu",
  58                         status, (unsigned long)errhandler_ref);
  59     OPAL_POST_OBJECT(event);
  60     OPAL_PMIX_WAKEUP_THREAD(&event->lock);
  61 }
  62 
  63 int pmix4x_client_init(opal_list_t *ilist)
  64 {
  65     opal_process_name_t pname;
  66     pmix_status_t rc;
  67     int dbg;
  68     opal_pmix4x_jobid_trkr_t *job;
  69     opal_pmix4x_event_t *event;
  70     pmix_info_t *pinfo;
  71     size_t ninfo, n;
  72     opal_value_t *ival;
  73 
  74     opal_output_verbose(1, opal_pmix_base_framework.framework_output,
  75                         "PMIx_client init");
  76 
  77     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
  78 
  79     if (0 == opal_pmix_base.initialized) {
  80         if (0 < (dbg = opal_output_get_verbosity(opal_pmix_base_framework.framework_output))) {
  81             asprintf(&dbgvalue, "PMIX_DEBUG=%d", dbg);
  82             putenv(dbgvalue);
  83         }
  84         /* check the evars for a mismatch */
  85         if (OPAL_SUCCESS != (dbg = opal_pmix_pmix4x_check_evars())) {
  86             OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
  87             return dbg;
  88         }
  89     }
  90 
  91     /* convert the incoming list to info structs */
  92     if (NULL != ilist && 0 < (ninfo = opal_list_get_size(ilist))) {
  93         PMIX_INFO_CREATE(pinfo, ninfo);
  94         n=0;
  95         OPAL_LIST_FOREACH(ival, ilist, opal_value_t) {
  96             (void)strncpy(pinfo[n].key, ival->key, PMIX_MAX_KEYLEN);
  97             pmix4x_value_load(&pinfo[n].value, ival);
  98             ++n;
  99         }
 100     } else {
 101         pinfo = NULL;
 102         ninfo = 0;
 103     }
 104 
 105     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 106     rc = PMIx_Init(&mca_pmix_pmix4x_component.myproc, pinfo, ninfo);
 107     if (NULL != pinfo) {
 108         PMIX_INFO_FREE(pinfo, ninfo);
 109     }
 110     if (PMIX_SUCCESS != rc) {
 111         dbg = pmix4x_convert_rc(rc);
 112         OPAL_ERROR_LOG(dbg);
 113         return dbg;
 114     }
 115     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
 116 
 117     ++opal_pmix_base.initialized;
 118     if (1 < opal_pmix_base.initialized) {
 119         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 120         return OPAL_SUCCESS;
 121     }
 122 
 123     /* store our jobid and rank */
 124     if (NULL != getenv(OPAL_MCA_PREFIX"orte_launch")) {
 125         /* if we were launched by the OMPI RTE, then
 126          * the jobid is in a special format - so get it */
 127         mca_pmix_pmix4x_component.native_launch = true;
 128         opal_convert_string_to_jobid(&pname.jobid, mca_pmix_pmix4x_component.myproc.nspace);
 129     } else {
 130         /* we were launched by someone else, so make the
 131          * jobid just be the hash of the nspace */
 132         OPAL_HASH_JOBID(mca_pmix_pmix4x_component.myproc.nspace, pname.jobid);
 133     }
 134     /* insert this into our list of jobids - it will be the
 135      * first, and so we'll check it first */
 136     job = OBJ_NEW(opal_pmix4x_jobid_trkr_t);
 137     (void)strncpy(job->nspace, mca_pmix_pmix4x_component.myproc.nspace, PMIX_MAX_NSLEN);
 138     job->jobid = pname.jobid;
 139     opal_list_append(&mca_pmix_pmix4x_component.jobids, &job->super);
 140 
 141     pname.vpid = pmix4x_convert_rank(mca_pmix_pmix4x_component.myproc.rank);
 142     opal_proc_set_name(&pname);
 143 
 144     /* release the thread in case the event handler fires when
 145      * registered */
 146     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 147 
 148     /* register the default event handler */
 149     event = OBJ_NEW(opal_pmix4x_event_t);
 150     opal_list_append(&mca_pmix_pmix4x_component.events, &event->super);
 151     PMIX_INFO_CREATE(pinfo, 1);
 152     PMIX_INFO_LOAD(&pinfo[0], PMIX_EVENT_HDLR_NAME, "OPAL-PMIX-2X-DEFAULT", PMIX_STRING);
 153     PMIx_Register_event_handler(NULL, 0, NULL, 0, pmix4x_event_hdlr, errreg_cbfunc, event);
 154     OPAL_PMIX_WAIT_THREAD(&event->lock);
 155     PMIX_INFO_FREE(pinfo, 1);
 156 
 157     return OPAL_SUCCESS;
 158 
 159 }
 160 
 161 static void dereg_cbfunc(pmix_status_t st, void *cbdata)
 162 {
 163     opal_pmix4x_event_t *ev = (opal_pmix4x_event_t*)cbdata;
 164     OPAL_PMIX_WAKEUP_THREAD(&ev->lock);
 165 }
 166 
 167 int pmix4x_client_finalize(void)
 168 {
 169     pmix_status_t rc;
 170     opal_pmix4x_event_t *event, *ev2;
 171     opal_list_t evlist;
 172     OBJ_CONSTRUCT(&evlist, opal_list_t);
 173 
 174     opal_output_verbose(1, opal_pmix_base_framework.framework_output,
 175                         "PMIx_client finalize");
 176 
 177     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
 178     --opal_pmix_base.initialized;
 179 
 180     if (0 == opal_pmix_base.initialized) {
 181         /* deregister all event handlers */
 182         OPAL_LIST_FOREACH_SAFE(event, ev2, &mca_pmix_pmix4x_component.events, opal_pmix4x_event_t) {
 183             OPAL_PMIX_DESTRUCT_LOCK(&event->lock);
 184             OPAL_PMIX_CONSTRUCT_LOCK(&event->lock);
 185             PMIx_Deregister_event_handler(event->index, dereg_cbfunc, (void*)event);
 186             opal_list_remove_item(&mca_pmix_pmix4x_component.events, &event->super);
 187             /* wait and release outside the loop to avoid double mutex
 188              * interlock */
 189             opal_list_append(&evlist, &event->super);
 190         }
 191     }
 192     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 193     OPAL_LIST_FOREACH_SAFE(event, ev2, &evlist, opal_pmix4x_event_t) {
 194         OPAL_PMIX_WAIT_THREAD(&event->lock);
 195         opal_list_remove_item(&evlist, &event->super);
 196         OBJ_RELEASE(event);
 197     }
 198     OBJ_DESTRUCT(&evlist);
 199     rc = PMIx_Finalize(NULL, 0);
 200 
 201     return pmix4x_convert_rc(rc);
 202 }
 203 
 204 int pmix4x_tool_init(opal_list_t *info)
 205 {
 206     pmix_info_t *pinfo;
 207     size_t ninfo, n;
 208     opal_pmix4x_jobid_trkr_t *job;
 209     opal_value_t *val;
 210     pmix_status_t rc;
 211     int ret;
 212     opal_process_name_t pname = {OPAL_JOBID_INVALID, OPAL_VPID_INVALID};
 213     opal_pmix4x_event_t *event;
 214 
 215     opal_output_verbose(1, opal_pmix_base_framework.framework_output,
 216                         "PMIx_tool init");
 217 
 218     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
 219 
 220     /* convert the incoming list to info structs */
 221     if (NULL != info && 0 < (ninfo = opal_list_get_size(info))) {
 222         PMIX_INFO_CREATE(pinfo, ninfo);
 223         n=0;
 224         OPAL_LIST_FOREACH(val, info, opal_value_t) {
 225             (void)strncpy(pinfo[n].key, val->key, PMIX_MAX_KEYLEN);
 226             pmix4x_value_load(&pinfo[n].value, val);
 227             ++n;
 228             /* check to see if our name is being given from above */
 229             if (0 == strcmp(val->key, OPAL_PMIX_TOOL_NSPACE)) {
 230                 opal_convert_string_to_jobid(&pname.jobid, val->data.string);
 231                 (void)strncpy(mca_pmix_pmix4x_component.myproc.nspace, val->data.string, PMIX_MAX_NSLEN);
 232             } else if (0 == strcmp(val->key, OPAL_PMIX_TOOL_RANK)) {
 233                 pname.vpid = val->data.name.vpid;
 234                 mca_pmix_pmix4x_component.myproc.rank = pname.vpid;
 235             }
 236         }
 237     } else {
 238         pinfo = NULL;
 239         ninfo = 0;
 240     }
 241     /* we are going to get our name from the server, or we were given it by the tool,
 242      * so mark as native launch so we don't convert back/forth */
 243     mca_pmix_pmix4x_component.native_launch = true;
 244 
 245     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 246     rc = PMIx_tool_init(&mca_pmix_pmix4x_component.myproc, pinfo, ninfo);
 247     if (NULL != pinfo) {
 248         PMIX_INFO_FREE(pinfo, ninfo);
 249     }
 250     if (PMIX_SUCCESS != rc) {
 251         ret = pmix4x_convert_rc(rc);
 252         OPAL_ERROR_LOG(ret);
 253         return ret;
 254     }
 255     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
 256 
 257     ++opal_pmix_base.initialized;
 258     if (1 < opal_pmix_base.initialized) {
 259         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 260         return OPAL_SUCCESS;
 261     }
 262 
 263     /* store our jobid and rank */
 264     opal_convert_string_to_jobid(&pname.jobid, mca_pmix_pmix4x_component.myproc.nspace);
 265     pname.vpid = pmix4x_convert_rank(mca_pmix_pmix4x_component.myproc.rank);
 266 
 267     /* insert this into our list of jobids - it will be the
 268      * first, and so we'll check it first */
 269     job = OBJ_NEW(opal_pmix4x_jobid_trkr_t);
 270     (void)strncpy(job->nspace, mca_pmix_pmix4x_component.myproc.nspace, PMIX_MAX_NSLEN);
 271     job->jobid = pname.jobid;
 272     opal_list_append(&mca_pmix_pmix4x_component.jobids, &job->super);
 273 
 274     opal_proc_set_name(&pname);
 275 
 276     /* release the thread in case the event handler fires when
 277      * registered */
 278     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 279 
 280     /* register the default event handler */
 281     event = OBJ_NEW(opal_pmix4x_event_t);
 282     opal_list_append(&mca_pmix_pmix4x_component.events, &event->super);
 283     PMIX_INFO_CREATE(pinfo, 1);
 284     PMIX_INFO_LOAD(&pinfo[0], PMIX_EVENT_HDLR_NAME, "OPAL-PMIX-2X-DEFAULT", PMIX_STRING);
 285     PMIx_Register_event_handler(NULL, 0, NULL, 0, pmix4x_event_hdlr, errreg_cbfunc, event);
 286     OPAL_PMIX_WAIT_THREAD(&event->lock);
 287     PMIX_INFO_FREE(pinfo, 1);
 288 
 289     return OPAL_SUCCESS;
 290 }
 291 
 292 int pmix4x_tool_fini(void)
 293 {
 294     pmix_status_t rc;
 295     opal_pmix4x_event_t *event, *ev2;
 296 
 297     opal_output_verbose(1, opal_pmix_base_framework.framework_output,
 298                         "PMIx_tool finalize");
 299 
 300     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
 301     --opal_pmix_base.initialized;
 302 
 303     if (0 == opal_pmix_base.initialized) {
 304         /* deregister all event handlers */
 305         OPAL_LIST_FOREACH_SAFE(event, ev2, &mca_pmix_pmix4x_component.events, opal_pmix4x_event_t) {
 306             OPAL_PMIX_DESTRUCT_LOCK(&event->lock);
 307             OPAL_PMIX_CONSTRUCT_LOCK(&event->lock);
 308             PMIx_Deregister_event_handler(event->index, dereg_cbfunc, (void*)event);
 309             OPAL_PMIX_WAIT_THREAD(&event->lock);
 310             opal_list_remove_item(&mca_pmix_pmix4x_component.events, &event->super);
 311             OBJ_RELEASE(event);
 312         }
 313     }
 314     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 315     rc = PMIx_tool_finalize();
 316 
 317     return pmix4x_convert_rc(rc);
 318 }
 319 
 320 
 321 int pmix4x_initialized(void)
 322 {
 323     int init;
 324 
 325     opal_output_verbose(1, opal_pmix_base_framework.framework_output,
 326                         "PMIx_client initialized");
 327 
 328     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
 329     init = opal_pmix_base.initialized;
 330     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 331 
 332     return init;
 333 }
 334 
 335 int pmix4x_abort(int flag, const char *msg,
 336                  opal_list_t *procs)
 337 {
 338     pmix_status_t rc;
 339     pmix_proc_t *parray=NULL;
 340     size_t n, cnt=0;
 341     opal_namelist_t *ptr;
 342     char *nsptr;
 343 
 344     opal_output_verbose(1, opal_pmix_base_framework.framework_output,
 345                         "PMIx_client abort");
 346 
 347     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
 348     if (0 >= opal_pmix_base.initialized) {
 349         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 350         return OPAL_ERR_NOT_INITIALIZED;
 351     }
 352     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 353 
 354     /* convert the list of procs to an array
 355      * of pmix_proc_t */
 356     if (NULL != procs && 0 < (cnt = opal_list_get_size(procs))) {
 357         PMIX_PROC_CREATE(parray, cnt);
 358         n=0;
 359         OPAL_LIST_FOREACH(ptr, procs, opal_namelist_t) {
 360             if (NULL == (nsptr = pmix4x_convert_jobid(ptr->name.jobid))) {
 361                 PMIX_PROC_FREE(parray, cnt);
 362                 return OPAL_ERR_NOT_FOUND;
 363             }
 364             (void)strncpy(parray[n].nspace, nsptr, PMIX_MAX_NSLEN);
 365             parray[n].rank = pmix4x_convert_opalrank(ptr->name.vpid);
 366             ++n;
 367         }
 368     }
 369 
 370     /* call the library abort - this is a blocking call */
 371     rc = PMIx_Abort(flag, msg, parray, cnt);
 372 
 373     /* release the array */
 374     PMIX_PROC_FREE(parray, cnt);
 375 
 376     return pmix4x_convert_rc(rc);
 377 }
 378 
 379 int pmix4x_store_local(const opal_process_name_t *proc, opal_value_t *val)
 380 {
 381     pmix_value_t kv;
 382     pmix_status_t rc;
 383     pmix_proc_t p;
 384     char *nsptr;
 385     opal_pmix4x_jobid_trkr_t *job;
 386 
 387     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
 388 
 389     if (0 >= opal_pmix_base.initialized) {
 390         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 391         return OPAL_ERR_NOT_INITIALIZED;
 392     }
 393     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 394 
 395     if (NULL != proc) {
 396         if (NULL == (nsptr = pmix4x_convert_jobid(proc->jobid))) {
 397             job = OBJ_NEW(opal_pmix4x_jobid_trkr_t);
 398             (void)opal_snprintf_jobid(job->nspace, PMIX_MAX_NSLEN, proc->jobid);
 399             job->jobid = proc->jobid;
 400             OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
 401             opal_list_append(&mca_pmix_pmix4x_component.jobids, &job->super);
 402             OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 403             nsptr = job->nspace;
 404         }
 405         (void)strncpy(p.nspace, nsptr, PMIX_MAX_NSLEN);
 406         p.rank = pmix4x_convert_opalrank(proc->vpid);
 407     } else {
 408         /* use our name */
 409         (void)strncpy(p.nspace, mca_pmix_pmix4x_component.myproc.nspace, PMIX_MAX_NSLEN);
 410         p.rank = pmix4x_convert_opalrank(OPAL_PROC_MY_NAME.vpid);
 411     }
 412 
 413     PMIX_VALUE_CONSTRUCT(&kv);
 414     pmix4x_value_load(&kv, val);
 415 
 416     /* call the library - this is a blocking call */
 417     rc = PMIx_Store_internal(&p, val->key, &kv);
 418     PMIX_VALUE_DESTRUCT(&kv);
 419 
 420     return pmix4x_convert_rc(rc);
 421 }
 422 
 423 int pmix4x_commit(void)
 424 {
 425     pmix_status_t rc;
 426 
 427     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
 428     if (0 >= opal_pmix_base.initialized) {
 429         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 430         return OPAL_ERR_NOT_INITIALIZED;
 431     }
 432     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 433 
 434     rc = PMIx_Commit();
 435     return pmix4x_convert_rc(rc);
 436 }
 437 
 438 static void opcbfunc(pmix_status_t status, void *cbdata)
 439 {
 440     pmix4x_opcaddy_t *op = (pmix4x_opcaddy_t*)cbdata;
 441 
 442     OPAL_ACQUIRE_OBJECT(op);
 443     if (NULL != op->opcbfunc) {
 444         op->opcbfunc(pmix4x_convert_rc(status), op->cbdata);
 445     }
 446     OBJ_RELEASE(op);
 447 }
 448 
 449 int pmix4x_fence(opal_list_t *procs, int collect_data)
 450 {
 451     pmix_status_t rc;
 452     opal_namelist_t *ptr;
 453     char *nsptr;
 454     size_t cnt = 0, n;
 455     pmix_proc_t *parray = NULL;
 456     pmix_info_t info, *iptr;
 457 
 458     opal_output_verbose(1, opal_pmix_base_framework.framework_output,
 459                         "PMIx_client fence");
 460 
 461     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
 462     if (0 >= opal_pmix_base.initialized) {
 463         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 464         return OPAL_ERR_NOT_INITIALIZED;
 465     }
 466 
 467     /* convert the list of procs to an array
 468      * of pmix_proc_t */
 469     if (NULL != procs && 0 < (cnt = opal_list_get_size(procs))) {
 470         PMIX_PROC_CREATE(parray, cnt);
 471         n=0;
 472         OPAL_LIST_FOREACH(ptr, procs, opal_namelist_t) {
 473             if (NULL == (nsptr = pmix4x_convert_jobid(ptr->name.jobid))) {
 474                 PMIX_PROC_FREE(parray, cnt);
 475                 OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 476                 return OPAL_ERR_NOT_FOUND;
 477             }
 478             (void)strncpy(parray[n].nspace, nsptr, PMIX_MAX_NSLEN);
 479             parray[n].rank = pmix4x_convert_opalrank(ptr->name.vpid);
 480             ++n;
 481         }
 482     }
 483     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 484 
 485     if (collect_data) {
 486         PMIX_INFO_CONSTRUCT(&info);
 487         (void)strncpy(info.key, PMIX_COLLECT_DATA, PMIX_MAX_KEYLEN);
 488         info.value.type = PMIX_BOOL;
 489         info.value.data.flag = true;
 490         iptr = &info;
 491         n = 1;
 492     } else {
 493         iptr = NULL;
 494         n = 0;
 495     }
 496 
 497     rc = PMIx_Fence(parray, cnt, iptr, n);
 498     if (collect_data) {
 499         PMIX_INFO_DESTRUCT(&info);
 500     }
 501     if (NULL != parray) {
 502         PMIX_PROC_FREE(parray, cnt);
 503     }
 504 
 505     return pmix4x_convert_rc(rc);
 506 }
 507 
 508 int pmix4x_fencenb(opal_list_t *procs, int collect_data,
 509                    opal_pmix_op_cbfunc_t cbfunc, void *cbdata)
 510 {
 511     pmix_status_t rc;
 512     pmix_proc_t *parray=NULL;
 513     size_t n, cnt=0;
 514     opal_namelist_t *ptr;
 515     pmix4x_opcaddy_t *op;
 516     char *nsptr;
 517 
 518     opal_output_verbose(1, opal_pmix_base_framework.framework_output,
 519                         "PMIx_client fencenb");
 520 
 521     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
 522     if (0 >= opal_pmix_base.initialized) {
 523         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 524         return OPAL_ERR_NOT_INITIALIZED;
 525     }
 526 
 527     /* convert the list of procs to an array
 528      * of pmix_proc_t */
 529     if (NULL != procs && 0 < (cnt = opal_list_get_size(procs))) {
 530         PMIX_PROC_CREATE(parray, cnt);
 531         n=0;
 532         OPAL_LIST_FOREACH(ptr, procs, opal_namelist_t) {
 533             if (NULL == (nsptr = pmix4x_convert_jobid(ptr->name.jobid))) {
 534                 PMIX_PROC_FREE(parray, cnt);
 535                 OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 536                 return OPAL_ERR_NOT_FOUND;
 537             }
 538             (void)strncpy(parray[n].nspace, nsptr, PMIX_MAX_NSLEN);
 539             parray[n].rank = pmix4x_convert_opalrank(ptr->name.vpid);
 540             ++n;
 541         }
 542     }
 543     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 544 
 545     /* create the caddy */
 546     op = OBJ_NEW(pmix4x_opcaddy_t);
 547     op->opcbfunc = cbfunc;
 548     op->cbdata = cbdata;
 549     op->procs = parray;
 550     op->nprocs = cnt;
 551 
 552     if (collect_data) {
 553         op->ninfo = 1;
 554         PMIX_INFO_CREATE(op->info, op->ninfo);
 555         PMIX_INFO_LOAD(&op->info[0], PMIX_COLLECT_DATA, NULL, PMIX_BOOL);
 556     }
 557 
 558     /* call the library function */
 559     rc = PMIx_Fence_nb(op->procs, op->nprocs, op->info, op->ninfo, opcbfunc, op);
 560     return pmix4x_convert_rc(rc);
 561 }
 562 
 563 int pmix4x_put(opal_pmix_scope_t opal_scope,
 564                opal_value_t *val)
 565 {
 566     pmix_value_t kv;
 567     pmix_scope_t pmix_scope = pmix4x_convert_opalscope(opal_scope);
 568     pmix_status_t rc;
 569 
 570     opal_output_verbose(1, opal_pmix_base_framework.framework_output,
 571                         "PMIx_client put");
 572 
 573     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
 574     if (0 >= opal_pmix_base.initialized) {
 575         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 576         return OPAL_ERR_NOT_INITIALIZED;
 577     }
 578     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 579 
 580     PMIX_VALUE_CONSTRUCT(&kv);
 581     pmix4x_value_load(&kv, val);
 582 
 583     rc = PMIx_Put(pmix_scope, val->key, &kv);
 584     PMIX_VALUE_DESTRUCT(&kv);
 585     return pmix4x_convert_rc(rc);
 586 }
 587 
 588 int pmix4x_get(const opal_process_name_t *proc, const char *key,
 589                opal_list_t *info, opal_value_t **val)
 590 {
 591     pmix_status_t rc;
 592     pmix_proc_t p;
 593     char *nsptr;
 594     pmix_info_t *pinfo = NULL;
 595     size_t sz = 0, n;
 596     opal_value_t *ival;
 597     pmix_value_t *pval = NULL;
 598     int ret;
 599 
 600     opal_output_verbose(1, opal_pmix_base_framework.framework_output,
 601                         "%s pmix4x:client get on proc %s key %s",
 602                         OPAL_NAME_PRINT(OPAL_PROC_MY_NAME),
 603                         (NULL == proc) ? "NULL" : OPAL_NAME_PRINT(*proc), key);
 604 
 605     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
 606     if (0 >= opal_pmix_base.initialized) {
 607         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 608         return OPAL_ERR_NOT_INITIALIZED;
 609     }
 610 
 611     if (NULL == proc) {
 612         /* if they are asking for our jobid, then return it */
 613         if (0 == strcmp(key, OPAL_PMIX_JOBID)) {
 614             (*val) = OBJ_NEW(opal_value_t);
 615             (*val)->key = strdup(key);
 616             (*val)->type = OPAL_UINT32;
 617             (*val)->data.uint32 = OPAL_PROC_MY_NAME.jobid;
 618             OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 619             return OPAL_SUCCESS;
 620         }
 621         /* if they are asking for our rank, return it */
 622         if (0 == strcmp(key, OPAL_PMIX_RANK)) {
 623             (*val) = OBJ_NEW(opal_value_t);
 624             (*val)->key = strdup(key);
 625             (*val)->type = OPAL_INT;
 626             (*val)->data.integer = pmix4x_convert_rank(mca_pmix_pmix4x_component.myproc.rank);
 627             OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 628             return OPAL_SUCCESS;
 629         }
 630     }
 631     *val = NULL;
 632 
 633     if (NULL == proc) {
 634         (void)strncpy(p.nspace, mca_pmix_pmix4x_component.myproc.nspace, PMIX_MAX_NSLEN);
 635         p.rank = pmix4x_convert_rank(PMIX_RANK_WILDCARD);
 636     } else {
 637         if (NULL == (nsptr = pmix4x_convert_jobid(proc->jobid))) {
 638             OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 639             return OPAL_ERR_NOT_FOUND;
 640         }
 641         (void)strncpy(p.nspace, nsptr, PMIX_MAX_NSLEN);
 642         p.rank = pmix4x_convert_opalrank(proc->vpid);
 643     }
 644     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 645 
 646     if (NULL != info && 0 < (sz = opal_list_get_size(info))) {
 647         PMIX_INFO_CREATE(pinfo, sz);
 648         n=0;
 649         OPAL_LIST_FOREACH(ival, info, opal_value_t) {
 650             (void)strncpy(pinfo[n].key, ival->key, PMIX_MAX_KEYLEN);
 651             pmix4x_value_load(&pinfo[n].value, ival);
 652             ++n;
 653         }
 654     }
 655 
 656     rc = PMIx_Get(&p, key, pinfo, sz, &pval);
 657     if (PMIX_SUCCESS == rc) {
 658         ival = OBJ_NEW(opal_value_t);
 659         if (NULL != key) {
 660             ival->key = strdup(key);
 661         }
 662         if (OPAL_SUCCESS != (ret = pmix4x_value_unload(ival, pval))) {
 663             rc = pmix4x_convert_opalrc(ret);
 664         } else {
 665             *val = ival;
 666         }
 667         PMIX_VALUE_FREE(pval, 1);
 668     }
 669     PMIX_INFO_FREE(pinfo, sz);
 670 
 671     return pmix4x_convert_rc(rc);
 672 }
 673 
 674 static void val_cbfunc(pmix_status_t status,
 675                        pmix_value_t *kv, void *cbdata)
 676 {
 677     pmix4x_opcaddy_t *op = (pmix4x_opcaddy_t*)cbdata;
 678     int rc;
 679     opal_value_t val, *v=NULL;
 680 
 681     OPAL_ACQUIRE_OBJECT(op);
 682     OBJ_CONSTRUCT(&val, opal_value_t);
 683     if (NULL != op->nspace) {
 684         val.key = strdup(op->nspace);
 685     }
 686     rc = pmix4x_convert_opalrc(status);
 687     if (PMIX_SUCCESS == status && NULL != kv) {
 688         rc = pmix4x_value_unload(&val, kv);
 689         v = &val;
 690     }
 691 
 692     if (NULL != op->valcbfunc) {
 693         op->valcbfunc(rc, v, op->cbdata);
 694     }
 695     OBJ_DESTRUCT(&val);
 696     OBJ_RELEASE(op);
 697 }
 698 
 699 int pmix4x_getnb(const opal_process_name_t *proc, const char *key,
 700                  opal_list_t *info,
 701                  opal_pmix_value_cbfunc_t cbfunc, void *cbdata)
 702 {
 703     pmix4x_opcaddy_t *op;
 704     opal_value_t *val;
 705     pmix_status_t rc;
 706     char *nsptr;
 707     size_t n;
 708 
 709     opal_output_verbose(1, opal_pmix_base_framework.framework_output,
 710                         "%s PMIx_client get_nb on proc %s key %s",
 711                         OPAL_NAME_PRINT(OPAL_PROC_MY_NAME),
 712                         (NULL == proc) ? "NULL" : OPAL_NAME_PRINT(*proc), key);
 713 
 714     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
 715     if (0 >= opal_pmix_base.initialized) {
 716         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 717         return OPAL_ERR_NOT_INITIALIZED;
 718     }
 719 
 720     if (NULL == proc) {
 721         /* if they are asking for our jobid, then return it */
 722         if (0 == strcmp(key, OPAL_PMIX_JOBID)) {
 723             if (NULL != cbfunc) {
 724                 val = OBJ_NEW(opal_value_t);
 725                 val->key = strdup(key);
 726                 val->type = OPAL_UINT32;
 727                 val->data.uint32 = OPAL_PROC_MY_NAME.jobid;
 728                 cbfunc(OPAL_SUCCESS, val, cbdata);
 729             }
 730             OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 731             return OPAL_SUCCESS;
 732         }
 733         /* if they are asking for our rank, return it */
 734         if (0 == strcmp(key, OPAL_PMIX_RANK)) {
 735             if (NULL != cbfunc) {
 736                 val = OBJ_NEW(opal_value_t);
 737                 val->key = strdup(key);
 738                 val->type = OPAL_INT;
 739                 val->data.integer = pmix4x_convert_rank(mca_pmix_pmix4x_component.myproc.rank);
 740                 cbfunc(OPAL_SUCCESS, val, cbdata);
 741             }
 742             OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 743             return OPAL_SUCCESS;
 744         }
 745     }
 746 
 747     /* create the caddy */
 748     op = OBJ_NEW(pmix4x_opcaddy_t);
 749     op->valcbfunc = cbfunc;
 750     op->cbdata = cbdata;
 751     if (NULL != key) {
 752         op->nspace = strdup(key);
 753     }
 754     if (NULL == proc) {
 755         (void)strncpy(op->p.nspace, mca_pmix_pmix4x_component.myproc.nspace, PMIX_MAX_NSLEN);
 756         op->p.rank = pmix4x_convert_rank(PMIX_RANK_WILDCARD);
 757     } else {
 758         if (NULL == (nsptr = pmix4x_convert_jobid(proc->jobid))) {
 759             OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 760             return OPAL_ERR_NOT_FOUND;
 761         }
 762         (void)strncpy(op->p.nspace, nsptr, PMIX_MAX_NSLEN);
 763         op->p.rank = pmix4x_convert_opalrank(proc->vpid);
 764     }
 765     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 766 
 767     if (NULL != info && 0 < (op->sz = opal_list_get_size(info))) {
 768         PMIX_INFO_CREATE(op->info, op->sz);
 769         n=0;
 770         OPAL_LIST_FOREACH(val, info, opal_value_t) {
 771             (void)strncpy(op->info[n].key, val->key, PMIX_MAX_KEYLEN);
 772             pmix4x_value_load(&op->info[n].value, val);
 773             ++n;
 774         }
 775     }
 776 
 777     /* call the library function */
 778     rc = PMIx_Get_nb(&op->p, key, op->info, op->sz, val_cbfunc, op);
 779     if (PMIX_SUCCESS != rc) {
 780         OBJ_RELEASE(op);
 781     }
 782 
 783     return pmix4x_convert_rc(rc);
 784 }
 785 
 786 int pmix4x_publish(opal_list_t *info)
 787 {
 788     pmix_info_t *pinfo;
 789     pmix_status_t ret;
 790     opal_value_t *iptr;
 791     size_t sz, n;
 792 
 793     opal_output_verbose(1, opal_pmix_base_framework.framework_output,
 794                         "PMIx_client publish");
 795 
 796     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
 797     if (0 >= opal_pmix_base.initialized) {
 798         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 799         return OPAL_ERR_NOT_INITIALIZED;
 800     }
 801     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 802 
 803     if (NULL == info) {
 804         return OPAL_ERR_BAD_PARAM;
 805     }
 806 
 807     sz = opal_list_get_size(info);
 808     if (0 < sz) {
 809         PMIX_INFO_CREATE(pinfo, sz);
 810         n=0;
 811         OPAL_LIST_FOREACH(iptr, info, opal_value_t) {
 812             (void)strncpy(pinfo[n].key, iptr->key, PMIX_MAX_KEYLEN);
 813             pmix4x_value_load(&pinfo[n].value, iptr);
 814             ++n;
 815         }
 816     } else {
 817         pinfo = NULL;
 818     }
 819 
 820     ret = PMIx_Publish(pinfo, sz);
 821     if (0 < sz) {
 822         PMIX_INFO_FREE(pinfo, sz);
 823     }
 824 
 825     return pmix4x_convert_rc(ret);
 826 }
 827 
 828 int pmix4x_publishnb(opal_list_t *info,
 829                      opal_pmix_op_cbfunc_t cbfunc, void *cbdata)
 830 {
 831     pmix_status_t ret;
 832     opal_value_t *iptr;
 833     size_t n;
 834     pmix4x_opcaddy_t *op;
 835 
 836     opal_output_verbose(1, opal_pmix_base_framework.framework_output,
 837                         "PMIx_client publish_nb");
 838 
 839     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
 840     if (0 >= opal_pmix_base.initialized) {
 841         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 842         return OPAL_ERR_NOT_INITIALIZED;
 843     }
 844     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 845 
 846     if (NULL == info) {
 847         return OPAL_ERR_BAD_PARAM;
 848     }
 849 
 850     /* create the caddy */
 851     op = OBJ_NEW(pmix4x_opcaddy_t);
 852     op->opcbfunc = cbfunc;
 853     op->cbdata = cbdata;
 854 
 855     op->sz = opal_list_get_size(info);
 856     if (0 < op->sz) {
 857         PMIX_INFO_CREATE(op->info, op->sz);
 858         n=0;
 859         OPAL_LIST_FOREACH(iptr, info, opal_value_t) {
 860             (void)strncpy(op->info[n].key, iptr->key, PMIX_MAX_KEYLEN);
 861             pmix4x_value_load(&op->info[n].value, iptr);
 862             ++n;
 863         }
 864     }
 865 
 866     ret = PMIx_Publish_nb(op->info, op->sz, opcbfunc, op);
 867 
 868     return pmix4x_convert_rc(ret);
 869 }
 870 
 871 int pmix4x_lookup(opal_list_t *data, opal_list_t *info)
 872 {
 873     opal_pmix_pdata_t *d;
 874     pmix_pdata_t *pdata;
 875     pmix_info_t *pinfo = NULL;
 876     pmix_status_t rc;
 877     size_t cnt, n, sz = 0;
 878     opal_value_t *iptr;
 879     opal_pmix4x_jobid_trkr_t *jptr, *job;
 880     int ret;
 881 
 882     opal_output_verbose(1, opal_pmix_base_framework.framework_output,
 883                         "pmix4x:client lookup");
 884 
 885     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
 886     if (0 >= opal_pmix_base.initialized) {
 887         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 888         return OPAL_ERR_NOT_INITIALIZED;
 889     }
 890     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 891 
 892     if (NULL == data || 0 == (cnt = opal_list_get_size(data))) {
 893         return OPAL_ERR_BAD_PARAM;
 894     }
 895     PMIX_PDATA_CREATE(pdata, cnt);
 896     n = 0;
 897     OPAL_LIST_FOREACH(d, data, opal_pmix_pdata_t) {
 898         (void)strncpy(pdata[n].key, d->value.key, PMIX_MAX_KEYLEN);
 899         ++n;
 900     }
 901 
 902     if (NULL != info && 0 < (sz = opal_list_get_size(info))) {
 903         PMIX_INFO_CREATE(pinfo, sz);
 904         n=0;
 905         OPAL_LIST_FOREACH(iptr, info, opal_value_t) {
 906             (void)strncpy(pinfo[n].key, iptr->key, PMIX_MAX_KEYLEN);
 907             pmix4x_value_load(&pinfo[n].value, iptr);
 908             ++n;
 909         }
 910     }
 911 
 912     rc = PMIx_Lookup(pdata, cnt, pinfo, sz);
 913     if (PMIX_SUCCESS == rc) {
 914         /* load the answers back into the list */
 915         n=0;
 916         OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
 917         OPAL_LIST_FOREACH(d, data, opal_pmix_pdata_t) {
 918             if (mca_pmix_pmix4x_component.native_launch) {
 919                 /* if we were launched by the OMPI RTE, then
 920                  * the jobid is in a special format - so get it */
 921                 opal_convert_string_to_jobid(&d->proc.jobid, pdata[n].proc.nspace);
 922             } else {
 923                 /* we were launched by someone else, so make the
 924                  * jobid just be the hash of the nspace */
 925                 OPAL_HASH_JOBID(pdata[n].proc.nspace, d->proc.jobid);
 926             }
 927             /* if we don't already have it, add this to our jobid tracker */
 928             job = NULL;
 929             OPAL_LIST_FOREACH(jptr, &mca_pmix_pmix4x_component.jobids, opal_pmix4x_jobid_trkr_t) {
 930                 if (jptr->jobid == d->proc.jobid) {
 931                     job = jptr;
 932                     break;
 933                 }
 934             }
 935             if (NULL == job) {
 936                 job = OBJ_NEW(opal_pmix4x_jobid_trkr_t);
 937                 (void)strncpy(job->nspace, pdata[n].proc.nspace, PMIX_MAX_NSLEN);
 938                 job->jobid = d->proc.jobid;
 939                 opal_list_append(&mca_pmix_pmix4x_component.jobids, &job->super);
 940             }
 941             d->proc.vpid = pmix4x_convert_rank(pdata[n].proc.rank);
 942             if (OPAL_SUCCESS != (ret = pmix4x_value_unload(&d->value, &pdata[n].value))) {
 943                 OPAL_ERROR_LOG(ret);
 944             }
 945         }
 946         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
 947     }
 948     PMIX_PDATA_FREE(pdata, cnt);
 949     if (NULL != pinfo) {
 950         PMIX_INFO_FREE(pinfo, sz);
 951     }
 952     return pmix4x_convert_rc(rc);
 953 }
 954 
 955 static void lk_cbfunc(pmix_status_t status,
 956                       pmix_pdata_t data[], size_t ndata,
 957                       void *cbdata)
 958 {
 959     pmix4x_opcaddy_t *op = (pmix4x_opcaddy_t*)cbdata;
 960     opal_pmix_pdata_t *d;
 961     opal_list_t results, *r = NULL;
 962     int rc;
 963     size_t n;
 964     opal_pmix4x_jobid_trkr_t *job, *jptr;
 965 
 966     OPAL_ACQUIRE_OBJECT(op);
 967 
 968     if (NULL == op->lkcbfunc) {
 969         OBJ_RELEASE(op);
 970         return;
 971     }
 972 
 973     rc = pmix4x_convert_rc(op->status);
 974     if (OPAL_SUCCESS == rc) {
 975         OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
 976         OBJ_CONSTRUCT(&results, opal_list_t);
 977         for (n=0; n < ndata; n++) {
 978             d = OBJ_NEW(opal_pmix_pdata_t);
 979             opal_list_append(&results, &d->super);
 980             if (mca_pmix_pmix4x_component.native_launch) {
 981                 /* if we were launched by the OMPI RTE, then
 982                  * the jobid is in a special format - so get it */
 983                 opal_convert_string_to_jobid(&d->proc.jobid, data[n].proc.nspace);
 984             } else {
 985                 /* we were launched by someone else, so make the
 986                  * jobid just be the hash of the nspace */
 987                 OPAL_HASH_JOBID(data[n].proc.nspace, d->proc.jobid);
 988             }
 989             /* if we don't already have it, add this to our jobid tracker */
 990             job = NULL;
 991             OPAL_LIST_FOREACH(jptr, &mca_pmix_pmix4x_component.jobids, opal_pmix4x_jobid_trkr_t) {
 992                 if (jptr->jobid == d->proc.jobid) {
 993                     job = jptr;
 994                     break;
 995                 }
 996             }
 997             if (NULL == job) {
 998                 job = OBJ_NEW(opal_pmix4x_jobid_trkr_t);
 999                 (void)strncpy(job->nspace, data[n].proc.nspace, PMIX_MAX_NSLEN);
1000                 job->jobid = d->proc.jobid;
1001                 opal_list_append(&mca_pmix_pmix4x_component.jobids, &job->super);
1002             }
1003             d->proc.vpid = pmix4x_convert_rank(data[n].proc.rank);
1004             d->value.key = strdup(data[n].key);
1005             rc = pmix4x_value_unload(&d->value, &data[n].value);
1006             if (OPAL_SUCCESS != rc) {
1007                 rc = OPAL_ERR_BAD_PARAM;
1008                 OPAL_ERROR_LOG(rc);
1009                 OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1010                 goto release;
1011             }
1012         }
1013         r = &results;
1014         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1015     }
1016 
1017   release:
1018     /* execute the callback */
1019     op->lkcbfunc(rc, r, op->cbdata);
1020 
1021     if (NULL != r) {
1022         OPAL_LIST_DESTRUCT(&results);
1023     }
1024     OBJ_RELEASE(op);
1025 }
1026 
1027 int pmix4x_lookupnb(char **keys, opal_list_t *info,
1028                     opal_pmix_lookup_cbfunc_t cbfunc, void *cbdata)
1029 {
1030     pmix_status_t ret;
1031     pmix4x_opcaddy_t *op;
1032     opal_value_t *iptr;
1033     size_t n;
1034 
1035 
1036     opal_output_verbose(1, opal_pmix_base_framework.framework_output,
1037                         "pmix4x:client lookup_nb");
1038 
1039     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
1040     if (0 >= opal_pmix_base.initialized) {
1041         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1042         return OPAL_ERR_NOT_INITIALIZED;
1043     }
1044     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1045 
1046     /* create the caddy */
1047     op = OBJ_NEW(pmix4x_opcaddy_t);
1048     op->lkcbfunc = cbfunc;
1049     op->cbdata = cbdata;
1050 
1051     if (NULL != info && 0 < (op->sz = opal_list_get_size(info))) {
1052         PMIX_INFO_CREATE(op->info, op->sz);
1053         n=0;
1054         OPAL_LIST_FOREACH(iptr, info, opal_value_t) {
1055             (void)strncpy(op->info[n].key, iptr->key, PMIX_MAX_KEYLEN);
1056             pmix4x_value_load(&op->info[n].value, iptr);
1057             ++n;
1058         }
1059     }
1060     ret = PMIx_Lookup_nb(keys, op->info, op->sz, lk_cbfunc, op);
1061 
1062     return pmix4x_convert_rc(ret);
1063 }
1064 
1065 int pmix4x_unpublish(char **keys, opal_list_t *info)
1066 {
1067     pmix_status_t ret;
1068     size_t ninfo, n;
1069     pmix_info_t *pinfo;
1070     opal_value_t *iptr;
1071 
1072     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
1073     if (0 >= opal_pmix_base.initialized) {
1074         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1075         return OPAL_ERR_NOT_INITIALIZED;
1076     }
1077     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1078 
1079     if (NULL != info && 0 < (ninfo = opal_list_get_size(info))) {
1080         PMIX_INFO_CREATE(pinfo, ninfo);
1081         n=0;
1082         OPAL_LIST_FOREACH(iptr, info, opal_value_t) {
1083             (void)strncpy(pinfo[n].key, iptr->key, PMIX_MAX_KEYLEN);
1084             pmix4x_value_load(&pinfo[n].value, iptr);
1085             ++n;
1086         }
1087     } else {
1088         pinfo = NULL;
1089         ninfo = 0;
1090     }
1091 
1092     ret = PMIx_Unpublish(keys, pinfo, ninfo);
1093     PMIX_INFO_FREE(pinfo, ninfo);
1094 
1095     return pmix4x_convert_rc(ret);
1096 }
1097 
1098 int pmix4x_unpublishnb(char **keys, opal_list_t *info,
1099                        opal_pmix_op_cbfunc_t cbfunc, void *cbdata)
1100 {
1101     pmix_status_t ret;
1102     pmix4x_opcaddy_t *op;
1103     opal_value_t *iptr;
1104     size_t n;
1105 
1106     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
1107     if (0 >= opal_pmix_base.initialized) {
1108         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1109         return OPAL_ERR_NOT_INITIALIZED;
1110     }
1111     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1112 
1113     /* create the caddy */
1114     op = OBJ_NEW(pmix4x_opcaddy_t);
1115     op->opcbfunc = cbfunc;
1116     op->cbdata = cbdata;
1117 
1118     if (NULL != info && 0 < (op->sz = opal_list_get_size(info))) {
1119         PMIX_INFO_CREATE(op->info, op->sz);
1120         n=0;
1121         OPAL_LIST_FOREACH(iptr, info, opal_value_t) {
1122             (void)strncpy(op->info[n].key, iptr->key, PMIX_MAX_KEYLEN);
1123             pmix4x_value_load(&op->info[n].value, iptr);
1124             ++n;
1125         }
1126     }
1127 
1128     ret = PMIx_Unpublish_nb(keys, op->info, op->sz, opcbfunc, op);
1129 
1130     return pmix4x_convert_rc(ret);
1131 }
1132 
1133 int pmix4x_spawn(opal_list_t *job_info, opal_list_t *apps, opal_jobid_t *jobid)
1134 {
1135     pmix_status_t rc;
1136     pmix_info_t *info = NULL;
1137     pmix_app_t *papps;
1138     size_t ninfo = 0, napps, n, m;
1139     opal_value_t *ival;
1140     opal_pmix_app_t *app;
1141     char nspace[PMIX_MAX_NSLEN+1];
1142     opal_pmix4x_jobid_trkr_t *job;
1143 
1144     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
1145     if (0 >= opal_pmix_base.initialized) {
1146         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1147         return OPAL_ERR_NOT_INITIALIZED;
1148     }
1149     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1150 
1151     *jobid = OPAL_JOBID_INVALID;
1152 
1153     if (NULL != job_info && 0 < (ninfo = opal_list_get_size(job_info))) {
1154         PMIX_INFO_CREATE(info, ninfo);
1155         n=0;
1156         OPAL_LIST_FOREACH(ival, job_info, opal_value_t) {
1157             (void)strncpy(info[n].key, ival->key, PMIX_MAX_KEYLEN);
1158             pmix4x_value_load(&info[n].value, ival);
1159             ++n;
1160         }
1161     }
1162 
1163     napps = opal_list_get_size(apps);
1164     PMIX_APP_CREATE(papps, napps);
1165     n=0;
1166     OPAL_LIST_FOREACH(app, apps, opal_pmix_app_t) {
1167         papps[n].cmd = strdup(app->cmd);
1168         if (NULL != app->argv) {
1169             papps[n].argv = opal_argv_copy(app->argv);
1170         }
1171         if (NULL != app->env) {
1172             papps[n].env = opal_argv_copy(app->env);
1173         }
1174         if (NULL != app->cwd) {
1175             papps[n].cwd = strdup(app->cwd);
1176         }
1177         papps[n].maxprocs = app->maxprocs;
1178         if (0 < (papps[n].ninfo = opal_list_get_size(&app->info))) {
1179             PMIX_INFO_CREATE(papps[n].info, papps[n].ninfo);
1180             m=0;
1181             OPAL_LIST_FOREACH(ival, &app->info, opal_value_t) {
1182                 (void)strncpy(papps[n].info[m].key, ival->key, PMIX_MAX_KEYLEN);
1183                 pmix4x_value_load(&papps[n].info[m].value, ival);
1184                 ++m;
1185             }
1186         }
1187         ++n;
1188     }
1189 
1190     rc = PMIx_Spawn(info, ninfo, papps, napps, nspace);
1191     if (PMIX_SUCCESS == rc) {
1192         OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
1193         if (mca_pmix_pmix4x_component.native_launch) {
1194             /* if we were launched by the OMPI RTE, then
1195              * the jobid is in a special format - so get it */
1196             opal_convert_string_to_jobid(jobid, nspace);
1197         } else {
1198             /* we were launched by someone else, so make the
1199              * jobid just be the hash of the nspace */
1200             OPAL_HASH_JOBID(nspace, *jobid);
1201         }
1202         /* add this to our jobid tracker */
1203         job = OBJ_NEW(opal_pmix4x_jobid_trkr_t);
1204         (void)strncpy(job->nspace, nspace, PMIX_MAX_NSLEN);
1205         job->jobid = *jobid;
1206         opal_list_append(&mca_pmix_pmix4x_component.jobids, &job->super);
1207         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1208     }
1209     return rc;
1210 }
1211 
1212 static void spcbfunc(pmix_status_t status,
1213                      char *nspace, void *cbdata)
1214 {
1215     pmix4x_opcaddy_t *op = (pmix4x_opcaddy_t*)cbdata;
1216     opal_pmix4x_jobid_trkr_t *job;
1217     opal_jobid_t jobid = OPAL_JOBID_INVALID;
1218     int rc;
1219 
1220     OPAL_ACQUIRE_OBJECT(op);
1221 
1222     rc = pmix4x_convert_rc(status);
1223     if (PMIX_SUCCESS == status) {
1224         /* this is in the PMIx local thread - need to protect
1225          * the framework-level data */
1226         OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
1227         if (mca_pmix_pmix4x_component.native_launch) {
1228             /* if we were launched by the OMPI RTE, then
1229              * the jobid is in a special format - so get it */
1230             opal_convert_string_to_jobid(&jobid, nspace);
1231         } else {
1232             /* we were launched by someone else, so make the
1233              * jobid just be the hash of the nspace */
1234             OPAL_HASH_JOBID(nspace, jobid);
1235         }
1236         /* add this to our jobid tracker */
1237         job = OBJ_NEW(opal_pmix4x_jobid_trkr_t);
1238         (void)strncpy(job->nspace, nspace, PMIX_MAX_NSLEN);
1239         job->jobid = jobid;
1240         opal_list_append(&mca_pmix_pmix4x_component.jobids, &job->super);
1241         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1242     }
1243 
1244     op->spcbfunc(rc, jobid, op->cbdata);
1245     OBJ_RELEASE(op);
1246 }
1247 
1248 int pmix4x_spawnnb(opal_list_t *job_info, opal_list_t *apps,
1249                    opal_pmix_spawn_cbfunc_t cbfunc, void *cbdata)
1250 {
1251     pmix_status_t ret;
1252     pmix4x_opcaddy_t *op;
1253     size_t n, m;
1254     opal_value_t *info;
1255     opal_pmix_app_t *app;
1256 
1257     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
1258     if (0 >= opal_pmix_base.initialized) {
1259         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1260         return OPAL_ERR_NOT_INITIALIZED;
1261     }
1262     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1263 
1264     /* create the caddy */
1265     op = OBJ_NEW(pmix4x_opcaddy_t);
1266     op->spcbfunc = cbfunc;
1267     op->cbdata = cbdata;
1268 
1269     if (NULL != job_info && 0 < (op->ninfo = opal_list_get_size(job_info))) {
1270         PMIX_INFO_CREATE(op->info, op->ninfo);
1271         n=0;
1272         OPAL_LIST_FOREACH(info, job_info, opal_value_t) {
1273             (void)strncpy(op->info[n].key, info->key, PMIX_MAX_KEYLEN);
1274             pmix4x_value_load(&op->info[n].value, info);
1275             ++n;
1276         }
1277     }
1278 
1279     op->sz = opal_list_get_size(apps);
1280     PMIX_APP_CREATE(op->apps, op->sz);
1281     n=0;
1282     OPAL_LIST_FOREACH(app, apps, opal_pmix_app_t) {
1283         op->apps[n].cmd = strdup(app->cmd);
1284         if (NULL != app->argv) {
1285             op->apps[n].argv = opal_argv_copy(app->argv);
1286         }
1287         if (NULL != app->env) {
1288             op->apps[n].env = opal_argv_copy(app->env);
1289         }
1290         op->apps[n].maxprocs = app->maxprocs;
1291         if (0 < (op->apps[n].ninfo = opal_list_get_size(&app->info))) {
1292             PMIX_INFO_CREATE(op->apps[n].info, op->apps[n].ninfo);
1293             m=0;
1294             OPAL_LIST_FOREACH(info, &app->info, opal_value_t) {
1295                 (void)strncpy(op->apps[n].info[m].key, info->key, PMIX_MAX_KEYLEN);
1296                 pmix4x_value_load(&op->apps[n].info[m].value, info);
1297                 ++m;
1298             }
1299         }
1300         ++n;
1301     }
1302 
1303     ret = PMIx_Spawn_nb(op->info, op->ninfo, op->apps, op->sz, spcbfunc, op);
1304 
1305     return pmix4x_convert_rc(ret);
1306 }
1307 
1308 int pmix4x_connect(opal_list_t *procs)
1309 {
1310     pmix_proc_t *p;
1311     size_t nprocs;
1312     opal_namelist_t *ptr;
1313     pmix_status_t ret;
1314     char *nsptr;
1315     size_t n;
1316 
1317     opal_output_verbose(1, opal_pmix_base_framework.framework_output,
1318                         "pmix4x:client connect");
1319 
1320     /* protect against bozo error */
1321     if (NULL == procs || 0 == (nprocs = opal_list_get_size(procs))) {
1322         return OPAL_ERR_BAD_PARAM;
1323     }
1324 
1325     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
1326     if (0 >= opal_pmix_base.initialized) {
1327         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1328         return OPAL_ERR_NOT_INITIALIZED;
1329     }
1330 
1331     /* convert the list of procs to an array
1332      * of pmix_proc_t */
1333     PMIX_PROC_CREATE(p, nprocs);
1334     n=0;
1335     OPAL_LIST_FOREACH(ptr, procs, opal_namelist_t) {
1336         if (NULL == (nsptr = pmix4x_convert_jobid(ptr->name.jobid))) {
1337             PMIX_PROC_FREE(p, nprocs);
1338             OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1339             return OPAL_ERR_NOT_FOUND;
1340         }
1341         (void)strncpy(p[n].nspace, nsptr, PMIX_MAX_NSLEN);
1342         p[n].rank = pmix4x_convert_opalrank(ptr->name.vpid);
1343         ++n;
1344     }
1345     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1346 
1347     ret = PMIx_Connect(p, nprocs, NULL, 0);
1348     PMIX_PROC_FREE(p, nprocs);
1349 
1350     return pmix4x_convert_rc(ret);
1351 }
1352 
1353 int pmix4x_connectnb(opal_list_t *procs,
1354                      opal_pmix_op_cbfunc_t cbfunc,
1355                      void *cbdata)
1356 {
1357     pmix4x_opcaddy_t *op;
1358     opal_namelist_t *ptr;
1359     pmix_status_t ret;
1360     char *nsptr;
1361     size_t n;
1362 
1363     opal_output_verbose(1, opal_pmix_base_framework.framework_output,
1364                         "pmix4x:client connect NB");
1365 
1366     /* protect against bozo error */
1367     if (NULL == procs || 0 == opal_list_get_size(procs)) {
1368         return OPAL_ERR_BAD_PARAM;
1369     }
1370 
1371     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
1372     if (0 >= opal_pmix_base.initialized) {
1373         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1374         return OPAL_ERR_NOT_INITIALIZED;
1375     }
1376 
1377     /* create the caddy */
1378     op = OBJ_NEW(pmix4x_opcaddy_t);
1379     op->opcbfunc = cbfunc;
1380     op->cbdata = cbdata;
1381     op->nprocs = opal_list_get_size(procs);
1382 
1383     /* convert the list of procs to an array
1384      * of pmix_proc_t */
1385     PMIX_PROC_CREATE(op->procs, op->nprocs);
1386     n=0;
1387     OPAL_LIST_FOREACH(ptr, procs, opal_namelist_t) {
1388         if (NULL == (nsptr = pmix4x_convert_jobid(ptr->name.jobid))) {
1389             OBJ_RELEASE(op);
1390             OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1391             return OPAL_ERR_NOT_FOUND;
1392         }
1393         (void)strncpy(op->procs[n].nspace, nsptr, PMIX_MAX_NSLEN);
1394         op->procs[n].rank = pmix4x_convert_opalrank(ptr->name.vpid);
1395         ++n;
1396     }
1397     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1398 
1399     ret = PMIx_Connect_nb(op->procs, op->nprocs, NULL, 0, opcbfunc, op);
1400     if (PMIX_SUCCESS != ret) {
1401         OBJ_RELEASE(op);
1402     }
1403     return pmix4x_convert_rc(ret);
1404 }
1405 
1406 int pmix4x_disconnect(opal_list_t *procs)
1407 {
1408     size_t nprocs, n;
1409     opal_namelist_t *ptr;
1410     pmix_status_t ret=PMIX_SUCCESS;
1411     pmix_proc_t *p;
1412     char *nsptr;
1413 
1414     opal_output_verbose(1, opal_pmix_base_framework.framework_output,
1415                         "pmix4x:client disconnect");
1416 
1417     /* protect against bozo error */
1418     if (NULL == procs || 0 == (nprocs = opal_list_get_size(procs))) {
1419         return OPAL_ERR_BAD_PARAM;
1420     }
1421 
1422     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
1423     if (0 >= opal_pmix_base.initialized) {
1424         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1425         return OPAL_ERR_NOT_INITIALIZED;
1426     }
1427 
1428     /* convert the list of procs to an array
1429      * of pmix_proc_t */
1430     PMIX_PROC_CREATE(p, nprocs);
1431     n=0;
1432     OPAL_LIST_FOREACH(ptr, procs, opal_namelist_t) {
1433         if (NULL == (nsptr = pmix4x_convert_jobid(ptr->name.jobid))) {
1434             PMIX_PROC_FREE(p, nprocs);
1435             OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1436             return OPAL_ERR_NOT_FOUND;
1437         }
1438         (void)strncpy(p[n].nspace, nsptr, PMIX_MAX_NSLEN);
1439         p[n].rank = pmix4x_convert_opalrank(ptr->name.vpid);
1440         ++n;
1441     }
1442     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1443 
1444     ret = PMIx_Disconnect(p, nprocs, NULL, 0);
1445     PMIX_PROC_FREE(p, nprocs);
1446 
1447     return pmix4x_convert_rc(ret);
1448 }
1449 
1450 int pmix4x_disconnectnb(opal_list_t *procs,
1451                         opal_pmix_op_cbfunc_t cbfunc,
1452                         void *cbdata)
1453 {
1454     pmix4x_opcaddy_t *op;
1455     opal_namelist_t *ptr;
1456     pmix_status_t ret;
1457     char *nsptr;
1458     size_t n;
1459 
1460     opal_output_verbose(1, opal_pmix_base_framework.framework_output,
1461                         "pmix4x:client disconnect NB");
1462 
1463     /* protect against bozo error */
1464     if (NULL == procs || 0 == opal_list_get_size(procs)) {
1465         return OPAL_ERR_BAD_PARAM;
1466     }
1467 
1468     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
1469     if (0 >= opal_pmix_base.initialized) {
1470         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1471         return OPAL_ERR_NOT_INITIALIZED;
1472     }
1473 
1474     /* create the caddy */
1475     op = OBJ_NEW(pmix4x_opcaddy_t);
1476     op->opcbfunc = cbfunc;
1477     op->cbdata = cbdata;
1478     op->nprocs = opal_list_get_size(procs);
1479 
1480     /* convert the list of procs to an array
1481      * of pmix_proc_t */
1482     PMIX_PROC_CREATE(op->procs, op->nprocs);
1483     n=0;
1484     OPAL_LIST_FOREACH(ptr, procs, opal_namelist_t) {
1485         if (NULL == (nsptr = pmix4x_convert_jobid(ptr->name.jobid))) {
1486             OBJ_RELEASE(op);
1487             OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1488             return OPAL_ERR_NOT_FOUND;
1489         }
1490         (void)strncpy(op->procs[n].nspace, nsptr, PMIX_MAX_NSLEN);
1491         op->procs[n].rank = pmix4x_convert_opalrank(ptr->name.vpid);
1492         ++n;
1493     }
1494     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1495 
1496     ret = PMIx_Disconnect_nb(op->procs, op->nprocs, NULL, 0, opcbfunc, op);
1497     if (PMIX_SUCCESS != ret) {
1498         OBJ_RELEASE(op);
1499     }
1500     return pmix4x_convert_rc(ret);
1501 }
1502 
1503 int pmix4x_resolve_peers(const char *nodename,
1504                          opal_jobid_t jobid,
1505                          opal_list_t *procs)
1506 {
1507     pmix_status_t ret;
1508     char *nspace;
1509     pmix_proc_t *array=NULL;
1510     size_t nprocs, n;
1511     opal_namelist_t *nm;
1512     opal_pmix4x_jobid_trkr_t *job;
1513 
1514     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
1515     if (0 >= opal_pmix_base.initialized) {
1516         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1517         return OPAL_ERR_NOT_INITIALIZED;
1518     }
1519 
1520     if (OPAL_JOBID_WILDCARD != jobid) {
1521         if (NULL == (nspace = pmix4x_convert_jobid(jobid))) {
1522             OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1523             return OPAL_ERR_NOT_FOUND;
1524         }
1525     } else {
1526         nspace = NULL;
1527     }
1528     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1529 
1530     ret = PMIx_Resolve_peers(nodename, nspace, &array, &nprocs);
1531 
1532     if (NULL != array && 0 < nprocs) {
1533         OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
1534         for (n=0; n < nprocs; n++) {
1535             nm = OBJ_NEW(opal_namelist_t);
1536             opal_list_append(procs, &nm->super);
1537             if (mca_pmix_pmix4x_component.native_launch) {
1538                 /* if we were launched by the OMPI RTE, then
1539                  * the jobid is in a special format - so get it */
1540                 opal_convert_string_to_jobid(&nm->name.jobid, array[n].nspace);
1541             } else {
1542                 /* we were launched by someone else, so make the
1543                  * jobid just be the hash of the nspace */
1544                 OPAL_HASH_JOBID(array[n].nspace, nm->name.jobid);
1545             }
1546             /* if we don't already have it, add this to our jobid tracker */
1547             if (NULL == pmix4x_convert_jobid(nm->name.jobid)) {
1548                 job = OBJ_NEW(opal_pmix4x_jobid_trkr_t);
1549                 (void)strncpy(job->nspace, array[n].nspace, PMIX_MAX_NSLEN);
1550                 job->jobid = nm->name.jobid;
1551                 opal_list_append(&mca_pmix_pmix4x_component.jobids, &job->super);
1552             }
1553             nm->name.vpid = pmix4x_convert_rank(array[n].rank);
1554         }
1555         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1556     }
1557     PMIX_PROC_FREE(array, nprocs);
1558     return pmix4x_convert_rc(ret);
1559 }
1560 
1561 int pmix4x_resolve_nodes(opal_jobid_t jobid, char **nodelist)
1562 {
1563     pmix_status_t ret;
1564     char *nsptr;
1565 
1566     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
1567     if (0 >= opal_pmix_base.initialized) {
1568         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1569         return OPAL_ERR_NOT_INITIALIZED;
1570     }
1571 
1572     if (NULL == (nsptr = pmix4x_convert_jobid(jobid))) {
1573         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1574         return OPAL_ERR_NOT_FOUND;
1575     }
1576     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1577 
1578     ret = PMIx_Resolve_nodes(nsptr, nodelist);
1579 
1580     return pmix4x_convert_rc(ret);
1581 }
1582 
1583 static void relcbfunc(void *cbdata)
1584 {
1585     pmix4x_opcaddy_t *op = (pmix4x_opcaddy_t*)cbdata;
1586     OBJ_RELEASE(op);
1587 }
1588 
1589 static void infocbfunc(pmix_status_t status,
1590                        pmix_info_t *info, size_t ninfo,
1591                        void *cbdata,
1592                        pmix_release_cbfunc_t release_fn,
1593                        void *release_cbdata)
1594 {
1595     pmix4x_opcaddy_t *op = (pmix4x_opcaddy_t*)cbdata;
1596     int rc;
1597 
1598     if (NULL != release_fn) {
1599         release_fn(release_cbdata);
1600     }
1601     rc = pmix4x_convert_rc(status);
1602     if (NULL != op->qcbfunc) {
1603         op->qcbfunc(rc, NULL, op->cbdata, relcbfunc, op);
1604     } else {
1605         OBJ_RELEASE(op);
1606     }
1607 }
1608 
1609 int pmix4x_allocate(opal_pmix_alloc_directive_t directive,
1610                     opal_list_t *info,
1611                     opal_pmix_info_cbfunc_t cbfunc, void *cbdata)
1612 {
1613     return OPAL_ERR_NOT_SUPPORTED;
1614 }
1615 
1616 int pmix4x_job_control(opal_list_t *targets,
1617                        opal_list_t *directives,
1618                        opal_pmix_info_cbfunc_t cbfunc, void *cbdata)
1619 {
1620     pmix4x_opcaddy_t *op;
1621     size_t n;
1622     opal_namelist_t *ptr;
1623     opal_value_t *iptr;
1624     pmix_status_t rc;
1625     char *nsptr;
1626 
1627     OPAL_PMIX_ACQUIRE_THREAD(&opal_pmix_base.lock);
1628     if (0 >= opal_pmix_base.initialized) {
1629         OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1630         return OPAL_ERR_NOT_INITIALIZED;
1631     }
1632 
1633     /* create the caddy */
1634     op = OBJ_NEW(pmix4x_opcaddy_t);
1635     op->qcbfunc = cbfunc;
1636     op->cbdata = cbdata;
1637     if (NULL != targets) {
1638         op->nprocs = opal_list_get_size(targets);
1639 
1640         /* convert the list of procs to an array
1641          * of pmix_proc_t */
1642         PMIX_PROC_CREATE(op->procs, op->nprocs);
1643         n=0;
1644         OPAL_LIST_FOREACH(ptr, targets, opal_namelist_t) {
1645             if (NULL == (nsptr = pmix4x_convert_jobid(ptr->name.jobid))) {
1646                 OBJ_RELEASE(op);
1647                 OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1648                 return OPAL_ERR_NOT_FOUND;
1649             }
1650             (void)strncpy(op->procs[n].nspace, nsptr, PMIX_MAX_NSLEN);
1651             op->procs[n].rank = pmix4x_convert_opalrank(ptr->name.vpid);
1652             ++n;
1653         }
1654     }
1655     OPAL_PMIX_RELEASE_THREAD(&opal_pmix_base.lock);
1656 
1657     if (NULL != directives && 0 < (op->ninfo = opal_list_get_size(directives))) {
1658         PMIX_INFO_CREATE(op->info, op->ninfo);
1659         n=0;
1660         OPAL_LIST_FOREACH(iptr, directives, opal_value_t) {
1661             (void)strncpy(op->info[n].key, iptr->key, PMIX_MAX_KEYLEN);
1662             pmix4x_value_load(&op->info[n].value, iptr);
1663             ++n;
1664         }
1665     }
1666 
1667     rc = PMIx_Job_control_nb(op->procs,op->nprocs, op->info, op->ninfo, infocbfunc, op);
1668     if (PMIX_SUCCESS != rc) {
1669         OBJ_RELEASE(op);
1670     }
1671     return pmix4x_convert_rc(rc);
1672 }

/* [<][>][^][v][top][bottom][index][help] */