Exemple #1
0
int dnet_trans_send_fail(struct dnet_session *s, struct dnet_addr *addr, struct dnet_trans_control *ctl, int err, int destroy)
{
	struct dnet_cmd cmd;
	memset(&cmd, 0, sizeof(cmd));
	dnet_trans_control_fill_cmd(s, ctl, &cmd);

	cmd.status = err;
	cmd.size = 0;

	if (ctl->complete) {
		cmd.flags &= ~DNET_FLAGS_REPLY;

		ctl->complete(addr, &cmd, ctl->priv);

		if (destroy) {
			cmd.flags |= DNET_FLAGS_DESTROY;
			ctl->complete(addr, &cmd, ctl->priv);
		}
	}

	return 0;
}
Exemple #2
0
/*
 * Allocates and sends transaction into given @st network state/connection.
 * Uses @s session only to get wait timeout for transaction, if it is NULL, global node timeout (@dnet_node::wait_ts) is used.
 *
 * If something fails, completion handler from @ctl will be invoked with (NULL, NULL, @ctl->priv) arguments
 */
int dnet_trans_alloc_send_state(struct dnet_session *s, struct dnet_net_state *st, struct dnet_trans_control *ctl)
{
	struct dnet_io_req req;
	struct dnet_node *n = st->n;
	struct dnet_cmd *cmd;
	struct dnet_trans *t;
	int err;

	t = dnet_trans_alloc(n, sizeof(struct dnet_cmd) + ctl->size);
	if (!t) {
		err = dnet_trans_send_fail(s, dnet_state_addr(st), ctl, -ENOMEM, 1);
		goto err_out_exit;
	}

	t->complete = ctl->complete;
	t->priv = ctl->priv;
	if (s) {
		t->wait_ts = *dnet_session_get_timeout(s);
	} else {
		t->wait_ts = n->wait_ts;
	}

	cmd = (struct dnet_cmd *)(t + 1);

	dnet_trans_control_fill_cmd(s, ctl, cmd);
	t->command = cmd->cmd;
	cmd->trans = t->rcv_trans = t->trans = atomic_inc(&n->trans);

	memcpy(&t->cmd, cmd, sizeof(struct dnet_cmd));

	if (ctl->size && ctl->data)
		memcpy(cmd + 1, ctl->data, ctl->size);

	dnet_convert_cmd(cmd);

	t->st = dnet_state_get(st);

	memset(&req, 0, sizeof(req));
	req.st = st;
	req.header = cmd;
	req.hsize = sizeof(struct dnet_cmd) + ctl->size;
	req.fd = -1;

	dnet_log(n, DNET_LOG_INFO, "%s: %s: created %s",
			dnet_dump_id(&cmd->id),
			dnet_cmd_string(cmd->cmd),
			dnet_print_trans(t)
		);

	err = dnet_trans_send(t, &req);
	if (err)
		goto err_out_put;

	return 0;

err_out_put:
	dnet_trans_send_fail(s, dnet_state_addr(st), ctl, err, 0);
	dnet_trans_put(t);
err_out_exit:
	return 0;
}