This fixes the following build warnings in a mingw environment:
../../lldb/source/Host/windows/MainLoopWindows.cpp:226:50: warning:
format specifies type 'int' but the argument has type
'IOObject::WaitableHandle' (aka 'void *') [-Wformat]
226 | "File descriptor %d already monitored.", waitable_handle);
| ~~ ^~~~~~~~~~~~~~~
../../lldb/source/Host/windows/MainLoopWindows.cpp:239:49: warning:
format specifies type 'int' but the argument has type 'DWORD' (aka
'unsigned long') [-Wformat]
238 | error = Status::FromErrorStringWithFormat("Unsupported file type
%d",
| ~~
| %lu
239 | file_type);
| ^~~~~~~~~
2 warnings generated.
I wasn't able to build lldb using Mingw-w64 on Windows without changing
these 3 lines. It seems like `std::atomic<bool>` wasn't being found
without `#include <atomic>` and `ceil` was defaulting to `std::ceil`
instead of `std::chrono::ceil`, but I'm not smart enough to know the
root cause. I'm sure I'm not the first people to try and compile lldb
(and clang and lld) with Mingw-w64 and I don't know if something is
wrong with my Mingw-w64, but my changes shouldn't have any affect if
they aren't needed.
This should improve synchronizing the MainLoopWindows monitor thread
with the main loop state.
This uses the `m_ready` and `m_event` event handles to manage when the
Monitor thread continues and adds new tests to cover additional use
cases.
I believe this should fix#147291 but it is hard to ensure a race
condition is fixed without running the CI on multiple
machines/configurations.
---------
Co-authored-by: Pavel Labath <pavel@labath.sk>
As seen on Linaro's Windows on Arm bot.
C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\source\Host\windows\MainLoopWindows.cpp(80,25): warning: missing field 'InternalHigh' initializer [-Wmissing-field-initializers]
80 | OVERLAPPED ov = {0};
| ^
C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\source\Host\windows\MainLoopWindows.cpp(135,8): warning: 'WillPoll' overrides a member function but is not marked 'override' [-Winconsistent-missing-override]
135 | void WillPoll() {
| ^
C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\include\lldb/Host/windows/MainLoopWindows.h(40,18): note: overridden virtual function is here
40 | virtual void WillPoll() {}
| ^
C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\source\Host\windows\MainLoopWindows.cpp(142,8): warning: 'DidPoll' overrides a member function but is not marked 'override' [-Winconsistent-missing-override]
142 | void DidPoll() {
| ^
C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\include\lldb/Host/windows/MainLoopWindows.h(41,18): note: overridden virtual function is here
41 | virtual void DidPoll() {}
| ^
C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\source\Host\windows\MainLoopWindows.cpp(80,25): warning: missing field 'InternalHigh' initializer [-Wmissing-field-initializers]
80 | OVERLAPPED ov = {0};
| ^
Commit 1a7b7e24bcc1041ae0fb90abcfb73d36d76f4a07 introduced a few casting
warnings and a build issue in Win32 platforms.
Trying to correct the casts to c++ style casts instead of C style casts.
This updates MainLoopWindows to support events for reading from a pipe
(both anonymous and named pipes) as well as sockets.
This unifies both handle types using `WSAWaitForMultipleEvents` which
can listen to both sockets and handles for change events.
This should allow us to unify how we handle watching pipes/sockets on
Windows and Posix systems.
We can extend this in the future if we want to support watching other
types, like files or even other events like a process life time.
---------
Co-authored-by: Pavel Labath <pavel@labath.sk>
The motivating use case is being able to "time out" certain operations
(by adding a timed callback which will force the termination of the
loop), but the design is flexible enough to accomodate other use cases
as well (e.g. running a periodic task in the background).
The implementation builds on the existing "pending callback" mechanism,
by associating a time point with each callback -- every time the loop
wakes up, it runs all of the callbacks which are past their point, and
it also makes sure to sleep only until the next callback is scheduled to
run.
I've done some renaming as names like "TriggerPendingCallbacks" were no
longer accurate -- the function may no longer cause any callbacks to be
called (it may just cause the main loop thread to recalculate the time
it wants to sleep).
This behavior made sense in the beginning as the class was completely
single threaded, so if the source count ever reached zero, there was no
way to add new ones. In https://reviews.llvm.org/D131160, the class
gained the ability to add events (callbacks) from other threads, which
means that is no longer the case (and indeed, one possible use case for
this class -- acting as a sort of arbiter for multiple threads wanting
to run code while making sure it runs serially -- has this class sit in
an empty Run call most of the time). I'm not aware of us having a use
for such a thing right now, but one of my tests in another patch turned
into something similar by accident.
Another problem with the current approach is that, in a
distributed/dynamic setup (multiple things using the main loop without a
clear coordinator), one can never be sure whether unregistering a
specific event will terminate the loop (it depends on whether there are
other listeners). We had this problem in lldb-platform.cpp, where we had
to add an additional layer of synchronization to avoid premature
termination. We can remove this if we can rely on the loop terminating
only when we tell it to.
This patch removes all of the Set.* methods from Status.
This cleanup is part of a series of patches that make it harder use the
anti-pattern of keeping a long-lives Status object around and updating
it while dropping any errors it contains on the floor.
This patch is largely NFC, the more interesting next steps this enables
is to:
1. remove Status.Clear()
2. assert that Status::operator=() never overwrites an error
3. remove Status::operator=()
Note that step (2) will bring 90% of the benefits for users, and step
(3) will dramatically clean up the error handling code in various
places. In the end my goal is to convert all APIs that are of the form
` ResultTy DoFoo(Status& error)
`
to
` llvm::Expected<ResultTy> DoFoo()
`
How to read this patch?
The interesting changes are in Status.h and Status.cpp, all other
changes are mostly
` perl -pi -e 's/\.SetErrorString/ = Status::FromErrorString/g' $(git
grep -l SetErrorString lldb/source)
`
plus the occasional manual cleanup.
This will be used as a replacement for selecting over a pipe fd, which
does not work on windows. The posix implementation still uses a pipe
under the hood, while the windows version uses windows event handles.
The idea is that, instead of writing to a pipe, one just inserts a
callback, which does whatever you wanted to do after the bytes come out
the read end of the pipe.
Differential Revision: https://reviews.llvm.org/D131160
This patch switches the MainLoop class to use the WSAEventSelect
mechanism to wait for multiple sockets to become readable. The
motivation for doing that is that this allows us to wait for other kinds
of events as well (as long as they can be converted to WSAEvents). This
will allow us to avoid (abstract away) pipe-based multiplexing
mechanisms in the generic code, since pipes cannot be combined with
sockets on windows.
Since the windows implementation will now look completely different than
the posix (file descriptor-based) implementations, I have split the
MainLoop class into two (MainLoopPosix and MainLoopWindows), with the
common code going into MainLoopBase.
Differential Revision: https://reviews.llvm.org/D131159