Since wait_for_objects can wait on sems, threads and ports in addition
to FDs, limiting to RLIMIT_NOFILES as in the select/poll case does not
work. Since space is allocated for the wait objects in kernel memory,
limiting their number to a valid range is still desireable.
The limit is now placed at the sum of max sem, thread and port count
plus RLIMIT_NOFILES.
This also fixes a signed vs. unsigned comparison warning in
check_max_fds introduced in hrev51866.
It was limited to a uint32 and could for example be overflown by the
slab MemoryManager that uses size_t on a 64 bit system.
This aligns the signature with create_area() that already uses size_t
for the size argument.
Note that the function is currently private, so the impact should be
limited.
The scheduler uses the load tracking logic to compute the load of
threads to be enqueued into the run queue. The time delta between the
last enqueue and the next enqueue may grow very large for threads
that mostly wait on conditions. In such cases the int "n" period count
variable would become too small and wrap around, leading to an
assertion failure.
For this to happen, the thread in question would have to have slept for
at least ~25 days and then wake up. Threads often affected would be ones
waiting for some other process to end, for example shell threads waiting
for a long running process to exit.
Fixes#13558.
Previously dead teams were always returned (as needed for wait/waitpid).
Using waitid it should however be possible to omit the WEXITED flag to
only get stopped (WUNTRACED | WSTOPPED) or continued (WCONTINUED) teams.
Adjust the other caller of the _kern_wait_for_child syscall, used by the
various less specific wait* functions, to always include WEXITED. This
avoids having to special case waitid in the syscall interface or with an
extra flag.
Add a check to ensure that any of these flags is set to avoid the now
possible case of nothing being specified. This fails with B_BAD_VALUE
(EINVAL) as on other systems.
On other systems their values are usually aliased. We defined them as
two different values, but didn't handle WSTOPPED anywhere. The check
is now simply extended to cover both bits.
When wait_for_child was called with a child argument equal to the
current team, the team was locked again to check if it was a child of
itself.
This is now handled the same way as on other systems, where this case
results in ECHILD (and not EINVAL).
It is implemented using websockets and canvas darwing. It directly
speaks the remote desktop protocol. A websocket proxy that translates
the TCP connection into a usable form is needed. Websockify works for
this out of the box directly under Haiku.
Note that not all drawing modes are implemented, and most of them don't
have a good match on the canvas side. Fonts are also not properly
supported yet. A sans serif font will be used on the client for
everything and the metrics between the client and server will diverge
and cause drawing artifacts.
Usage:
* Run an application with a target screen to create the desktop:
TARGET_SCREEN=5001 Terminal
* Use a websocket proxy to expose the port via websockets:
websockify.py 5000 localhost:5001
* Open HaikuRemoteDesktop.html in a browser and connect.
To get the full desktop experience you may want to run Tracker and
Deskbar inside the virtual desktop. As they are both single launch
and controlled by the launch_daemon, you have to stop them via:
launch_roster stop x-vnd.be-trak
launch_roster stop x-vnd.be-tskb
And then start them manually from within the virtual desktop:
/system/Tracker &
/system/Deskbar &
The ScreenOwner interface gets an additional ScreenChanged() hook. It
is implemented in the Desktop class to automatically set the preferred
screen mode on the changed screen.
The HWInterfaceListener, previously only used by the downstream
DrawingEngine, gets an additional ScreenChanged() hook as well to inform
an upstream client of a changed screen.
The ScreenManager ties these two mechanisms together.
Instead of the server connecting back to a listening client, make it
into a more traditional setup with the server listening on a port and
the client connecting to it.
The client can now either connect directly, unencrypted and without the
ability to trigger listening and specifying a command, or through SSH,
as before with the possibilty to run a target application and causing
the creation of the listener.
With the direction change, there's only the need for one, local, port
forward with SSH, which simplifies things.
Renaming of the temporary repo file failed when used with a relative
target path. The path was appended twice in such a case. Also when
used with a specified base directory, the relative temporary repo file
wasn't reachable from the changed working directory.
To fix both cases, create the BEntry pointing at the temporary repo
file before changing the directory and rename it using only the target
leaf name.
The SpinLocker was always initialized to fThread->time_lock even though
fThread may be NULL. This looks like a simple oversight as the rest of
the method handles fThread being NULL and the team variants of these
timers have very similar logic and do the NULL check as well.
This fixes the last remaining KDL in the posixtestsuite.
According to the FreeBSD kernel malloc man page the allocator is
expected to return power of two aligned addresses for allocations up to
one page size. While it also states that this shouldn't be relied upon,
at least our (directly copied) bus_dmamem_alloc expects it and drivers
may depend on it as well. Looking through the FreeBSD commit logs, this
expectation seems to be rooted quite deeply.
This fixes watchdog timeouts in the ipro1000 driver under KVM and may
help with #11953. It might also be related to #9099 and #9601 as those
seem memory allocation related as well.
* Use print format macros to fix the 64 bit build.
* Correct a typo in the shift of the trigger mode definition. As the
value is 0 either way, this does not make a functional difference.
* Use macros instead of values in comparisons.
This allows usb_ecm to work in case it is part of a device using
different configurations for different types of interfaces and ECM is
not the first configuration.
While the USB descriptors are specifically built in such a way that it's
always possible to correctly query the max packet size, some devices
unfortunatley use bogus values in their descriptors and rely on the
stack to use the mandated values.
This fixes USB devices in VirtualBox when EHCI emulation is used. This
really is a bug in their descriptor emulation though.
Don't initialize the current qtd field with the terminate bit as it does
not exist in this field. While the lower 5 bits are documented as being
ignored anyway, this is more correct. Should cause no functional change.
The heap implementation of the runtime_loader was switched to the one
of the bootloader in 6f0994d but was since updated independently.
To keep the diff between the two implementations as small as possible,
the bootloader implementation was first copied to the runtime_loader
and then some features not relevant in the runtime_loader (like the
special large allocation handling) have been removed and the
runtime_loader specific features (grow_heap, add_area) have been
reintegrated. But basically this applies 96689a5..HEAD of
src/system/boot/loader/heap.cpp to the runtime_loader heap.
This brings in the switch from a linked list to a splay tree based
free chunk management. Since the allocation counts in the runtime_loader
are rather small, this does not perceptibly affect performance in either
direction though.
The needed storage space for tracking the allocation size was not
accounted for when growing the heap. Since the growth size is always
rounded up to a multiple of 32KiB, this did almost never matter as the
new allocation wouldn't need the full size. If the allocation did
happen to need the full size however, the newly added area would always
be too small. As the allocation attempt was simply restarted after each
successful growth, this lead to an endless loop creating small new
areas, which would then quickly starve the system for memory.
The int32 was cast to a ssize_t which has a different size on 64 bit,
therefore clobbering the stack.
Also remove the use of basic type references in arguments, which
probably was the reason for doing the above in the first place.
The cleanup commit df48d3f9a8 broke
constructing a BPicture from an archive due to an incomplete rename.
The passed in BMessage was used as the data buffer instead of the
extracted data field.
Fixes the application side crash of #12340. Seeing how long this was
broken without anyone noticing, the feature doesn't seem to be very
popular.
This introduces a more sane API (currently private) that allows for
safer and possibly more efficient implementations:
* It uses a struct of named and typed function pointers instead of just
a void pointer array. This adds type safety to the callbacks so the
compiler can figure out if things match up before subtle bugs get
introduced.
* It provides bounds for all strings/buffers passed to the callbacks.
* It uses const references instead of implicitly copying arguments.
* It folds stroke_x/fill_x pairs into draw_x functions with a fill
argument to reduce the amount of functions needed.
* It uses unsigned values where negative values make no sense.
The old API has been implemented on top of the new one using adapter
functions. It makes copies of all data passed to the callbacks which
effectively keeps the picture data from being modified. This matches
with the R5 behaviour.
This also reimplements the buffer parsing to be safe against corrupted
data by validating that the types actually fit in the provided sizes
and buffers (using a templated reader).
Since this class is used from the app_server with user provided data,
making it more safe is important even though it comes with a slight
overhead (replicating R5 behaviour, i.e. crashing the app_server when
corrupted data is fed, doesn't seem very appropriate here).
It's a 32 bit register which needs properly aligned 32 bit writes. Using
a bit field does not guarantee that, so replace it with shifts and
masks. Should fix#12338.
It waits for the message port of each application to become available
using waitfor and then waits for the application to actually reply
using hey. This establishes the criterion of the boot process being
complete as "all servers (and Tracker & Deskbar) are started and
respond to messages".
This can be used by scripts to do verious performance measurements.
Specifically it can be used to measure the boot time since it represents
the uptime.
A KMessage request always needs to be honoured, regardless of the data
size.
KMessage does not currently protect against messages that are too large,
but this needs to be solved in KMessage when it becomes a problem.
Long application signatures and paths could previously take up too much
space, causing the buttons to be cut off or become completely invisible.
Actually fixes#11367.
The application is now launched suspended and the ports are created
and transferred to the launched team before its main thread is
resumed.
The ports are therefore owned by the launched team instead of the
launch_daemon. This is important when sending messages by area, as
the port owner is used to determine where the data area needs to be
transferred to. This commit therefore fixes#12285.
Note that it is still possible to get at the ports with find_port()
while they are still owned by the launch_daemon. This should not be a
problem however, as these ports are not supposed to be found this way
but only through BLaunchRoster::GetData(), which is synchronized with
the above process.
Creating the ports in the launch_daemon still has the benefit of
returning valid communication ports earlier, i.e. without having to
wait for the launched application to actually become ready.
It allows to launch the app, but keep its main thread suspended instead
of automatically resuming it.
Also add appThread argument which allows to retrieve the main thread of
the launched team.
Previously the LaunchDaemon would send out its own team id when a given
job was not yet launched, leading to invalid BMessengers once the port
owner changed to the actually launched team.
The launch of the target team and the launch data replies were also not
synchronized, which could lead to the launched team getting a reply
pointing to the launch_daemon when requesting data for itself. This is
the case for the BRoster init of the registrar. The fix in hrev49561
therefore didn't always work, because the registrar would sometimes get
the launch_daemon team id instead of the id of itself. It would later
try talking to the launch_daemon, which obviously never replied, leading
to #12237.
The LaunchDaemon now delegates the launch data reply to the Job instead.
The Job either replies directly, in case it has already been launched,
or queues the reply for when the launch completes. This causes launch
data requesters to block until the launch attempt is completed, but
won't block the LaunchDaemon message loop.
This commit introduces the seperate fLaunchStatus to properly handle the
ambiguity of fTeam being < 0, which is the case for both, when no launch
was attempted and when the launch failed. This new field now determines
what IsLaunched() returns and how launch data replies are handled.
The new launch status is additionally protected by the launch status
lock, which will later probably be made broader in scope to protect
against race conditions once service monitoring is implemented.
The extra quotes aren't needed and cause problems when not parsed
through a shell. For example LD_PRELOAD which is handled by the
runtime_loader directly failed to work as there was no way to remove
the extra single quotes.
Note that quotes and single quotes can still be added to the variables
through respective quoting in the driver settings syntax.
Previously the thread member was overwritten with the freeing thread
when a page was freed, leading to confusion when hitting unallocated
pages due to the debugger message still stating "allocated by thread".
Track the freeing thread separately as it might be interesting to know
both, which thread initially allocated and which thread eventually freed
an allocation.
When the MimeUpdateThread is done, it marks itself as finished and
notifies the thread manager to clean up finished threads. Since multiple
such threads might finish at the same time and trigger the cleanup
notification, other threads that already marked themselves finished but
haven't actually exited yet might already be deleted and removed. This
would then lead to a use-after-free when they subsequently tried to send
their own cleanup message.
To solve the race condition, the thread manager will now wait for the
thread to actually exit before cleaning it up.
The introduction of the launch_daemon has made this race condition more
likely due to more applications starting in parallel, each triggering a
CreateAppMetaMimeThread which is a subclass of MimeUpdateThread. This
commit might therefore fix#12237.
The environment variables were always added to the static environment
list instead of the one supplied as argument. This worked for targets,
as there the scripts are evaluated before the static environment is
used. For services and jobs this isn't the case, causing sourced
environment variables to be missing.
BApplication::_InitData() already avoided the use of BRoster from the
registrar (and launch_daemon) where it isn't available. Since
create_app_meta_mime() indirectly just sends a message to the registrar
using BRoster, it too cannot work when the registrar isn't available.
This fixes a regression introduced in 9bfc833, where the old way of
getting the roster port was replaced with its launch_daemon counterpart.
The previous method of finding the roster did always fail when running
from the registrar, as at the time of initialization (initialize_before
of libbe) the registrar looper doesn't exist yet. This commit restores
the previous behaviour by checking if the returned registrar team is the
current team and avoiding initialization in that case.
The regression caused a 5 second boot delay when later BApplication
initialization of the registrar tried to communicate with itself with a
reply timeout of that length.
Fixes#12258 at least partially and might affect #12237.
This was missed when introducing the feature in hrev49558. Thanks Jérôme
for the pointer!
Also add a note explaining that update operations on cached entries and
the removal of uncached entries are safe.
These are always allocated using an area. The allocation size is
increased as to guarantee the availability of a suitable address. The
pages between the allocation info and the actual, aligned start address
and the pages past the allocation end are then protected.
This commit also fixes corruption of the allocation info for large
allocations that used areas. The alignment wasn't taken into account
when calculating the amount of space needed. The alignment could then
lead to rounding down the allocation start such that it would overlap
with the allocation info.
It provides a way for filesystems to cache a lookup failure and
therefore prevents repeated lookups of missing entries. This is a
common scenario for example in command lookup and compiling, where
each directory in PATH or each include directory is searched for the
given entry.
The individual debug heap implementations are now exposed via a
structure of function pointers and a common frontend dispatches the
malloc and malloc_debug APIs through them.
The MALLOC_DEBUG environment variable can be used to select the guarded
heap by adding 'g', otherwise the debug heap is used as the default.
Consequently the separate libroot_guarded is not needed anymore and has
been removed.
To allow the use of environment variables this early, init_env_post_heap
has been added and the heap dependent atfork() moved there. This allowed
to fold the code of init_heap_post_env into init_heap so the former has
been removed.
If the view fails to lock because it is actually gone, we obviously
can't use it to return the container, so delete it directly in that
case.
Fixes#12072 and probably #11982 which would then be a duplicate.
TCPEndpoint::Free() uses _EnterTimeWait() to start the time-wait timer
for later cleanup. The latter did call _CancelConnectionTimers()
unconditionally however, also cancelling a retransmit timer that was
possibly still needed for the retransmission of the FIN packet. If the
FIN packet got lost, the connection would be left open on the other end.
The APICall trace entry just records the function name but this is
enough to deduce where some of the state changes come from.
Also move the TRACE macros past the MutexLockers to ensure that their
output happens at the time when the methods actually run.
The retransmit timer was only stopped when all in flight data was
acknowledged and never updated on individual acknowledgements. This
caused a lot of erroneous retransmits whenever the buffer was filled
fast enough so that the acknowledgements never caught up, i.e. whenever
uploading or streaming data.
Move setting of the initial retransmit timer inside the send loop so it
is closer to the actual time the segment is sent out and simplify the
logic a bit.
Limit the minimal retransmit timeout to 200 msecs to avoid spurious
retransmit in the face of delayed acknowledgements. This is lower than
the 1 second minimum the RFCs suggest. Other stacks use various other
sub-second timeouts, the 200 msecs follows what Linux does.
Also add the exponential back off of the retransmit timeout when
retransmits are triggered. This is bounded by a 60 seconds maximum
according to RFC6298.
The WaitList implementation had a race condition between checking for
the condition and acquiering the semaphore. If a thread was rescheduled
at that point, the signal could be missed due to the use of
release_sem_etc() with the B_RELEASE_ALL flag while the thread was not
yet waiting for the semaphore. The transfer would subsequently stall.
The removal of the vnode happens later than the actual unlink. As part
of the unlink, the vnode cache is already updated to mark the unlinked
directory invalid. This means its entry in the directory list needs to
be removed as well. Otherwise, if a directory list entry is looked up
in the time between unlink and remove_vnode, the assertion which checks
the validity of the directory list entries would fail.