/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: AuNetInterface.cpp Date: 2022-8-16 Author: Reece ***/ #include "Networking.hpp" #include "AuNetInterface.hpp" #include "AuNetWorker.hpp" namespace Aurora::IO::Net { NetInterface::NetInterface() : netServiceResolve_(this), netServiceSockets_(this), netServiceDatagram_(this) { } #define NET_INTERFACE_ADD_SERVICE(type, selfHosted, pOverload) \ AU_LOCK_GUARD(this->mutex_); \ \ if (this->pOverload) \ { \ return this->pOverload; \ } \ else \ { \ return AuSPtr(AuSharedFromThis(), &this->selfHosted); \ } AuSPtr NetInterface::GetWorkersService() { NET_INTERFACE_ADD_SERVICE(INetSrvWorkers, netServiceWorkers_, pNetServiceOverloadWorkers_); } AuSPtr NetInterface::GetResolveService() { NET_INTERFACE_ADD_SERVICE(INetSrvResolve, netServiceResolve_, pNetServiceOverloadResolve_); } AuSPtr NetInterface::GetSocketService() { NET_INTERFACE_ADD_SERVICE(INetSrvSockets, netServiceSockets_, pNetServiceOverloadSockets_); } AuSPtr NetInterface::GetDatagramService() { NET_INTERFACE_ADD_SERVICE(INetSrvDatagram, netServiceDatagram_, pNetServiceOverloadDatagram_); } AuSPtr NetInterface::GetInterfacesService() { AU_LOCK_GUARD(this->mutex_); if (this->pNetServiceOverloadNetworkInterfaces_) { return this->pNetServiceOverloadNetworkInterfaces_; } if (!this->netServiceInterfaces_.IsSupportedOnOS()) { return {}; } return AuSPtr(AuSharedFromThis(), &this->netServiceInterfaces_); } void NetInterface::SetWorkersService(const AuSPtr &pWorkers) { AU_LOCK_GUARD(this->mutex_); this->pNetServiceOverloadWorkers_ = pWorkers; } void NetInterface::SetResolveService(const AuSPtr &pResolve) { AU_LOCK_GUARD(this->mutex_); this->pNetServiceOverloadResolve_ = pResolve; } void NetInterface::SetSocketService(const AuSPtr &pSockets) { AU_LOCK_GUARD(this->mutex_); this->pNetServiceOverloadSockets_ = pSockets; } void NetInterface::SetDatagramService(const AuSPtr &pDatagrams) { AU_LOCK_GUARD(this->mutex_); this->pNetServiceOverloadDatagram_ = pDatagrams; } void NetInterface::SetInterfacesService(const AuSPtr &pNetworkInterfaces) { AU_LOCK_GUARD(this->mutex_); this->pNetServiceOverloadNetworkInterfaces_ = pNetworkInterfaces; } bool NetInterface::TrySchedule(const AuSPtr &pWorkUnit) { auto workerId = AuAtomicAdd(&this->atomicCounter_, 1u) - 1u; auto worker = this->netServiceWorkers_.GetWorkerByIndex(workerId); if (!worker) { SysPushErrorIO("No Worker"); return {}; } return worker->ToProcessor()->SubmitIOWorkItem(pWorkUnit); } AuSPtr NetInterface::TryScheduleEx() { AuSPtr worker; do { worker = this->netServiceWorkers_.GetWorkerByIndex(AuAtomicAdd(&this->atomicCounter_, 1u) - 1u); } while (!worker); return worker; } void NetInterface::Shutdown() { } void NetInterface::Destroy() { } AUKN_SYM AuSPtr NewNetworkInterface() { if (!IsNetReady()) { SysPushErrorNet("Platform network service isn't available"); return {}; } auto iface = AuMakeShared(); if (!iface) { return iface; } // TODO: ... return iface; } }