freebsd_network: Handle published conditions with timeout 0.
Previously, since we passed B_RELATIVE_TIMEOUT unconditionally, a timeout of 0 would mean that it would return as soon as there was CPU time available (so, usually, instantly.) This usually was not a "problem" in that it caused broken behavior, but it would result in exceptionally high CPU usage. At first I implemented this correctly (i.e. a timeout of 0 will block until explicitly woken up) but then discovered that our implementation of these functions creates subtle race conditions compared to their FreeBSD counterparts, and so to avoid deadlocks, a timeout of 1 second is imposed. For situations where there are deadlocks due to race conditions, this will make them painfully obvious (e.g. all network transfers stalling for a second every 2-3 seconds or so.)
This commit is contained in:
parent
a029a69c55
commit
81acff62c6
@ -64,9 +64,14 @@ int
|
||||
publishedConditionTimedWait(const void* waitChannel, const int timeout)
|
||||
{
|
||||
ConditionVariableEntry variableEntry;
|
||||
bigtime_t usecs = ticks_to_usecs(timeout);
|
||||
|
||||
// FreeBSD has a condition-variable scheduling system with different
|
||||
// scheduling semantics than ours does. As a result, it seems there are
|
||||
// some scenarios which work fine under FreeBSD but race into a deadlock
|
||||
// on Haiku. To avoid this, turn unlimited timeouts into 1sec ones.
|
||||
status_t status = variableEntry.Wait(waitChannel, B_RELATIVE_TIMEOUT,
|
||||
ticks_to_usecs(timeout));
|
||||
usecs > 0 ? usecs : 1000 * 1000);
|
||||
|
||||
if (status != B_OK)
|
||||
status = EWOULDBLOCK;
|
||||
|
Loading…
Reference in New Issue
Block a user