mirror of
https://github.com/microsoft/WSL.git
synced 2026-02-04 02:06:49 -06:00
* link: Collect WSL logs (recommended method) Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * link: Advanced Authoring Tests in C++ Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * link: CMake Documentation and Community Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * link: Collect WSL logs for networking issues Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * link: Collect WSL logs (recommended method) Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: ; otherwise, Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: a Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: access Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: accessible Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: across Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: actively Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: adapters Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: address Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: addresses Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: and Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: appropriate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: argument Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: associated Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: attach Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: available Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: beginning Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: between Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: binaries Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: bound Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: buffer Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: buffers Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: cannot Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: canonical Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: capabilities Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: case-insensitive Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: case-sensitive Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: certified Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: command Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: committer Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: communication Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: complains Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: configuration Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: consumed Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: continue Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: converted Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: currently Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: customers Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: daemon Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: deferred Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: definitions Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: delimiter Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: delivered Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: dellink Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: derived Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: descriptor Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: destined Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: destruct Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: destructible Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: destructor Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: detach Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: differentiate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: directories Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: disassociate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: disposition Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: distribution Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: distro Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: duping Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: emitted Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: empty Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: environment Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: every time Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: exclusive Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: expected Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: expire Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: explicitly Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: fall back Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: false Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: fastfail Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: filesystem Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: first Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: followed Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: for Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: functionality Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: functionally Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: github Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: greater Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: guarantee Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: guaranteed Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: handles Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: hangup Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: hierarchy Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: hogwarts Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: hydrated Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: icrnl Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: implementation Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: implementing Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: initialize Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: instance Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: instantiate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: instantiations Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: intentionally Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: interpret Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: interpreter Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: irreversibly Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: iteration Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: iterator Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: its Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: kernel Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: kmsg Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: knowledge Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: maximum Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: mirrored Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: msftconnecttest Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: multi Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: multiple Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: mutable Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: namespace Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: nonexistent Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: notifications Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: occurred Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: occurring Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: otherwise, Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: outstanding Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: overridden Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: partition Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: pass through Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: passthrough Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: performs Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: periodically Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: positional Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: precedence Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: preexisting Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: preferring Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: prepopulate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: previous Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: privileges Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: process Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: processes Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: programmatically Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: protection Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: provided Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: reasonable Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: receive Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: received Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: red hat Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: reentrant Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: registered Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: regularly Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: relay Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: release Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: representing Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: requests Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: response Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: resurrect Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: retention Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: returned Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: security Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: semaphore Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: separate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: separator Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: service Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: set up Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: setup Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: severely Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: should Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: signal Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: similarly Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: simple Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: simplified Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: single Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: specified Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: splitting Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: standard Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: stress Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: succeed Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: success Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: successfully Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: supplementary Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: synced Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: system Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: take Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: than Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: that opening Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: the Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: threadpool Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: to Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: true Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: truncate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: tunneling Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: unexpected Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: uninitialize Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: unique Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: unprivileged Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: unregistered Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: untrusted Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: upgrade Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: utility Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: validating Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: variant Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: variation Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: variations Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: verify Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: visible Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: whether Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: winget Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: worker Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: written Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: wslservice Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * format source --------- Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> Co-authored-by: Ben Hillis <benhillis@gmail.com> Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
297 lines
8.2 KiB
C++
297 lines
8.2 KiB
C++
// Copyright (C) Microsoft Corporation. All rights reserved.
|
|
#include "precomp.h"
|
|
#include "p9io.h"
|
|
|
|
#ifndef TEMP_FAILURE_RETRY
|
|
#define TEMP_FAILURE_RETRY(expression) \
|
|
(__extension__({ \
|
|
long int __result; \
|
|
do \
|
|
__result = (long int)(expression); \
|
|
while (__result == -1L && errno == EINTR); \
|
|
__result; \
|
|
}))
|
|
#endif
|
|
|
|
namespace p9fs {
|
|
|
|
EpollWatcher g_Watcher;
|
|
|
|
CoroutineIoIssuer::CoroutineIoIssuer(int fd) : m_FileDescriptor(fd)
|
|
{
|
|
}
|
|
|
|
void CoroutineIoIssuer::Callback(sigval value)
|
|
{
|
|
const auto operation = static_cast<CoroutineIoOperation*>(value.sival_ptr);
|
|
auto bytesTransferred = aio_return(&operation->ControlBlock);
|
|
int error = 0;
|
|
if (bytesTransferred < 0)
|
|
{
|
|
error = aio_error(&operation->ControlBlock);
|
|
}
|
|
|
|
operation->Result = {error, static_cast<size_t>(bytesTransferred)};
|
|
if (!operation->DoneOrCoroutine.exchange(true))
|
|
{
|
|
return;
|
|
}
|
|
|
|
// TODO: Can we use this thread to resume the coroutine?
|
|
g_Scheduler.Schedule(operation->Coroutine);
|
|
}
|
|
|
|
bool CoroutineIoIssuer::PreIssue(CoroutineIoOperation& operation, CancelToken& token)
|
|
{
|
|
// Register the IO for cancellation.
|
|
operation.ControlBlock = {};
|
|
operation.ControlBlock.aio_fildes = m_FileDescriptor;
|
|
operation.ControlBlock.aio_sigevent.sigev_notify = SIGEV_THREAD;
|
|
operation.ControlBlock.aio_sigevent.sigev_notify_function = Callback;
|
|
operation.ControlBlock.aio_sigevent.sigev_value.sival_ptr = &operation;
|
|
if (token.Register(operation))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
// The operation has already been cancelled. Don't even issue the IO.
|
|
operation.Result = {ECANCELED, 0};
|
|
operation.DoneOrCoroutine = true;
|
|
return false;
|
|
}
|
|
|
|
void CoroutineIoIssuer::IssueFailed(CancelToken& token)
|
|
{
|
|
// Unwind the work done in PreIssue.
|
|
token.Unregister();
|
|
}
|
|
|
|
void CoroutineIoIssuer::PostIssue(CoroutineIoOperation& operation, CancelToken& token, IoResult result)
|
|
{
|
|
if (result.Error != 0)
|
|
{
|
|
// The IO completed synchronously.
|
|
operation.Result = result;
|
|
operation.DoneOrCoroutine = true;
|
|
|
|
WI_ASSERT(operation.Coroutine == nullptr);
|
|
}
|
|
else if (token.Cancelled())
|
|
{
|
|
// The IO did not complete synchronously, but the operation has been
|
|
// cancelled. Depending on when the cancel occurred, the IO may not have
|
|
// been cancelled, so cancel it now.
|
|
aio_cancel(operation.ControlBlock.aio_fildes, &operation.ControlBlock);
|
|
}
|
|
}
|
|
|
|
// Register an epoll operation for either an in or an out event.
|
|
// Returns true if the operation must suspend to wait for the event, or false if the operation can
|
|
// resume immediately.
|
|
// N.B. There can be only one operation registered at a time for each event.
|
|
bool EpollDispatcher::Register(int event, CoroutineEpollOperation& operation)
|
|
{
|
|
std::scoped_lock<std::mutex> lock{m_lock};
|
|
if (event == EPOLLIN)
|
|
{
|
|
FAIL_FAST_IF(m_inOperation != nullptr);
|
|
if (WI_IsFlagSet(m_currentEvents, EPOLLIN))
|
|
{
|
|
WI_ClearFlag(m_currentEvents, EPOLLIN);
|
|
|
|
// Since Register is called before the operation is registered for cancellation,
|
|
// it's not possible for this to return false.
|
|
operation.SetResult(0);
|
|
return false;
|
|
}
|
|
|
|
m_inOperation = &operation;
|
|
}
|
|
else
|
|
{
|
|
FAIL_FAST_IF(event != EPOLLOUT);
|
|
FAIL_FAST_IF(m_outOperation != nullptr);
|
|
if (WI_IsFlagSet(m_currentEvents, EPOLLOUT))
|
|
{
|
|
WI_ClearFlag(m_currentEvents, EPOLLOUT);
|
|
operation.SetResult(0);
|
|
return false;
|
|
}
|
|
|
|
m_outOperation = &operation;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// Removes the handler for the specified event (EPOLLIN or EPOLLOUT).
|
|
void EpollDispatcher::Remove(int event)
|
|
{
|
|
std::scoped_lock<std::mutex> lock{m_lock};
|
|
if (event == EPOLLIN)
|
|
{
|
|
m_inOperation = nullptr;
|
|
}
|
|
else
|
|
{
|
|
FAIL_FAST_IF(event != EPOLLOUT);
|
|
m_outOperation = nullptr;
|
|
}
|
|
}
|
|
|
|
// Notifies the dispatcher an event has occurred.
|
|
void EpollDispatcher::Notify(int events)
|
|
{
|
|
std::scoped_lock<std::mutex> lock{m_lock};
|
|
|
|
// Resume the out operation first, since that is responding to an existing message rather than
|
|
// reading the request for a new one.
|
|
if (WI_IsFlagSet(events, EPOLLOUT))
|
|
{
|
|
if (m_outOperation != nullptr)
|
|
{
|
|
m_outOperation->Resume(0);
|
|
m_outOperation = nullptr;
|
|
}
|
|
else
|
|
{
|
|
// If no operation is registered, remember the event occurred for the next time one
|
|
// is registered.
|
|
WI_SetFlag(m_currentEvents, EPOLLOUT);
|
|
}
|
|
}
|
|
|
|
if (WI_IsFlagSet(events, EPOLLIN))
|
|
{
|
|
if (m_inOperation != nullptr)
|
|
{
|
|
m_inOperation->Resume(0);
|
|
m_inOperation = nullptr;
|
|
}
|
|
else
|
|
{
|
|
// If no operation is registered, remember the event occurred for the next time one
|
|
// is registered.
|
|
WI_SetFlag(m_currentEvents, EPOLLIN);
|
|
}
|
|
}
|
|
}
|
|
|
|
void EpollWatcher::Run()
|
|
{
|
|
FAIL_FAST_IF(m_EpollFileDescriptor >= 0);
|
|
|
|
m_EpollFileDescriptor = epoll_create1(EPOLL_CLOEXEC);
|
|
THROW_LAST_ERROR_IF(m_EpollFileDescriptor < 0);
|
|
|
|
std::thread(WatchThread, this).detach();
|
|
}
|
|
|
|
void EpollWatcher::Add(int fd, int events, EpollDispatcher& dispatcher)
|
|
{
|
|
epoll_event event{};
|
|
event.events = events;
|
|
event.data.ptr = &dispatcher;
|
|
THROW_LAST_ERROR_IF(epoll_ctl(m_EpollFileDescriptor, EPOLL_CTL_ADD, fd, &event) < 0);
|
|
}
|
|
|
|
void EpollWatcher::Remove(int fd)
|
|
{
|
|
THROW_LAST_ERROR_IF(epoll_ctl(m_EpollFileDescriptor, EPOLL_CTL_DEL, fd, nullptr) < 0);
|
|
}
|
|
|
|
void EpollWatcher::WatchThread(EpollWatcher* watcher)
|
|
{
|
|
for (;;)
|
|
{
|
|
epoll_event events[10];
|
|
int result = TEMP_FAILURE_RETRY(epoll_wait(watcher->m_EpollFileDescriptor, events, 10, -1));
|
|
THROW_LAST_ERROR_IF(result < 0);
|
|
|
|
for (int i = 0; i < result; ++i)
|
|
{
|
|
if (events[i].data.ptr != nullptr)
|
|
{
|
|
const auto dispatcher = static_cast<EpollDispatcher*>(events[i].data.ptr);
|
|
dispatcher->Notify(events[i].events);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Task<size_t> RecvAsync(CoroutineEpollIssuer& socket, gsl::span<gsl::byte> buffer, CancelToken& token)
|
|
{
|
|
CoroutineEpollOperation operation;
|
|
auto result =
|
|
co_await socket.Issue<ssize_t>(operation, token, EPOLLIN, [&](int fd) { return recv(fd, buffer.data(), buffer.size(), 0); });
|
|
|
|
if (result < 0)
|
|
{
|
|
THROW_ERRNO(-result);
|
|
}
|
|
|
|
co_return static_cast<size_t>(result);
|
|
}
|
|
|
|
Task<size_t> SendAsync(CoroutineEpollIssuer& socket, gsl::span<const gsl::byte> buffer, CancelToken& token)
|
|
{
|
|
CoroutineEpollOperation operation;
|
|
auto result = co_await socket.Issue<ssize_t>(
|
|
operation, token, EPOLLOUT, [&](int fd) { return send(fd, buffer.data(), buffer.size(), 0); });
|
|
|
|
if (result < 0)
|
|
{
|
|
THROW_ERRNO(-result);
|
|
}
|
|
|
|
co_return static_cast<size_t>(result);
|
|
}
|
|
|
|
Task<int> AcceptAsync(CoroutineEpollIssuer& listen, CancelToken& token)
|
|
{
|
|
CoroutineEpollOperation operation;
|
|
auto result = co_await listen.Issue<int>(
|
|
operation, token, EPOLLIN, [&](int fd) { return accept4(fd, nullptr, nullptr, SOCK_NONBLOCK | SOCK_CLOEXEC); });
|
|
|
|
if (result < 0)
|
|
{
|
|
THROW_ERRNO(-result);
|
|
}
|
|
|
|
co_return result;
|
|
}
|
|
|
|
Task<IoResult> ReadAsync(CoroutineIoIssuer& file, std::uint64_t offset, gsl::span<gsl::byte> buffer, CancelToken& token)
|
|
{
|
|
CoroutineIoOperation operation;
|
|
co_return co_await file.Issue(operation, token, [&](aiocb& cb) -> IoResult {
|
|
cb.aio_buf = buffer.data();
|
|
cb.aio_nbytes = buffer.size();
|
|
cb.aio_offset = offset;
|
|
if (aio_read(&cb) < 0)
|
|
{
|
|
return {-errno, 0};
|
|
}
|
|
|
|
return {};
|
|
});
|
|
}
|
|
|
|
Task<IoResult> WriteAsync(CoroutineIoIssuer& file, std::uint64_t offset, gsl::span<const gsl::byte> buffer, CancelToken& token)
|
|
{
|
|
CoroutineIoOperation operation;
|
|
co_return co_await file.Issue(operation, token, [&](aiocb& cb) -> IoResult {
|
|
cb.aio_buf = (volatile void*)buffer.data();
|
|
cb.aio_nbytes = buffer.size();
|
|
cb.aio_offset = offset;
|
|
if (aio_write(&cb) < 0)
|
|
{
|
|
return {errno, 0};
|
|
}
|
|
|
|
return {};
|
|
});
|
|
}
|
|
|
|
} // namespace p9fs
|