示例#1
0
文件: ucall.c 项目: jvesely/helenos
/** SEND user call */
tcp_error_t tcp_uc_send(tcp_conn_t *conn, void *data, size_t size,
    xflags_t flags)
{
	size_t buf_free;
	size_t xfer_size;

	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_uc_send()", conn->name);

	tcp_conn_lock(conn);

	if (conn->cstate == st_closed) {
		tcp_conn_unlock(conn);
		return TCP_ENOTEXIST;
	}

	if (conn->cstate == st_listen) {
		/* Change connection to active */
		tcp_conn_sync(conn);
	}


	if (conn->snd_buf_fin) {
		tcp_conn_unlock(conn);
		return TCP_ECLOSING;
	}

	while (size > 0) {
		buf_free = conn->snd_buf_size - conn->snd_buf_used;
		while (buf_free == 0 && !conn->reset) {
			log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: buf_free == 0, waiting.",
			    conn->name);
			fibril_condvar_wait(&conn->snd_buf_cv, &conn->lock);
			buf_free = conn->snd_buf_size - conn->snd_buf_used;
		}

		if (conn->reset) {
			tcp_conn_unlock(conn);
			return TCP_ERESET;
		}

		xfer_size = min(size, buf_free);

		/* Copy data to buffer */
		memcpy(conn->snd_buf + conn->snd_buf_used, data, xfer_size);
		data += xfer_size;
		conn->snd_buf_used += xfer_size;
		size -= xfer_size;

		tcp_tqueue_new_data(conn);
	}

	tcp_tqueue_new_data(conn);
	tcp_conn_unlock(conn);

	return TCP_EOK;
}
示例#2
0
文件: ucall.c 项目: jvesely/helenos
/** CLOSE user call */
tcp_error_t tcp_uc_close(tcp_conn_t *conn)
{
	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_uc_close(%p)", conn->name,
	    conn);

	tcp_conn_lock(conn);

	if (conn->cstate == st_closed) {
		log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_close - ENOTEXIST");
		tcp_conn_unlock(conn);
		return TCP_ENOTEXIST;
	}

	if (conn->cstate == st_listen || conn->cstate == st_syn_sent) {
		log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_close - listen/syn_sent");
		tcp_conn_reset(conn);
		tcp_conn_unlock(conn);
		return TCP_EOK;
	}

	if (conn->snd_buf_fin) {
		log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_close - ECLOSING");
		tcp_conn_unlock(conn);
		return TCP_ECLOSING;
	}

	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_uc_close - set snd_buf_fin");
	conn->snd_buf_fin = true;
	tcp_tqueue_new_data(conn);

	tcp_conn_unlock(conn);
	return TCP_EOK;
}
示例#3
0
/** CLOSE user call */
tcp_error_t tcp_uc_close(tcp_conn_t *conn)
{
	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_uc_close()", conn->name);

	fibril_mutex_lock(&conn->lock);

	if (conn->cstate == st_closed) {
		fibril_mutex_unlock(&conn->lock);
		return TCP_ENOTEXIST;
	}

	if (conn->snd_buf_fin) {
		fibril_mutex_unlock(&conn->lock);
		return TCP_ECLOSING;
	}

	conn->snd_buf_fin = true;
	tcp_tqueue_new_data(conn);

	fibril_mutex_unlock(&conn->lock);
	return TCP_EOK;
}