Exemple #1
0
mc_msg_t *mc_msg_new_with_key_and_value_full(const char *key,
                                             size_t nkey,
                                             const char *value,
                                             size_t nvalue) {
  // add + 2 for '\0' for both key & value
  mc_msg_t *msg = mc_msg_new(nkey + nvalue + 2);
  char *ptr = (char*)msg;

  ptr += sizeof(mc_msg_t);

  // copy the key and set the pointers
  memcpy(ptr, key, nkey);
  ptr[nkey] = '\0';

  msg->key.str = ptr;
  msg->key.len = nkey;

  // move past the key
  ptr += nkey + 1;

  // copy the value and set the pointers
  memcpy(ptr, value, nvalue);
  ptr[nvalue] = '\0';

  msg->value.str = ptr;
  msg->value.len = nvalue;
  return msg;
}
Exemple #2
0
static Object mcr_int(ObjectData* this_, int64_t val) {
  mcr::mcrouter_msg_t msg;
  msg.req = mc_msg_new(0);
  msg.req->number = val;
  msg.req->op = op;
  return Native::data<MCRouter>(this_)->issue(msg);
}
Exemple #3
0
mc_msg_t* mc_msg_dup(const mc_msg_t *msg) {
  FBI_ASSERT(msg);
  FBI_ASSERT(msg->_refcount > 0 || msg->_refcount == MSG_NOT_REFCOUNTED);
  mc_msg_t *msg_copy = mc_msg_new(msg->_extra_size);
  if (msg_copy == NULL) {
    return NULL;
  }
  _msgcpy(msg_copy, msg);
  return msg_copy;
}
Exemple #4
0
mc_msg_t *mc_msg_new_with_key_full(const char *key, size_t nkey) {
  mc_msg_t *msg = mc_msg_new(nkey + 1);  // + 1 for '\0'.
  char *ptr = (char*)msg;
  ptr += sizeof(mc_msg_t);
  memcpy(ptr, key, nkey);
  msg->key.str = ptr;
  msg->key.str[nkey] = '\0';
  msg->key.len = nkey;
  return msg;
}
Exemple #5
0
/* reallocate a mc_msg_t
 * for deep/shallow copying semantics, see _msgcpy
 * For more on why we do it this way, see Task #689247 and D314525
 */
mc_msg_t* mc_msg_realloc(mc_msg_t *msg, size_t new_extra_size) {
  if (msg == NULL) {
    // Same behavior as realloc, malloc on NULL
    return mc_msg_new(new_extra_size);
  }

  if (new_extra_size <= msg->_extra_size) {
    return msg;
  }

  mc_msg_t *msg_copy = mc_msg_new(new_extra_size);
  if (msg_copy == NULL) {
    // Same behavior as realloc, don't clean up msg
    return NULL;
  }

  _msgcpy(msg_copy, msg);
  msg_copy->_extra_size = new_extra_size;

  // "free" it
  mc_msg_decref(msg);

  return msg_copy;
}
Exemple #6
0
mc_msg_t* mc_msg_dup_append_key_full(const mc_msg_t *msg,
                                     const char* key_append,
                                     size_t nkey_append) {
  FBI_ASSERT(msg);
  FBI_ASSERT(msg->_refcount > 0 || msg->_refcount == MSG_NOT_REFCOUNTED);
  FBI_ASSERT(key_append);

  // Stats are not supported.
  if (msg->stats) {
    return NULL;
  }

  if (!nkey_append) {
    return mc_msg_dup(msg);
  }

  size_t new_extra_size = msg->_extra_size + nkey_append;
  if (!_in_msg(msg, msg->key.str, msg->key.len)) {
    new_extra_size += msg->key.len + 1; // +1 for null terminator
  }
  mc_msg_t* const msg_copy = mc_msg_new(new_extra_size);
  if (msg_copy == NULL) {
    return NULL;
  }
  mc_msg_shallow_copy(msg_copy, msg);

  // The new message's key is always embedded.
  msg_copy->key.len = msg->key.len + nkey_append;
  msg_copy->key.str = (void*) msg_copy + sizeof(*msg_copy);
  memcpy(msg_copy->key.str, msg->key.str, msg->key.len);
  memcpy(msg_copy->key.str + msg->key.len, key_append, nkey_append);
  msg_copy->key.str[msg_copy->key.len] = 0;

  if (_in_msg(msg, msg->value.str, msg->value.len)) {
    // The value starts after the key, including the null terminator.
    msg_copy->value.str = msg_copy->key.str + msg_copy->key.len + 1;
    memcpy(msg_copy->value.str, msg->value.str, msg_copy->value.len);
  }
  return msg_copy;
}
Exemple #7
0
static Object mcr_void(ObjectData* this_) {
  mcr::mcrouter_msg_t msg;
  msg.req = mc_msg_new(0);
  msg.req->op = op;
  return Native::data<MCRouter>(this_)->issue(msg);
}
Exemple #8
0
static mc_msg_t *_msg_create(mc_msg_t *base, entry_list_t *elist,
                             _parse_info_t* parse_info) {
  size_t msg_size = 0;
  mc_msg_t *msg = NULL;
  size_t stats_offset = 0;
  size_t body_offset = 0;
  void *body = NULL;

  // Make sure we're not screwing up alignment here
  FBI_ASSERT(sizeof(mc_msg_t) % sizeof(void *) == 0);

  // Construct a message of the following format
  //    __________________
  //   |                   |
  //   |      mc_msg_t     | <- base message
  //   |___________________|
  //   |                   |
  //   |  nstring_t array  | <- stats array (optional)
  //   |___________________|
  //   |                   |
  //   |     key string    | <- key (optional)
  //   |___________________|
  //   |                   |
  //   |    value string   | <- value (optional)
  //   |___________________|
  //   |                   |
  //   |      stats[0]     | <- stats[0] (and so on...)
  //   |___________________|
  //

  msg_size = sizeof(mc_msg_t);

  if (parse_info->stats_count > 0) {
    stats_offset = msg_size;
    msg_size += (sizeof(nstring_t) * parse_info->stats_count);
  }

  body_offset = msg_size;
  msg_size += elist->nbody;

  FBI_ASSERT(msg_size >= sizeof(*base));

  msg = mc_msg_new(msg_size - sizeof(mc_msg_t));
  if (msg == NULL) {
    goto error;
  }

  // Copy base
  mc_msg_copy(msg, base);

  // Copy body
  memcpy((void*)msg + body_offset, elist->body, elist->nbody);
  body = (void*)msg + body_offset;

  if (parse_info->stats_count > 0) {
    FBI_ASSERT(stats_offset > 0);
    nstring_t *stats = (nstring_t*) ((void*)msg + stats_offset);
    uint64_t i;
    int sidx;
    for (i = 0, sidx = 0;
         i < elist->nentries && sidx < parse_info->stats_count; i++) {
      um_elist_entry_t *entry = &elist->entries[i];
      if (ntoh16(entry->tag) == msg_stats) {
        _set_str(&stats[sidx], body, entry);
        sidx++;
      }
    }
    msg->stats = stats;
  }

  _fill_msg_strs(msg, elist, body, parse_info);

  return msg;

error:
  if (msg != NULL) {
    mc_msg_decref(msg);
    msg = NULL;
  }
  return NULL;
}