void hmesg_scrub(hmesg_t *mesg) { switch (mesg->type) { case HMESG_SESSION: if (mesg->status == HMESG_STATUS_REQ) hsession_fini(&mesg->data.session); break; case HMESG_JOIN: if (mesg->status == HMESG_STATUS_REQ || mesg->status == HMESG_STATUS_OK) { hsignature_fini(&mesg->data.join); } break; case HMESG_FETCH: if (mesg->status == HMESG_STATUS_OK) { hpoint_fini(&mesg->data.fetch.cand); hpoint_fini(&mesg->data.fetch.best); } break; case HMESG_REPORT: if (mesg->status == HMESG_STATUS_REQ) hpoint_fini(&mesg->data.fetch.cand); break; default: break; /* All other cases have no heap memory to release. */ } }
/* * Signature-related function definitions. */ int hsignature_copy(hsignature_t *dst, const hsignature_t *src) { int i; hsignature_fini(dst); dst->range = (hrange_t *) malloc(sizeof(hrange_t) * src->range_len); if (!dst->range) return -1; dst->range_len = src->range_len; dst->range_cap = src->range_len; dst->name = stralloc(src->name); if (!dst->name) return -1; for (i = 0; i < dst->range_len; ++i) { dst->range[i] = HRANGE_INITIALIZER; if (hrange_copy(&dst->range[i], &src->range[i]) != 0) return -1; } return 0; }
int harmony_join(hdesc_t *hdesc, const char *host, int port, const char *name) { int i, perf_len; int apply_argv = (hdesc->state < HARMONY_STATE_CONNECTED); char *cfgval; /* Verify that we have *at least* one variable bound, and that * this descriptor isn't already associated with a tuning * session. */ if (hdesc->ptr_len == 0) { hdesc->errstr = "No variables bound to Harmony session"; errno = EINVAL; return -1; } if (hdesc->state >= HARMONY_STATE_READY) { hdesc->errstr = "Descriptor already joined with an existing session"; errno = EINVAL; return -1; } if (hdesc->state == HARMONY_STATE_INIT) { hdesc->socket = tcp_connect(host, port); if (hdesc->socket < 0) { hdesc->errstr = "Error establishing TCP connection with server"; return -1; } if (hdesc->id == NULL) hdesc->id = default_id(hdesc->socket); hdesc->state = HARMONY_STATE_CONNECTED; hdesc->sess.sig.name = stralloc(name); if (!hdesc->sess.sig.name) { hdesc->errstr = "Error allocating memory for signature name"; return -1; } } /* Prepare a Harmony message. */ hmesg_scrub(&hdesc->mesg); hdesc->mesg.data.join = HSIGNATURE_INITIALIZER; if (hsignature_copy(&hdesc->mesg.data.join, &hdesc->sess.sig) < 0) { hdesc->errstr = "Internal error copying signature data"; return -1; } /* send the client registration message */ if (send_request(hdesc, HMESG_JOIN) != 0) return -1; if (hdesc->mesg.status != HMESG_STATUS_OK) { hdesc->errstr = "Invalid message received"; errno = EINVAL; return -1; } hsignature_fini(&hdesc->sess.sig); if (hsignature_copy(&hdesc->sess.sig, &hdesc->mesg.data.join) < 0) { hdesc->errstr = "Error copying received signature structure"; return -1; } /* Apply argv configuration directives now, if necessary. */ if (apply_argv) { for (i = 0; i < hdesc->cmd_len; ++i) { char *key, *val, *cpy; cpy = stralloc(hdesc->cmd[i]); if (hcfg_parse(cpy, &key, &val)) { /* This should never fail, but just in case. */ hdesc->errstr = "Error parsing argv config directive."; return -1; } if (hcfg_set(hdesc->sess.cfg, key, val)) { hdesc->errstr = "Error applying argv config directive."; return -1; } free(cpy); } } cfgval = harmony_getcfg(hdesc, CFGKEY_PERF_COUNT); if (cfgval) { perf_len = atoi(cfgval); if (perf_len < 1) { hdesc->errstr = "Invalid value for " CFGKEY_PERF_COUNT; return -1; } free(cfgval); } else { perf_len = DEFAULT_PERF_COUNT; } hdesc->perf = hperf_alloc(perf_len); if (!hdesc->perf) { hdesc->errstr = "Error allocating performance array."; return -1; } hdesc->state = HARMONY_STATE_READY; return 0; }
int constraint_fini(void) { hsignature_fini(&local_sig); return 0; }