mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-21 22:47:50 +00:00
terminal session: return number of bytes written
To better support non-blocking terminal components, let the 'Terminal::Session::write()' function return the number of bytes actually written. Fixes #2240
This commit is contained in:
parent
9f7a4feab4
commit
dbb641d44a
@ -277,14 +277,15 @@ class Terminal::Session_component : public Rpc_object<Session, Session_component
|
||||
return num_bytes;
|
||||
}
|
||||
|
||||
void _write(size_t num_bytes)
|
||||
size_t _write(size_t num_bytes)
|
||||
{
|
||||
char *dst = _io_buffer.local_addr<char>();
|
||||
while (num_bytes) {
|
||||
size_t size = _driver.write(dst, num_bytes);
|
||||
num_bytes -= size;
|
||||
dst += size;
|
||||
size_t written_bytes;
|
||||
for (written_bytes = 0; written_bytes < num_bytes; ) {
|
||||
written_bytes += _driver.write(dst + written_bytes,
|
||||
num_bytes - written_bytes);
|
||||
}
|
||||
return written_bytes;
|
||||
}
|
||||
|
||||
Dataspace_capability _dataspace() { return _io_buffer.cap(); }
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013 Genode Labs GmbH
|
||||
* Copyright (C) 2013-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -183,14 +183,22 @@ namespace Terminal {
|
||||
return num_bytes;
|
||||
}
|
||||
|
||||
void _write(Genode::size_t num_bytes)
|
||||
Genode::size_t _write(Genode::size_t num_bytes)
|
||||
{
|
||||
/* sanitize argument */
|
||||
num_bytes = Genode::min(num_bytes, _io_buffer.size());
|
||||
|
||||
/* write data to descriptor */
|
||||
if (::write(fd(), _io_buffer.local_addr<char>(), num_bytes) < 0)
|
||||
ssize_t written_bytes = ::write(fd(),
|
||||
_io_buffer.local_addr<char>(),
|
||||
num_bytes);
|
||||
|
||||
if (written_bytes < 0) {
|
||||
Genode::error("write error, dropping data");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return written_bytes;
|
||||
}
|
||||
|
||||
Genode::Dataspace_capability _dataspace()
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2016 Genode Labs GmbH
|
||||
* Copyright (C) 2011-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -433,14 +433,22 @@ namespace Terminal {
|
||||
return num_bytes;
|
||||
}
|
||||
|
||||
void _write(Genode::size_t num_bytes)
|
||||
Genode::size_t _write(Genode::size_t num_bytes)
|
||||
{
|
||||
/* sanitize argument */
|
||||
num_bytes = Genode::min(num_bytes, _io_buffer.size());
|
||||
|
||||
/* write data to socket, assuming that it won't block */
|
||||
if (::write(sd(), _io_buffer.local_addr<char>(), num_bytes) < 0)
|
||||
ssize_t written_bytes = ::write(sd(),
|
||||
_io_buffer.local_addr<char>(),
|
||||
num_bytes);
|
||||
|
||||
if (written_bytes < 0) {
|
||||
Genode::error("write error, dropping data");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return written_bytes;
|
||||
}
|
||||
|
||||
Genode::Dataspace_capability _dataspace()
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2013 Genode Labs GmbH
|
||||
* Copyright (C) 2011-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -427,7 +427,7 @@ namespace Terminal {
|
||||
return num_bytes;
|
||||
}
|
||||
|
||||
void _write(Genode::size_t num_bytes)
|
||||
Genode::size_t _write(Genode::size_t num_bytes)
|
||||
{
|
||||
Genode::Lock::Guard guard(_lock);
|
||||
|
||||
@ -439,6 +439,8 @@ namespace Terminal {
|
||||
_decoder.insert(src[i]);
|
||||
}
|
||||
_trigger_flush_callback.trigger_flush();
|
||||
|
||||
return num_bytes;
|
||||
}
|
||||
|
||||
Genode::Dataspace_capability _dataspace()
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013 Genode Labs GmbH
|
||||
* Copyright (C) 2013-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -297,7 +297,7 @@ class Terminal::Session_component : public Genode::Rpc_object<Session, Session_c
|
||||
return num_bytes;
|
||||
}
|
||||
|
||||
void _write(Genode::size_t num_bytes)
|
||||
Genode::size_t _write(Genode::size_t num_bytes)
|
||||
{
|
||||
unsigned char *src = _io_buffer.local_addr<unsigned char>();
|
||||
|
||||
@ -306,6 +306,8 @@ class Terminal::Session_component : public Genode::Rpc_object<Session, Session_c
|
||||
/* submit character to sequence decoder */
|
||||
_decoder.insert(src[i]);
|
||||
}
|
||||
|
||||
return num_bytes;
|
||||
}
|
||||
|
||||
Genode::Dataspace_capability _dataspace()
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2013 Genode Labs GmbH
|
||||
* Copyright (C) 2011-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -80,17 +80,21 @@ class Terminal::Session_client : public Genode::Rpc_client<Session>
|
||||
while (written_bytes < num_bytes) {
|
||||
|
||||
/* copy payload to I/O buffer */
|
||||
Genode::size_t n = Genode::min(num_bytes - written_bytes,
|
||||
_io_buffer.size());
|
||||
Genode::size_t payload_bytes = Genode::min(num_bytes - written_bytes,
|
||||
_io_buffer.size());
|
||||
Genode::memcpy(_io_buffer.local_addr<char>(),
|
||||
src + written_bytes, n);
|
||||
src + written_bytes, payload_bytes);
|
||||
|
||||
/* tell server to pick up new I/O buffer content */
|
||||
call<Rpc_write>(n);
|
||||
Genode::size_t written_payload_bytes = call<Rpc_write>(payload_bytes);
|
||||
|
||||
written_bytes += written_payload_bytes;
|
||||
|
||||
if (written_payload_bytes != payload_bytes)
|
||||
return written_bytes;
|
||||
|
||||
written_bytes += n;
|
||||
}
|
||||
return num_bytes;
|
||||
return written_bytes;
|
||||
}
|
||||
|
||||
void connected_sigh(Genode::Signal_context_capability cap)
|
||||
|
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2013 Genode Labs GmbH
|
||||
* Copyright (C) 2011-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -91,7 +91,7 @@ struct Terminal::Session : Genode::Session
|
||||
GENODE_RPC(Rpc_size, Size, size);
|
||||
GENODE_RPC(Rpc_avail, bool, avail);
|
||||
GENODE_RPC(Rpc_read, Genode::size_t, _read, Genode::size_t);
|
||||
GENODE_RPC(Rpc_write, void, _write, Genode::size_t);
|
||||
GENODE_RPC(Rpc_write, Genode::size_t, _write, Genode::size_t);
|
||||
GENODE_RPC(Rpc_connected_sigh, void, connected_sigh, Genode::Signal_context_capability);
|
||||
GENODE_RPC(Rpc_read_avail_sigh, void, read_avail_sigh, Genode::Signal_context_capability);
|
||||
GENODE_RPC(Rpc_dataspace, Genode::Dataspace_capability, _dataspace);
|
||||
|
@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-2016 Genode Labs GmbH
|
||||
* Copyright (C) 2011-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
@ -168,14 +168,16 @@ class Uart::Session_component : public Rpc_object<Uart::Session,
|
||||
return n;
|
||||
}
|
||||
|
||||
void _write(Genode::size_t num_bytes)
|
||||
Genode::size_t _write(Genode::size_t num_bytes)
|
||||
{
|
||||
/* constain argument to I/O buffer size */
|
||||
/* constrain argument to I/O buffer size */
|
||||
num_bytes = Genode::min(num_bytes, _io_buffer.size());
|
||||
|
||||
char const *io_buf = _io_buffer.local_addr<char>();
|
||||
for (Genode::size_t i = 0; i < num_bytes; i++)
|
||||
_driver.put_char(io_buf[i]);
|
||||
|
||||
return num_bytes;
|
||||
}
|
||||
|
||||
Genode::Dataspace_capability _dataspace() {
|
||||
|
@ -117,16 +117,19 @@ class Terminal::Session_component : public Rpc_object<Session, Session_component
|
||||
|
||||
size_t _read(size_t dst_len) { return 0; }
|
||||
|
||||
void _write(Genode::size_t num_bytes)
|
||||
size_t _write(Genode::size_t num_bytes)
|
||||
{
|
||||
/* sanitize argument */
|
||||
num_bytes = Genode::min(num_bytes, _io_buffer.size());
|
||||
|
||||
char const *src = _io_buffer.local_addr<char>();
|
||||
|
||||
for (size_t written_bytes = 0; written_bytes < num_bytes; )
|
||||
size_t written_bytes;
|
||||
for (written_bytes = 0; written_bytes < num_bytes; )
|
||||
written_bytes += _output.write(src + written_bytes,
|
||||
num_bytes - written_bytes);
|
||||
|
||||
return written_bytes;
|
||||
}
|
||||
|
||||
Dataspace_capability _dataspace() { return _io_buffer.cap(); }
|
||||
|
@ -92,10 +92,12 @@ Genode::size_t Session_component::_read(Genode::size_t dst_len)
|
||||
}
|
||||
|
||||
|
||||
void Session_component::_write(Genode::size_t num_bytes)
|
||||
Genode::size_t Session_component::_write(Genode::size_t num_bytes)
|
||||
{
|
||||
unsigned char *src = _io_buffer.local_addr<unsigned char>();
|
||||
|
||||
size_t const num_bytes_total = num_bytes;
|
||||
|
||||
size_t num_bytes_written = 0;
|
||||
size_t src_index = 0;
|
||||
while (num_bytes_written < num_bytes)
|
||||
@ -129,6 +131,8 @@ void Session_component::_write(Genode::size_t num_bytes)
|
||||
|
||||
_cross_num_bytes_avail += num_bytes_written;
|
||||
_partner.cross_write();
|
||||
|
||||
return num_bytes_total;
|
||||
}
|
||||
|
||||
|
||||
|
@ -74,7 +74,7 @@ namespace Terminal {
|
||||
|
||||
Genode::size_t _read(Genode::size_t dst_len);
|
||||
|
||||
void _write(Genode::size_t num_bytes);
|
||||
Genode::size_t _write(Genode::size_t num_bytes);
|
||||
|
||||
Genode::Dataspace_capability _dataspace();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user