The internal reuse of FixedMemoryStream makes this straightforward.
There alread is one user of the new API, demonstrating the need for this
change beyond what I said out to use it for :^)
Just like with input buffered streams, we don't currently have a use
case for output buffered streams which aren't seekable, since the main
application are files.
Since the existing Promise class is designed with deferred tasks on the
main thread only, we need a new class that will ensure we can handle
promises that are resolved/rejected off the main thread.
This new class ensures that the callbacks are only called on the same
thread that the promise is fulfilled from. If the callbacks are not set
before the thread tries to fulfill the promise, it will spin until they
are so that they will run on that thread.
Returning a reference resulted in Mail's use of Promise causing a crash.
Also, awaiting an already-awaited promise is an odd thing to do anyway,
so let's just make it release the resolved/rejected value instead of
returning a reference to it.
Co-Authored-By: Valtteri Koskivuori <vkoskiv@gmail.com>
The previous iteration of this API was somewhat odd and rough in random
places, which degraded usability and made less than perfect sense.
This commit reworks the API to be a little closer to more
conventional promise APIs (a la javascript promises).
Also adds a test to ensure the class even works.
It does not make sense to test known-working code that is deprecated and
in the process of being removed. Also, this test becomes too cumbersome
to write without using read_all or line iteration in some form, and
migrating the test is just silly.
Note that in some cases (in particular SQL::Result and PDFErrorOr),
there is no Formatter defined for the error type, hence TRY_OR_FAIL
cannot work as-is. Furthermore, this commit leaves untouched the places
where MUST could be replaced by TRY_OR_FAIL.
Inspired by:
https://github.com/SerenityOS/serenity/pull/18710#discussion_r1186892445
When BufferedFile.can_read_line() was invoked on files with no newlines,
t incorrectly returned a false result for this single line that, even
though doesn't finish with a newline character, is still a line. Since
this method is usually used in tandem with read_line(), users would miss
reading this line (and hence all the file contents).
This commit fixes this corner case by adding another check after a
negative result from finding a newline character. This new check does
the same as the check that is done *before* looking for newlines, which
takes care of this problem, but only works for files that have at least
one newline (hence the buffer has already been filled).
A new unit test has been added that shows the use case. Without the
changes in this commit the test fails, which is a testament that this
commit really fixes the underlying issue.
Similar to POSIX read, the basic read and write functions of AK::Stream
do not have a lower limit of how much data they read or write (apart
from "none at all").
Rename the functions to "read some [data]" and "write some [data]" (with
"data" being omitted, since everything here is reading and writing data)
to make them sufficiently distinct from the functions that ensure to
use the entire buffer (which should be the go-to function for most
usages).
No functional changes, just a lot of new FIXMEs.
This commit moves the implementation of getopt into AK, and converts its
API to understand and use StringView instead of char*.
Everything else is caught in the crossfire of making
Option::accept_value() take a StringView instead of a char const*.
With this, we must now pass a Span<StringView> to ArgsParser::parse(),
applications using LibMain are unaffected, but anything not using that
or taking its own argc/argv has to construct a Vector<StringView> for
this method.
When we move the test to AK (together with the actual stream
implementation), finding the input file to read from is going to become
significantly harder, since the test also runs outside of SerenityOS.
Since this was just a smoke test during early development (and we should
now have reasonable coverage with actual usages in the other parts of
the OS), let's just remove that test instead of trying to make input
file lookups work.
`Stream` will be qualified as `AK::Stream` until we remove the
`Core::Stream` namespace. `IODevice` now reuses the `SeekMode` that is
defined by `SeekableStream`, since defining its own would require us to
qualify it with `AK::SeekMode` everywhere.
The test currently watches /tmp, which the OS can create/modify files
under at any time outside of our control. So just ignore events that we
aren't interested in.
Also test removing an item from the FileWatcher.
A negative return value doesn't make sense for any of those functions.
The return types were inherited from POSIX, where they also need to have
an indicator for an error (negative values).
This implements FileWatcher using inotify filesystem events. Serenity's
InodeWatcher is remarkably similar to inotify, so this is almost an
identical implementation.
The existing TestLibCoreFileWatcher test is added to Lagom (currently
just for Linux).
This does not implement BlockingFileWatcher as that is currently not
used anywhere but on Serenity.
This saves us an actual seek and rereading already stored buffer data in
cases where the seek is entirely covered by the currently buffered data.
This is especially important since we implement `discard` using `seek`
for seekable streams.
Also add some tests that ensure that the input and output streams match
each other, because I can't wrap my head around what the internal
representation looks like.
In 7c5e30daaa, the focus was "only" on
Userland/Libraries/, whereas this commit cleans up the remaining
headers in the repo, and any new badly-formatted include.
This is a first step towards handling OOM errors instead of just
crashing the program.
Now UDPServer's method `receive()` return memory allocation
errors explicitly with help of ErrorOr.
This removes one FIXME and make a bunch of new ones. :(
Next to functions like `is_eof` these were really confusing to use, and
the `read`/`write` functions should fail anyways if a stream is not
readable/writable.
We have a new, improved string type coming up in AK (OOM aware, no null
state), and while it's going to use UTF-8, the name UTF8String is a
mouthful - so let's free up the String name by renaming the existing
class.
Making the old one have an annoying name will hopefully also help with
quick adoption :^)
Otherwise, we end up propagating those dependencies into targets that
link against that library, which creates unnecessary link-time
dependencies.
Also included are changes to readd now missing dependencies to tools
that actually need them.
Each of these strings would previously rely on StringView's char const*
constructor overload, which would call __builtin_strlen on the string.
Since we now have operator ""sv, we can replace these with much simpler
versions. This opens the door to being able to remove
StringView(char const*).
No functional changes.
This new class with an admittedly long OOP-y name provides a circular
queue in shared memory. The queue is a lock-free synchronous queue
implemented with atomics, and its implementation is significantly
simplified by only accounting for one producer (and multiple consumers).
It is intended to be used as a producer-consumer communication
datastructure across processes. The original motivation behind this
class is efficient short-period transfer of audio data in userspace.
This class includes formal proofs of several correctness properties of
the main queue operations `enqueue` and `dequeue`. These proofs are not
100% complete in their existing form as the invariants they depend on
are "handwaved". This seems fine to me right now, as any proof is better
than no proof :^). Anyways, the proofs should build confidence that the
implemented algorithms, which are only roughly based on existing work,
operate correctly in even the worst-case concurrency scenarios.
Similar reasoning to making Core::Stream::read() return Bytes, except
that every user of read_line() creates a StringView from the result, so
let's just return one right away.