mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-13 22:23:45 +00:00
util/attempt.h: introduce 'Ok' type
This type alleviates the need to re-introduce custom '*_ok' types whenever a result can be an error but no value.
This commit is contained in:
parent
2e76f4fc58
commit
fee2f354dc
@ -87,30 +87,11 @@ class Core::Platform : public Platform_generic
|
||||
*/
|
||||
struct Pseudo_ram_allocator : Range_allocator
|
||||
{
|
||||
Alloc_result try_alloc(size_t) override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Alloc_result alloc_aligned(size_t, unsigned, Range) override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Alloc_result alloc_addr(size_t, addr_t) override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Range_result add_range(addr_t, size_t) override
|
||||
{
|
||||
return Range_ok();
|
||||
}
|
||||
|
||||
Range_result remove_range(addr_t, size_t) override
|
||||
{
|
||||
return Range_ok();
|
||||
}
|
||||
Alloc_result try_alloc(size_t) override { return nullptr; }
|
||||
Alloc_result alloc_aligned(size_t, unsigned, Range) override { return nullptr; }
|
||||
Alloc_result alloc_addr(size_t, addr_t) override { return nullptr; }
|
||||
Range_result add_range(addr_t, size_t) override { return Ok(); }
|
||||
Range_result remove_range(addr_t, size_t) override { return Ok(); }
|
||||
|
||||
void free(void *) override { }
|
||||
void free(void *, size_t) override { }
|
||||
|
@ -137,8 +137,7 @@ struct Genode::Range_allocator : Allocator
|
||||
/**
|
||||
* Return type of range-management operations
|
||||
*/
|
||||
struct Range_ok { };
|
||||
using Range_result = Attempt<Range_ok, Alloc_error>;
|
||||
using Range_result = Attempt<Ok, Alloc_error>;
|
||||
|
||||
/**
|
||||
* Add free address range to allocator
|
||||
|
@ -63,8 +63,7 @@ class Genode::Slab : public Allocator
|
||||
*/
|
||||
void _insert_sb(Block *);
|
||||
|
||||
struct Expand_ok { };
|
||||
using Expand_result = Attempt<Expand_ok, Alloc_error>;
|
||||
using Expand_result = Attempt<Ok, Alloc_error>;
|
||||
|
||||
/**
|
||||
* Expand slab by one block
|
||||
|
@ -26,9 +26,8 @@ namespace Genode { namespace Trace {
|
||||
using Thread_name = String<32>;
|
||||
|
||||
struct Num_subjects { unsigned value; };
|
||||
struct Policy_size { size_t num_bytes; };
|
||||
struct Buffer_size { size_t num_bytes; };
|
||||
struct Trace_ok { };
|
||||
struct Policy_size { size_t num_bytes; };
|
||||
struct Buffer_size { size_t num_bytes; };
|
||||
|
||||
struct Policy_id;
|
||||
struct Subject_id;
|
||||
|
@ -353,9 +353,8 @@ struct Genode::Pd_session : Session, Pd_account
|
||||
virtual addr_t dma_addr(Ram_dataspace_capability) = 0;
|
||||
|
||||
enum class Attach_dma_error { OUT_OF_RAM, OUT_OF_CAPS, DENIED };
|
||||
struct Attach_dma_ok { };
|
||||
|
||||
using Attach_dma_result = Attempt<Attach_dma_ok, Attach_dma_error>;
|
||||
using Attach_dma_result = Attempt<Ok, Attach_dma_error>;
|
||||
|
||||
/**
|
||||
* Attach dataspace to I/O page table at specified address 'at'
|
||||
|
@ -96,7 +96,7 @@ struct Genode::Trace::Connection : Genode::Connection<Genode::Trace::Session>,
|
||||
void unload_policy(Policy_id id) { call<Rpc_unload_policy>(id); }
|
||||
|
||||
enum class Trace_error { FOREIGN, SOURCE_IS_DEAD, INVALID_SUBJECT, INVALID_POLICY };
|
||||
using Trace_result = Attempt<Trace_ok, Trace_error>;
|
||||
using Trace_result = Attempt<Ok, Trace_error>;
|
||||
|
||||
/**
|
||||
* Start tracing of a subject
|
||||
@ -108,7 +108,7 @@ struct Genode::Trace::Connection : Genode::Connection<Genode::Trace::Session>,
|
||||
return call<Rpc_trace>(s, p, size); });
|
||||
|
||||
return rpc_result.convert<Trace_result>(
|
||||
[&] (Trace_ok ok) { return ok; },
|
||||
[&] (Ok ok) { return ok; },
|
||||
[&] (Trace_rpc_error e) {
|
||||
switch (e) {
|
||||
case Trace_rpc_error::OUT_OF_RAM: /* cannot occur, handled by '_retry' above */
|
||||
|
@ -40,7 +40,7 @@ struct Genode::Trace::Session : Genode::Session
|
||||
using Alloc_policy_rpc_result = Attempt<Policy_id, Alloc_policy_rpc_error>;
|
||||
using Subjects_rpc_result = Attempt<Num_subjects, Alloc_rpc_error>;
|
||||
using Infos_rpc_result = Attempt<Num_subjects, Alloc_rpc_error>;
|
||||
using Trace_rpc_result = Attempt<Trace_ok, Trace_rpc_error>;
|
||||
using Trace_rpc_result = Attempt<Ok, Trace_rpc_error>;
|
||||
|
||||
|
||||
virtual ~Session() { }
|
||||
|
@ -19,6 +19,11 @@
|
||||
namespace Genode {
|
||||
template <typename, typename> struct Attempt;
|
||||
template <typename, typename> struct Unique_attempt;
|
||||
|
||||
/**
|
||||
* Type used for results with no return value but error conditions
|
||||
*/
|
||||
struct Ok { };
|
||||
}
|
||||
|
||||
|
||||
|
@ -102,8 +102,7 @@ class Core::Trace::Policy_registry
|
||||
_policies.remove(p);
|
||||
}
|
||||
|
||||
struct Insert_ok { };
|
||||
using Insert_result = Attempt<Insert_ok, Ram::Error>;
|
||||
using Insert_result = Attempt<Ok, Ram::Error>;
|
||||
|
||||
Insert_result insert(Policy_owner const &owner, Policy_id const id,
|
||||
Allocator &md_alloc, Ram::Allocator &ram,
|
||||
@ -115,7 +114,7 @@ class Core::Trace::Policy_registry
|
||||
Policy &policy = *new (&md_alloc) Policy(owner, id, md_alloc, ram, size);
|
||||
_policies.insert(&policy);
|
||||
return policy.ds.convert<Insert_result>(
|
||||
[&] (Ram::Allocation const &) { return Insert_ok(); },
|
||||
[&] (Ram::Allocation const &) { return Ok(); },
|
||||
[&] (Ram::Error e) { return e; });
|
||||
}
|
||||
catch (Out_of_ram) { return Ram::Error::OUT_OF_RAM; }
|
||||
|
@ -366,7 +366,7 @@ Region_map_component::attach_dma(Dataspace_capability ds_cap, addr_t at)
|
||||
using Attach_dma_error = Pd_session::Attach_dma_error;
|
||||
|
||||
return _attach(ds_cap, attr).convert<Attach_dma_result>(
|
||||
[&] (Range) { return Pd_session::Attach_dma_ok(); },
|
||||
[&] (Range) { return Ok(); },
|
||||
[&] (Attach_error e) {
|
||||
switch (e) {
|
||||
case Attach_error::OUT_OF_RAM: return Attach_dma_error::OUT_OF_RAM;
|
||||
|
@ -120,7 +120,7 @@ Session_component::trace(Subject_id subject_id, Policy_id policy_id, Buffer_size
|
||||
{
|
||||
using Result = Subject::Trace_result;
|
||||
switch (result) {
|
||||
case Result::OK: return Trace_ok { };
|
||||
case Result::OK: return Ok { };
|
||||
case Result::OUT_OF_RAM: return Trace_rpc_error::OUT_OF_RAM;
|
||||
case Result::OUT_OF_CAPS: return Trace_rpc_error::OUT_OF_CAPS;
|
||||
case Result::FOREIGN: return Trace_rpc_error::FOREIGN;
|
||||
|
@ -254,7 +254,7 @@ Allocator_avl_base::Range_result Allocator_avl_base::add_range(addr_t new_addr,
|
||||
/* create new block that spans over all merged blocks */
|
||||
_add_block(*new_block_ptr, new_addr, new_size, Block::FREE);
|
||||
|
||||
return Range_ok();
|
||||
return Ok();
|
||||
},
|
||||
[&] (Alloc_error error) {
|
||||
return error; });
|
||||
@ -287,7 +287,7 @@ Allocator_avl_base::Range_result Allocator_avl_base::remove_range(addr_t base, s
|
||||
_md_alloc.free(blocks.b2_ptr, sizeof(Block));
|
||||
|
||||
if (b == 0)
|
||||
result = Range_ok();
|
||||
result = Ok();
|
||||
|
||||
done = true;
|
||||
return;
|
||||
|
@ -138,7 +138,7 @@ Heap::_allocate_dataspace(size_t size, bool enforce_separate_metadata)
|
||||
|
||||
/* add new local address range to our local allocator */
|
||||
_alloc->add_range(attach_guard.range.start, size).with_result(
|
||||
[&] (Range_allocator::Range_ok) {
|
||||
[&] (Ok) {
|
||||
metadata = _alloc->alloc_aligned(sizeof(Heap::Dataspace), log2(16U)); },
|
||||
[&] (Alloc_error error) {
|
||||
metadata = error; });
|
||||
|
@ -331,7 +331,7 @@ void Slab::_insert_sb(Block *sb)
|
||||
Slab::Expand_result Slab::_expand()
|
||||
{
|
||||
if (!_backing_store || _nested)
|
||||
return Expand_ok();
|
||||
return Ok();
|
||||
|
||||
/* allocate new block for slab */
|
||||
_nested = true;
|
||||
@ -353,7 +353,7 @@ Slab::Expand_result Slab::_expand()
|
||||
* list.
|
||||
*/
|
||||
_insert_sb(sb_ptr);
|
||||
return Expand_ok(); },
|
||||
return Ok(); },
|
||||
|
||||
[&] (Alloc_error error) {
|
||||
return error; });
|
||||
@ -387,8 +387,8 @@ Allocator::Alloc_result Slab::try_alloc(size_t size)
|
||||
Expand_result expand_result = _expand();
|
||||
if (expand_result.failed())
|
||||
return expand_result.convert<Alloc_result>(
|
||||
[&] (Expand_ok) { return Alloc_error::DENIED; },
|
||||
[&] (Alloc_error error) { return error; });
|
||||
[&] (Ok) { return Alloc_error::DENIED; },
|
||||
[&] (Alloc_error e) { return e; });
|
||||
}
|
||||
|
||||
/* skip completely occupied slab blocks, detect cycles */
|
||||
|
@ -395,8 +395,7 @@ struct Slab_backend_alloc : public Genode::Allocator,
|
||||
Genode::Allocator_avl _range;
|
||||
Genode::Ram_allocator &_ram;
|
||||
|
||||
struct Extend_ok { };
|
||||
using Extend_result = Genode::Attempt<Extend_ok, Alloc_error>;
|
||||
using Extend_result = Genode::Attempt<Ok, Alloc_error>;
|
||||
|
||||
Extend_result _extend_one_block()
|
||||
{
|
||||
@ -430,8 +429,8 @@ struct Slab_backend_alloc : public Genode::Allocator,
|
||||
|
||||
return _range.add_range(_base + range.start, range.num_bytes)
|
||||
.convert<Extend_result>(
|
||||
[&] (Range_allocator::Range_ok) { return Extend_ok(); },
|
||||
[&] (Alloc_error e) { return e; });
|
||||
[&] (Ok) { return Ok(); },
|
||||
[&] (Alloc_error e) { return e; });
|
||||
},
|
||||
|
||||
[&] (Region_map::Attach_error e) {
|
||||
@ -479,8 +478,8 @@ struct Slab_backend_alloc : public Genode::Allocator,
|
||||
return result;
|
||||
|
||||
return _extend_one_block().convert<Alloc_result>(
|
||||
[&] (Extend_ok) { return _range.try_alloc(size); },
|
||||
[&] (Alloc_error error) { return error; });
|
||||
[&] (Ok) { return _range.try_alloc(size); },
|
||||
[&] (Alloc_error e) { return e; });
|
||||
}
|
||||
|
||||
void free(void *addr, Genode::size_t size) { _range.free(addr, size); }
|
||||
|
@ -112,9 +112,9 @@ class Timed_semaphore
|
||||
{
|
||||
public:
|
||||
|
||||
struct Down_ok { };
|
||||
struct Down_timed_out { };
|
||||
using Down_result = Genode::Attempt<Down_ok, Down_timed_out>;
|
||||
using Ok = Genode::Ok;
|
||||
using Down_result = Genode::Attempt<Ok, Down_timed_out>;
|
||||
|
||||
private:
|
||||
|
||||
@ -198,7 +198,7 @@ class Timed_semaphore
|
||||
blockade.block();
|
||||
|
||||
if (wakeup_called)
|
||||
return Down_ok();
|
||||
return Ok();
|
||||
else
|
||||
return Down_timed_out();
|
||||
}
|
||||
@ -338,7 +338,7 @@ class Timed_semaphore
|
||||
|
||||
} else {
|
||||
_meta_mutex.release();
|
||||
return Down_ok();
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -243,7 +243,7 @@ struct Cond
|
||||
Genode::Microseconds(timeout_ms(currtime, *abstime) * 1000);
|
||||
|
||||
signal_sem.down(true, timeout_us).with_result(
|
||||
[&] (Timed_semaphore::Down_ok) { },
|
||||
[&] (Timed_semaphore::Ok) { },
|
||||
[&] (Timed_semaphore::Down_timed_out) { result = -2; }
|
||||
);
|
||||
}
|
||||
|
@ -32,8 +32,7 @@ class Pcapng::Write_buffer
|
||||
public:
|
||||
|
||||
enum class Append_error { OUT_OF_MEM, OVERFLOW };
|
||||
struct Append_ok { };
|
||||
using Append_result = Attempt<Append_ok, Append_error>;
|
||||
using Append_result = Attempt<Ok, Append_error>;
|
||||
|
||||
private:
|
||||
|
||||
@ -59,7 +58,7 @@ class Pcapng::Write_buffer
|
||||
|
||||
_total_length += block.size();
|
||||
|
||||
return Append_ok();
|
||||
return Ok();
|
||||
}
|
||||
|
||||
void write_to_file(Genode::Append_file &dst, Directory::Path const &path)
|
||||
|
@ -113,10 +113,9 @@ struct Extract::Extracted_archive : Noncopyable
|
||||
|
||||
struct Strip { unsigned value; };
|
||||
|
||||
struct Extract_ok { };
|
||||
enum class Extract_error : uint32_t {
|
||||
OPEN_FAILED, READ_FAILED, WRITE_FAILED, };
|
||||
using Extract_result = Attempt<Extract_ok, Extract_error>;
|
||||
using Extract_result = Attempt<Ok, Extract_error>;
|
||||
|
||||
/**
|
||||
* \param path path to archive file
|
||||
@ -223,7 +222,7 @@ struct Extract::Extracted_archive : Noncopyable
|
||||
return Extract_error::WRITE_FAILED;
|
||||
}
|
||||
|
||||
return Extract_ok();
|
||||
return Ok();
|
||||
}
|
||||
};
|
||||
|
||||
@ -279,7 +278,7 @@ struct Extract::Main
|
||||
|
||||
Extracted_archive archive;
|
||||
archive.extract(src_path, strip, raw_name).with_result(
|
||||
[&] (Extracted_archive::Extract_ok) {
|
||||
[&] (Ok) {
|
||||
|
||||
if (_verbose)
|
||||
log("extracted '", src_path, "' to '", dst_path, "'");
|
||||
|
@ -193,7 +193,7 @@ Symlink_resolve_result Libc::resolve_symlinks(char const *path, Absolute_path &r
|
||||
resolved_path = next_iteration_working_path;
|
||||
resolved_path.remove_trailing('/');
|
||||
|
||||
return Symlinks_resolved_ok();
|
||||
return Ok();
|
||||
}
|
||||
|
||||
|
||||
@ -214,7 +214,7 @@ static Symlink_resolve_result resolve_symlinks_except_last_element(char const *p
|
||||
return Symlink_resolve_error();
|
||||
}
|
||||
|
||||
return Symlinks_resolved_ok();
|
||||
return Ok();
|
||||
}
|
||||
|
||||
|
||||
|
@ -28,9 +28,8 @@ namespace Libc {
|
||||
|
||||
using Absolute_path = Genode::Path<PATH_MAX>;
|
||||
|
||||
struct Symlinks_resolved_ok { };
|
||||
struct Symlink_resolve_error { };
|
||||
using Symlink_resolve_result = Attempt<Symlinks_resolved_ok, Symlink_resolve_error>;
|
||||
using Symlink_resolve_result = Attempt<Ok, Symlink_resolve_error>;
|
||||
|
||||
Symlink_resolve_result resolve_symlinks(char const *path,
|
||||
Absolute_path &resolved_path);
|
||||
|
@ -158,15 +158,13 @@ void Libc::Kernel::_init_file_descriptors()
|
||||
resolved_path = next_iteration_working_path;
|
||||
resolved_path.remove_trailing('/');
|
||||
|
||||
return Symlinks_resolved_ok();
|
||||
return Ok();
|
||||
};
|
||||
|
||||
using Path = String<Vfs::MAX_PATH_LEN>;
|
||||
|
||||
struct Absolute_path_resolved_ok { };
|
||||
struct Absolute_path_resolve_error { };
|
||||
using Absolute_path_resolve_result = Attempt<Absolute_path_resolved_ok,
|
||||
Absolute_path_resolve_error>;
|
||||
using Absolute_path_resolve_result = Attempt<Ok, Absolute_path_resolve_error>;
|
||||
|
||||
auto resolve_absolute_path = [&] (Path const &path, Absolute_path &abs_path) -> Absolute_path_resolve_result
|
||||
{
|
||||
@ -177,7 +175,7 @@ void Libc::Kernel::_init_file_descriptors()
|
||||
if (resolve_symlinks(abs_dir, abs_path).failed())
|
||||
return Absolute_path_resolve_error();
|
||||
abs_path.append_element(dir_entry.string());
|
||||
return Absolute_path_resolved_ok();
|
||||
return Ok();
|
||||
} catch (Path_base::Path_too_long) { return Absolute_path_resolve_error(); }
|
||||
};
|
||||
|
||||
|
@ -101,7 +101,7 @@ class Genode::Packet_allocator : public Genode::Range_allocator
|
||||
if (bits_cnt > max_cnt)
|
||||
_array->set(max_cnt, bits_cnt - max_cnt);
|
||||
|
||||
return Range_ok();
|
||||
return Ok();
|
||||
|
||||
}
|
||||
catch (Out_of_ram) { error = Alloc_error::OUT_OF_RAM; }
|
||||
@ -134,7 +134,7 @@ class Genode::Packet_allocator : public Genode::Range_allocator
|
||||
_bits = nullptr;
|
||||
}
|
||||
|
||||
return Range_ok();
|
||||
return Ok();
|
||||
}
|
||||
|
||||
Alloc_result alloc_aligned(size_t size, unsigned, Range) override
|
||||
|
@ -67,7 +67,7 @@ void Device_pd::add_range(Io_mmu::Range const & range,
|
||||
|
||||
do {
|
||||
_pd.attach_dma(cap, range.start).with_result(
|
||||
[&] (Pd_session::Attach_dma_ok) {
|
||||
[&] (Ok) {
|
||||
/* trigger eager mapping of memory */
|
||||
_pd.map(Pd_session::Virt_range { range.start, range.size });
|
||||
retry = false;
|
||||
|
@ -22,9 +22,8 @@ using namespace Genode;
|
||||
|
||||
struct Entropy_source : Interface
|
||||
{
|
||||
struct Collect_ok { };
|
||||
struct Collect_error { };
|
||||
using Collect_result = Attempt<Collect_ok, Collect_error>;
|
||||
using Collect_result = Attempt<Ok, Collect_error>;
|
||||
|
||||
virtual Collect_result collect(Byte_range_ptr const &dst) = 0;
|
||||
};
|
||||
@ -87,7 +86,7 @@ struct Xoroshiro_128_plus_reseeding
|
||||
{
|
||||
return _entropy_src.collect(Byte_range_ptr { (char*)&_seed,
|
||||
sizeof(_seed) }).convert<bool>(
|
||||
[&] (Entropy_source::Collect_ok) {
|
||||
[&] (Ok) {
|
||||
_consumed_limit = CONSUME_THRESHOLD + (_seed & 0xfffu);
|
||||
_xoroshiro.construct(_seed);
|
||||
return true;
|
||||
@ -161,7 +160,7 @@ struct Vfs::Xoroshiro_file_system : Single_file_system
|
||||
Collect_result collect(Byte_range_ptr const &dst) override
|
||||
{
|
||||
if (_seed_file.read(Readonly_file::At { 0 }, dst) >= dst.num_bytes)
|
||||
return Collect_ok();
|
||||
return Ok();
|
||||
|
||||
return Collect_error();
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ size_t Terminal_crosslink::Session_component::_write(size_t num_bytes)
|
||||
|
||||
while ((num_bytes_written < num_bytes) && !error)
|
||||
_buffer.add(src[num_bytes_written]).with_result(
|
||||
[&] (Ring_buffer::Add_ok) { ++num_bytes_written; },
|
||||
[&] (Ok) { ++num_bytes_written; },
|
||||
[&] (Ring_buffer::Add_error) { error = true; }
|
||||
);
|
||||
|
||||
|
@ -51,10 +51,9 @@ namespace Terminal_crosslink {
|
||||
Ring_buffer(Byte_range_ptr const &buffer)
|
||||
: _queue(buffer.start), _queue_size(buffer.num_bytes) { }
|
||||
|
||||
struct Add_ok { };
|
||||
enum class Add_error { OVERFLOW };
|
||||
|
||||
using Add_result = Attempt<Add_ok, Add_error>;
|
||||
using Add_result = Attempt<Ok, Add_error>;
|
||||
|
||||
/**
|
||||
* Place element into ring buffer
|
||||
@ -64,7 +63,7 @@ namespace Terminal_crosslink {
|
||||
if ((_head + 1)%_queue_size != _tail) {
|
||||
_queue[_head] = ev;
|
||||
_head = (_head + 1)%_queue_size;
|
||||
return Add_ok();
|
||||
return Ok();
|
||||
} else
|
||||
return Add_error::OVERFLOW;
|
||||
}
|
||||
|
@ -300,7 +300,7 @@ struct Test_tracing
|
||||
_trace.trace(id, policy_id, Trace::Buffer_size{16384});
|
||||
|
||||
trace_result.with_result(
|
||||
[&] (Trace::Trace_ok) {
|
||||
[&] (Ok) {
|
||||
Dataspace_capability ds_cap = _trace.buffer(id);
|
||||
_test_monitor.construct(env.rm(), id, ds_cap);
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user