diff --git a/orte/mca/gpr/base/pack_api_cmd/gpr_base_pack_subscribe.c b/orte/mca/gpr/base/pack_api_cmd/gpr_base_pack_subscribe.c index 05ccd4d169..b3304b1344 100644 --- a/orte/mca/gpr/base/pack_api_cmd/gpr_base_pack_subscribe.c +++ b/orte/mca/gpr/base/pack_api_cmd/gpr_base_pack_subscribe.c @@ -40,6 +40,7 @@ int orte_gpr_base_pack_subscribe(orte_buffer_t *cmd, { orte_gpr_cmd_flag_t command; int rc; + size_t zero=0; command = ORTE_GPR_SUBSCRIBE_CMD; @@ -48,14 +49,28 @@ int orte_gpr_base_pack_subscribe(orte_buffer_t *cmd, return rc; } + /* there MUST be some subscriptions, so don't have to check that here - it was checked on the API + * itself. + */ if (ORTE_SUCCESS != (rc = orte_dps.pack(cmd, subscriptions, num_subs, ORTE_GPR_SUBSCRIPTION))) { ORTE_ERROR_LOG(rc); return rc; } - if (ORTE_SUCCESS != (rc = orte_dps.pack(cmd, trigs, num_trigs, ORTE_GPR_TRIGGER))) { - ORTE_ERROR_LOG(rc); - return rc; + /* the API DOES allow there to be no triggers - if that happens, then trigs will be NULL and num_trigs + * should be set to zero. we can't send that to the DPS though as it is an error condition over there, + * so check for it here and record a "zero" if nothing is there + */ + if (NULL != trigs && 0 < num_trigs) { + if (ORTE_SUCCESS != (rc = orte_dps.pack(cmd, trigs, num_trigs, ORTE_GPR_TRIGGER))) { + ORTE_ERROR_LOG(rc); + return rc; + } + } else { + if (ORTE_SUCCESS != (rc = orte_dps.pack(cmd, &zero, 1, ORTE_SIZE))) { + ORTE_ERROR_LOG(rc); + return rc; + } } return ORTE_SUCCESS; diff --git a/orte/mca/gpr/replica/communications/gpr_replica_subscribe_cm.c b/orte/mca/gpr/replica/communications/gpr_replica_subscribe_cm.c index 7fd74e699f..13defee553 100644 --- a/orte/mca/gpr/replica/communications/gpr_replica_subscribe_cm.c +++ b/orte/mca/gpr/replica/communications/gpr_replica_subscribe_cm.c @@ -74,7 +74,28 @@ int orte_gpr_replica_recv_subscribe_cmd(orte_process_name_t* sender, goto RETURN_ERROR; } - if (0 < n) { + /* if the original command did not provide any triggers, then we put a size_t value in the buffer of "zero" + * to avoid causing buffer problems. thus, we need to check to see if the type is size_t vs trigger vs + * something else. if it is trigger, then we need the number to be greater than 0, which should always + * be true (we check it just to be safe). if it is size_t, then the value should be zero - anything else + * generates an error. + */ + if (ORTE_SIZE == type) { + /* this case means that there were no triggers, so we need to clear the value from the buffer + * and continue on + */ + n=1; + if (ORTE_SUCCESS != orte_dps.unpack(input_buffer, &num_trigs, &n, ORTE_SIZE)) { + ORTE_ERROR_LOG(rc); + goto RETURN_ERROR; + } + /* if the returned number of triggers isn't zero, then we have a problem */ + if (0 != num_trigs) { + ORTE_ERROR_LOG(ORTE_ERR_COMM_FAILURE); + rc = ORTE_ERR_COMM_FAILURE; + goto RETURN_ERROR; + } + } else if (ORTE_GPR_TRIGGER == type && 0 < n) { /* create the space for the triggers */ trigs = (orte_gpr_trigger_t**)malloc(n * sizeof(orte_gpr_trigger_t*)); if (NULL == trigs) { @@ -87,8 +108,15 @@ int orte_gpr_replica_recv_subscribe_cmd(orte_process_name_t* sender, ORTE_ERROR_LOG(rc); goto RETURN_ERROR; } + num_trigs = n; + } else { + /* we must have an error condition - it either wasn't the right type, or we had the type okay + * but don't have a good number of elements. report the error and move on + */ + ORTE_ERROR_LOG(ORTE_ERR_COMM_FAILURE); + rc = ORTE_ERR_COMM_FAILURE; + goto RETURN_ERROR; } - num_trigs = n; /* register subscriptions */