#include #include #include #include #include #include #include #include static void hide_unused_params(int x, ...) { va_list ap; va_start(ap, x); va_end(ap); } typedef struct { pthread_mutex_t mutex; pthread_cond_t cond; volatile bool active; pmix_status_t status; } mylock_t; typedef struct { mylock_t lock; pmix_info_t *info; size_t ninfo; } myxfer_t; #define DEBUG_CONSTRUCT_LOCK(l) \ do { \ pthread_mutex_init(&(l)->mutex, NULL); \ pthread_cond_init(&(l)->cond, NULL); \ (l)->active = true; \ (l)->status = PMIX_SUCCESS; \ } while (0) #define DEBUG_DESTRUCT_LOCK(l) \ do { \ pthread_mutex_destroy(&(l)->mutex); \ pthread_cond_destroy(&(l)->cond); \ } while (0) #define DEBUG_WAIT_THREAD(lck) \ do { \ pthread_mutex_lock(&(lck)->mutex); \ while ((lck)->active) { \ pthread_cond_wait(&(lck)->cond, &(lck)->mutex); \ } \ pthread_mutex_unlock(&(lck)->mutex); \ } while (0) #define DEBUG_WAKEUP_THREAD(lck) \ do { \ pthread_mutex_lock(&(lck)->mutex); \ (lck)->active = false; \ pthread_cond_broadcast(&(lck)->cond); \ pthread_mutex_unlock(&(lck)->mutex); \ } while (0) static void setup_cbfunc(pmix_status_t status, pmix_info_t info[], size_t ninfo, void *provided_cbdata, pmix_op_cbfunc_t cbfunc, void *cbdata) { myxfer_t *x = (myxfer_t *) provided_cbdata; size_t n; /* transfer it to the caddy for return to the main thread */ x->lock.status = status; if (0 < ninfo) { PMIX_INFO_CREATE(x->info, ninfo); x->ninfo = ninfo; for (n = 0; n < ninfo; n++) { PMIX_INFO_XFER(&x->info[n], &info[n]); } } /* let the library release the data and cleanup from * the operation */ if (NULL != cbfunc) { cbfunc(PMIX_SUCCESS, cbdata); } DEBUG_WAKEUP_THREAD(&x->lock); } int main(int argc, char **argv) { pmix_status_t rc=0; myxfer_t x; pmix_proc_t myproc; pmix_info_t *info; size_t n, ninfo; char *myvni = NULL; hide_unused_params(rc, argc, argv); /* setup the PMIx tool library - don't need to connect * to a PMIx server */ ninfo = 2; PMIX_INFO_CREATE(info, ninfo); n = 0; PMIX_INFO_LOAD(&info[n], PMIX_TOOL_DO_NOT_CONNECT, NULL, PMIX_BOOL); ++n; PMIX_INFO_LOAD(&info[n], PMIX_LAUNCHER, NULL, PMIX_BOOL); if (PMIX_SUCCESS != (rc = PMIx_tool_init(&myproc, info, ninfo))) { fprintf(stderr, "Init failed with error %s\n", PMIx_Error_string(rc)); return rc; } PMIX_INFO_FREE(info, ninfo); /* ask for a security credential */ DEBUG_CONSTRUCT_LOCK(&x.lock); x.info = NULL; x.ninfo = 0; ninfo = 1; PMIX_INFO_CREATE(info, ninfo); n = 0; PMIX_INFO_LOAD(&info[n], PMIX_ALLOC_FABRIC_SEC_KEY, NULL, PMIX_BOOL); rc = PMIx_server_setup_application(myproc.nspace, info, ninfo, setup_cbfunc, &x); if (PMIX_SUCCESS != rc) { /* the thread won't be called back */ PMIX_INFO_FREE(info, ninfo); goto done; } DEBUG_WAIT_THREAD(&x.lock); PMIX_INFO_FREE(info, ninfo); if (PMIX_SUCCESS != x.lock.status) { /* couldn't allocate it */ rc = x.lock.status; goto done; } /* find the VNI in the returned data - shouldn't be anything else */ for (n = 0; n < x.ninfo; n++) { if (PMIX_CHECK_KEY(&x.info[n], PMIX_CREDENTIAL)) { myvni = strdup(x.info[n].value.data.string); break; } } fprintf(stderr, "VNI: %s\n", (NULL == myvni) ? "NULL" : myvni); done: rc = PMIx_tool_finalize(); return rc; }