This reverts commit a362c37c8b.
The commit tried to add an unused function that continued our tradition
of not properly waiting for things but instead flooding event loop with
condition checks that delay firing of the event. I think this is a
fundamentally flawed approach. See also checks for
`fire_when_not_visible` in LibCore/EventLoopImplementationUnix.cpp.
If no EventLoop is present in the stack (like when you forget to create
one), a message is nicer than letting the developer go through the
stacktrace to figure out what went wrong.
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.
This shouldn't have been moved to EventLoopManager, as the manager is
global and one-per-process, and the implementation is one-per-loop.
This makes cross-thread event posting work again, and unbreaks
SoundPlayer (and probably other things as well.)
Things such as timers and notifiers aren't specific to one instance of
Core::EventLoop, so let's not tie them down to EventLoopImplementation.
Instead, move those APIs + signals & a few other things to a new
EventLoopManager interface. EventLoopManager also knows how to create a
new EventLoopImplementation object.
Using QEventLoop works for everything but it breaks *one* little feature
that we care about: automatically quitting the app when all windows have
been closed.
That only works if you drive the outermost main event loop with a
QCoreApplication instead of a QEventLoop. This is unfortunate, as it
complicates our API a little bit, but I'm sure we can think of a way to
make this nicer someday.
In order for QCoreApplication::exec() to process our own
ThreadEventQueue, we now have a zero-timer that we kick whenever new
events are posted to the thread queue.
The EventLoop is now a wrapper around an EventLoopImplementation.
Our old EventLoop code has moved into EventLoopImplementationUnix and
continues to work as before.
The main difference is that all the separate thread_local variables have
been collected into a file-local ThreadData data structure.
The goal here is to allow running Core::EventLoop with a totally
different backend, such as Qt for Ladybird.
This program has never lived up to its original idea, and has been
broken for years (property editing, etc). It's also unmaintained and
off-by-default since forever.
At this point, Inspector is more of a maintenance burden than a feature,
so this commit removes it from the system, along with the mechanism in
Core::EventLoop that enables it.
If we decide we want the feature again in the future, it can be
reimplemented better. :^)
Not a single client of this API actually used the event mask feature to
listen for readability AND writability.
Let's simplify the API and have only one hook: on_activation.
Instead of juggling events between individual instances of
Core::EventLoop, move queueing and processing to a separate per-thread
queue (ThreadEventQueue).
This was used in exactly one place, to avoid sending multiple
CustomEvents to the enqueuer thread in Audio::ConnectionToServer.
Instead of this, we now just send a CustomEvent and wake the enqueuer
thread. If it wakes up and has multiple CustomEvents, they get delivered
and ignored in no time anyway. Since they only get ignored if there's
no work to be done, this seems harmless.
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.
In this context, the promises are considered "jobs", and such jobs
depend in some way on the event loop. Therefore, they can be added to
the event loop, and the event loop will cancel all of its pending jobs
when it ends.
This will make it easier to support both string types at the same time
while we convert code, and tracking down remaining uses.
One big exception is Value::to_string() in LibJS, where the name is
dictated by the ToString AO.
This commit does three things atomically:
- switch over Core::Account+SystemServer+LoginServer to sid based socket
names.
- change socket names with %uid to %sid.
- add/update necessary pledges and unveils.
Userland: Switch over servers to sid based sockets
Userland: Properly pledge and unveil for sid based sockets
Core::Acount is only used within ``#ifdef __serenity__`` blocks in these
files, so guard the inclusion of Account.h in the same way.
This fixes the Android build of these files.
The audio enqueuer thread goes to sleep when there is no more audio data
present, and through normal Core::EventLoop events it can be woken up.
However, that waking up only happens when the thread is not currently
running, so that the wake-up events don't queue up and cause weirdness.
The atomic variable responsible for keeping track of whether the thread
is active can lead to a racy deadlock however, where the audio enqueuer
thread will never wake up again despite there being audio data to
enqueue. Consider this scenario:
- Main thread calls into async_enqueue. It detects that according to the
atomic variable, the other thread is still running, skipping the event
queue wake.
- Enqueuer thread has just finished playing the last chunk of audio and
detects that there is no audio left. It enters the if block with the
dbgln "Reached end of provided audio data..."
- Main thread enqueues audio, making the user sample queue non-empty.
- Enqueuer thread does not check this condition again, instead setting
the atomic variable to indicate that it is not running. It exits into
an event loop sleep.
- Main thread exits async_enqueue. The calling audio enqueuing system
(see e.g. Piano, but all of them function similarly) will wait until
the enqueuer thread has played enough samples before async_enqueue is
called again. However, since the enqueuer thread will never play any
audio, this condition is never fulfilled and audio playback deadlocks
This commit fixes that by allowing the event loop to not enqueue an
event that already exists, therefore overloading the audio enqueuer
event loop by at maximum one message in weird situations. We entirely
get rid of the atomic variable and the race condition is prevented.
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.
The main event loop functionality was used in just two places where the
alternative is a bit simpler. Remove it in favor of referencing the
event loop directly, or just invoking `EventLoop::current()`.
Note that we don't need locking in the constructor since we're now only
modifying a thread-local `Vector`. We also don't need locking in the
old call sites to `::with_main_locked()` since we already lock the
event loop in the subsequent `::post_event()` invocation.
For now, EventLoop and Application still have a make_inspectable
parameter, so that when working on an application you can temporarily
hard-code it to be inspectable rather than having to set the env var
each time.
A mistake I've repeatedly made is along these lines:
```c++
auto nread = TRY(source_file->read(buffer));
TRY(destination_file->write(buffer));
```
It's a little clunky to have to create a Bytes or StringView from the
buffer's data pointer and the nread, and easy to forget and just use
the buffer. So, this patch changes the read() function to return a
Bytes of the data that were just read.
The other read_foo() methods will be modified in the same way in
subsequent commits.
Fixes#13687