Esempio n. 1
0
File: ipcc.c Progetto: krig/libqb
ssize_t
qb_ipcc_sendv_recv(qb_ipcc_connection_t * c,
		   const struct iovec * iov, uint32_t iov_len,
		   void *res_msg, size_t res_len, int32_t ms_timeout)
{
	ssize_t res = 0;
	int32_t timeout_now;
	int32_t timeout_rem = ms_timeout;

	if (c == NULL) {
		return -EINVAL;
	}

	if (c->funcs.fc_get) {
		res = c->funcs.fc_get(&c->request);
		if (res < 0) {
			return res;
		} else if (res > 0 && res <= c->fc_enable_max) {
			return -EAGAIN;
		} else {
			/*
			 * we can transmit
			 */
		}
	}

	res = qb_ipcc_sendv(c, iov, iov_len);
	if (res < 0) {
		return res;
	}

	do {
		if (timeout_rem > QB_IPC_MAX_WAIT_MS || ms_timeout == -1) {
			timeout_now = QB_IPC_MAX_WAIT_MS;
		} else {
			timeout_now = timeout_rem;
		}

		res = qb_ipcc_recv(c, res_msg, res_len, timeout_now);
		if (res == -ETIMEDOUT) {
			if (ms_timeout < 0) {
				res = -EAGAIN;
			} else {
				timeout_rem -= timeout_now;
				if (timeout_rem > 0) {
					res = -EAGAIN;
				}
			}
		} else	if (res < 0 && res != -EAGAIN) {
			errno = -res;
			qb_util_perror(LOG_DEBUG,
				       "qb_ipcc_recv %d timeout:(%d/%d)",
				       res, timeout_now, timeout_rem);
		}
	} while (res == -EAGAIN && c->is_connected);

	return res;
}
Esempio n. 2
0
static int
internal_ipc_send_request(crm_ipc_t * client, const void *iov, int ms_timeout)
{
    int rc = 0;
    time_t timeout = time(NULL) + 1 + (ms_timeout / 1000);

    do {
        rc = qb_ipcc_sendv(client->ipc, iov, 2);
    } while (rc == -EAGAIN && time(NULL) < timeout && crm_ipc_connected(client));

    return rc;
}
Esempio n. 3
0
static void
_benchmark(qb_ipcc_connection_t *conn, int write_size)
{
	struct timeval tv1, tv2, tv_elapsed;
	struct iovec iov[2];
	unsigned int res;
	struct qb_ipc_request_header hdr;
	int write_count = 0;

	alarm_notice = 0;
	hdr.size = write_size;
	hdr.id = QB_IPC_MSG_USER_START + 1;

	iov[0].iov_base = &hdr;
	iov[0].iov_len = sizeof(struct qb_ipc_request_header);

	iov[1].iov_base = data;
	iov[1].iov_len = write_size - sizeof(struct qb_ipc_request_header);

	alarm (10);

	gettimeofday (&tv1, NULL);
	do {
		res = qb_ipcc_sendv(conn, iov, 2);
		if (res == write_size) {
			write_count++;
		}
	} while (alarm_notice == 0 && (res == write_size || res == -EAGAIN));
	if (res < 0) {
		perror("qb_ipcc_sendv");
	}
	gettimeofday (&tv2, NULL);
	timersub (&tv2, &tv1, &tv_elapsed);

	printf ("%5d messages sent ", write_count);
	printf ("%5d bytes per write ", write_size);
	printf ("%7.3f Seconds runtime ",
		(tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0)));
	printf ("%9.3f TP/s ",
		((float)write_count) /  (tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0)));
	printf ("%7.3f MB/s.\n",
		((float)write_count) * ((float)write_size) /  ((tv_elapsed.tv_sec + (tv_elapsed.tv_usec / 1000000.0)) * 1000000.0));
}
Esempio n. 4
0
static void
_benchmark(qb_ipcc_connection_t *conn, int write_size)
{
	struct iovec iov[2];
	ssize_t res;
	struct qb_ipc_request_header hdr;
	int write_count = 0;
	float secs;

	alarm_notice = 0;
	hdr.size = write_size;
	hdr.id = QB_IPC_MSG_USER_START + 1;

	iov[0].iov_base = &hdr;
	iov[0].iov_len = sizeof(struct qb_ipc_request_header);

	iov[1].iov_base = data;
	iov[1].iov_len = write_size - sizeof(struct qb_ipc_request_header);

	alarm (10);

	qb_util_stopwatch_start(sw);
	do {
		res = qb_ipcc_sendv(conn, iov, 2);
		if (res == write_size) {
			write_count++;
		}
	} while (alarm_notice == 0 && (res == write_size || res == -EAGAIN));
	if (res < 0) {
		perror("qb_ipcc_sendv");
	}
	qb_util_stopwatch_stop(sw);
	secs = qb_util_stopwatch_sec_elapsed_get(sw);

	printf ("%5d messages sent ", write_count);
	printf ("%5d bytes per write ", write_size);
	printf ("%7.3f Seconds runtime ", secs);
	printf ("%9.3f TP/s ",
		((float)write_count) / secs);
	printf ("%7.3f MB/s.\n",
		((float)write_count) * ((float)write_size) / secs);
}
Esempio n. 5
0
  json IPCClientPrivate::qbIPCSendRecvJSON(const json& jval)
  {
    if (!isConnected()) {
      throw IPCException(IPCException::ConnectionError, "Not connected");
    }

    const std::string json_string = jval.dump();

    struct qb_ipc_request_header hdr;
    hdr.id = 0;
    hdr.size = sizeof hdr + json_string.size();

    struct iovec iov[2];
    iov[0].iov_base = &hdr;
    iov[0].iov_len = sizeof hdr;
    iov[1].iov_base = (void *)json_string.c_str();
    iov[1].iov_len = json_string.size();

    const uint64_t id = jval["_i"];

    /* Lock the return value slot map */
    std::unique_lock<std::mutex> rv_map_lock(_rv_map_mutex);

    /*
     * Create the promise and future objects.
     * The promise will be fullfiled by the message
     * processing handlers after they process
     * a reply from the server.
     */
    auto& promise = _rv_map[id];
    auto future = promise.get_future();

    qb_ipcc_sendv(_qb_conn, iov, 2);

    /* 
     * Unlock the return value map so that the message
     * processing handler aren't blocked.
     */
    rv_map_lock.unlock();

    /* Wait for some time for the reply to be received */
    const std::chrono::milliseconds timeout_ms(5*1000);
    const bool timed_out = \
      future.wait_for(timeout_ms) == std::future_status::timeout;

    json retval;

    if (!timed_out) {
      retval = future.get();
    }

    /* Remove the slot from the return value slot map */
    rv_map_lock.lock();
    _rv_map.erase(id);
    rv_map_lock.unlock();

    if (timed_out) {
      throw IPCException(IPCException::TransientError, "Timed out while waiting for IPC reply");
    }
    else {
      /*
       * We might have caused an exception. Check whether
       * that's the case and if true, throw it here.
       */
      if (isExceptionJSON(retval)) {
	throw IPCException(IPCException::ProtocolError, "The remote end sent an exception");
      }
      else {
	return std::move(retval);
      }
    }
    return json();
  }