Kernel: Convert try_make_ref_counted to use ErrorOr

This allows more ergonomic memory allocation failure related error
checking using the TRY macro.
This commit is contained in:
Idan Horowitz 2022-02-03 16:43:34 +02:00 committed by Andreas Kling
parent 8289727fac
commit a65bbbdb71
4 changed files with 14 additions and 15 deletions

View file

@ -336,16 +336,16 @@ inline RefPtr<T> adopt_ref_if_nonnull(T* object)
}
template<typename T, class... Args>
requires(IsConstructible<T, Args...>) inline RefPtr<T> try_make_ref_counted(Args&&... args)
requires(IsConstructible<T, Args...>) inline ErrorOr<NonnullRefPtr<T>> try_make_ref_counted(Args&&... args)
{
return adopt_ref_if_nonnull(new (nothrow) T(forward<Args>(args)...));
return adopt_nonnull_ref_or_enomem(new (nothrow) T(forward<Args>(args)...));
}
// FIXME: Remove once P0960R3 is available in Clang.
template<typename T, class... Args>
inline RefPtr<T> try_make_ref_counted(Args&&... args)
inline ErrorOr<NonnullRefPtr<T>> try_make_ref_counted(Args&&... args)
{
return adopt_ref_if_nonnull(new (nothrow) T { forward<Args>(args)... });
return adopt_nonnull_ref_or_enomem(new (nothrow) T { forward<Args>(args)... });
}
template<typename T>

View file

@ -98,13 +98,14 @@ NonnullRefPtr<Bar> another_owner = our_object;
```
The `try_make_ref_counted<T>()` function constructs an object wrapped in `RefPtr<T>` which may be null if the allocation does not succeed. This allows the calling code to handle allocation failure as it wishes. All arguments passed to it are forwarded to `T`'s constructor.
The `try_make_ref_counted<T>()` function constructs an object wrapped in `ErrorOr<NonnullRefPtr<T>>` which may be an error if the allocation does not succeed. This allows the calling code to handle allocation failure as it wishes. All arguments passed to it are forwarded to `T`'s constructor.
```cpp
RefPtr<Bar> our_object = try_make_ref_counted<Bar>();
if (!our_object) {
auto our_object_or_error = try_make_ref_counted<Bar>();
if (our_object_or_error.is_error()) {
// handle allocation failure...
}
NonnullRefPtr<Bar> our_object = our_object_or_error.release_value();
RefPtr<Bar> another_owner = our_object;
```

View file

@ -486,16 +486,16 @@ inline RefPtr<T> adopt_ref_if_nonnull(T* object)
}
template<typename T, class... Args>
requires(IsConstructible<T, Args...>) inline RefPtr<T> try_make_ref_counted(Args&&... args)
requires(IsConstructible<T, Args...>) inline ErrorOr<NonnullRefPtr<T>> try_make_ref_counted(Args&&... args)
{
return adopt_ref_if_nonnull(new (nothrow) T(forward<Args>(args)...));
return adopt_nonnull_ref_or_enomem(new (nothrow) T(forward<Args>(args)...));
}
// FIXME: Remove once P0960R3 is available in Clang.
template<typename T, class... Args>
inline RefPtr<T> try_make_ref_counted(Args&&... args)
inline ErrorOr<NonnullRefPtr<T>> try_make_ref_counted(Args&&... args)
{
return adopt_ref_if_nonnull(new (nothrow) T { forward<Args>(args)... });
return adopt_nonnull_ref_or_enomem(new (nothrow) T { forward<Args>(args)... });
}
template<typename T>

View file

@ -45,12 +45,10 @@ ErrorOr<NonnullRefPtr<Thread>> Thread::try_create(NonnullRefPtr<Process> process
auto kernel_stack_region = TRY(MM.allocate_kernel_region(default_kernel_stack_size, {}, Memory::Region::Access::ReadWrite, AllocationStrategy::AllocateNow));
kernel_stack_region->set_stack(true);
auto block_timer = try_make_ref_counted<Timer>();
if (!block_timer)
return ENOMEM;
auto block_timer = TRY(try_make_ref_counted<Timer>());
auto name = TRY(KString::try_create(process->name()));
return adopt_nonnull_ref_or_enomem(new (nothrow) Thread(move(process), move(kernel_stack_region), block_timer.release_nonnull(), move(name)));
return adopt_nonnull_ref_or_enomem(new (nothrow) Thread(move(process), move(kernel_stack_region), move(block_timer), move(name)));
}
Thread::Thread(NonnullRefPtr<Process> process, NonnullOwnPtr<Memory::Region> kernel_stack_region, NonnullRefPtr<Timer> block_timer, NonnullOwnPtr<KString> name)