mirror of
https://github.com/wiiu-env/ftpiiu_plugin.git
synced 2024-11-04 20:15:09 +01:00
Auto start/stop
More fine-grained locking
This commit is contained in:
parent
b925088965
commit
49b2571336
@ -58,11 +58,11 @@ private:
|
||||
/// \param port_ Port to listen on
|
||||
FtpServer (std::uint16_t port_);
|
||||
|
||||
/// \brief Handle when start button is pressed
|
||||
void handleStartButton ();
|
||||
/// \brief Handle when network is found
|
||||
void handleNetworkFound ();
|
||||
|
||||
/// \brief Handle when stop button is pressed
|
||||
void handleStopButton ();
|
||||
/// \brief Handle when network is lost
|
||||
void handleNetworkLost ();
|
||||
|
||||
/// \brief Server loop
|
||||
void loop ();
|
||||
|
@ -34,6 +34,9 @@ namespace platform
|
||||
/// \brief Initialize platform
|
||||
bool init ();
|
||||
|
||||
/// \brief Whether network is visible
|
||||
bool networkVisible ();
|
||||
|
||||
/// \brief Platform loop
|
||||
bool loop ();
|
||||
|
||||
|
@ -34,10 +34,13 @@
|
||||
|
||||
#include "gfx.h"
|
||||
|
||||
#include <malloc.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
#include <chrono>
|
||||
#include <ctime>
|
||||
#include <malloc.h>
|
||||
#include <mutex>
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -51,9 +54,11 @@ constexpr auto SOCU_BUFFERSIZE = 0x100000;
|
||||
static_assert (SOCU_BUFFERSIZE % SOCU_ALIGN == 0);
|
||||
|
||||
/// \brief Whether soc:u is active
|
||||
bool s_socuActive = false;
|
||||
std::atomic<bool> s_socuActive = false;
|
||||
/// \brief soc:u buffer
|
||||
u32 *s_socuBuffer = nullptr;
|
||||
/// \brief ac:u fence
|
||||
platform::Mutex s_acuFence;
|
||||
|
||||
/// \brief Clear color
|
||||
constexpr auto CLEAR_COLOR = 0x204B7AFF;
|
||||
@ -99,6 +104,20 @@ C3D_Tex s_gfxTexture;
|
||||
/// \brief Texture atlas metadata
|
||||
Tex3DS_Texture s_gfxT3x;
|
||||
|
||||
/// \brief Get network visibility
|
||||
bool getNetworkVisibility ()
|
||||
{
|
||||
// serialize ac:u access from multiple threads
|
||||
auto lock = std::scoped_lock (s_acuFence);
|
||||
|
||||
// get wifi status
|
||||
std::uint32_t wifi = 0;
|
||||
if (R_FAILED (ACU_GetWifiStatus (&wifi)) || !wifi)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// \brief Start network
|
||||
void startNetwork ()
|
||||
{
|
||||
@ -106,9 +125,7 @@ void startNetwork ()
|
||||
if (s_socuActive)
|
||||
return;
|
||||
|
||||
// get wifi status
|
||||
std::uint32_t wifi = 0;
|
||||
if (R_FAILED (ACU_GetWifiStatus (&wifi)) || !wifi)
|
||||
if (!getNetworkVisibility ())
|
||||
return;
|
||||
|
||||
// allocate soc:u buffer
|
||||
@ -302,6 +319,15 @@ bool platform::init ()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool platform::networkVisible ()
|
||||
{
|
||||
// check if soc:u is active
|
||||
if (!s_socuActive)
|
||||
return false;
|
||||
|
||||
return getNetworkVisibility ();
|
||||
}
|
||||
|
||||
bool platform::loop ()
|
||||
{
|
||||
if (!aptMainLoop ())
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "ftpServer.h"
|
||||
|
||||
#include "fs.h"
|
||||
#include "platform.h"
|
||||
|
||||
#include "imgui.h"
|
||||
|
||||
@ -35,6 +36,13 @@
|
||||
#include <thread>
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
#define LOCKED(x) \
|
||||
do \
|
||||
{ \
|
||||
auto const lock = std::scoped_lock (m_lock); \
|
||||
x; \
|
||||
} while (0)
|
||||
|
||||
namespace
|
||||
{
|
||||
/// \brief Application start time
|
||||
@ -60,8 +68,6 @@ FtpServer::FtpServer (std::uint16_t const port_)
|
||||
{
|
||||
Log::bind (m_log);
|
||||
|
||||
handleStartButton ();
|
||||
|
||||
m_thread = platform::Thread (std::bind (&FtpServer::threadFunc, this));
|
||||
}
|
||||
|
||||
@ -78,27 +84,11 @@ void FtpServer::draw ()
|
||||
#else
|
||||
ImGui::SetNextWindowSize (ImVec2 (width, height));
|
||||
#endif
|
||||
ImGui::SetNextWindowFocus ();
|
||||
ImGui::Begin (STATUS_STRING,
|
||||
nullptr,
|
||||
ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize);
|
||||
|
||||
{
|
||||
auto const lock = std::scoped_lock (m_lock);
|
||||
if (!m_socket)
|
||||
{
|
||||
if (ImGui::Button ("Start"))
|
||||
handleStartButton ();
|
||||
}
|
||||
else if (ImGui::Button ("Stop"))
|
||||
handleStopButton ();
|
||||
|
||||
if (m_socket)
|
||||
{
|
||||
ImGui::SameLine ();
|
||||
ImGui::TextUnformatted (m_name.c_str ());
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto const lock = std::scoped_lock (s_lock);
|
||||
if (!s_freeSpace.empty ())
|
||||
@ -108,6 +98,15 @@ void FtpServer::draw ()
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
ImGui::SameLine ();
|
||||
auto const lock = std::scoped_lock (m_lock);
|
||||
if (m_socket)
|
||||
ImGui::TextUnformatted (m_name.c_str ());
|
||||
else
|
||||
ImGui::TextUnformatted ("Waiting for network...");
|
||||
}
|
||||
|
||||
ImGui::Separator ();
|
||||
|
||||
#ifdef _3DS
|
||||
@ -132,8 +131,11 @@ void FtpServer::draw ()
|
||||
ImGui::Separator ();
|
||||
#endif
|
||||
|
||||
for (auto &session : m_sessions)
|
||||
session->draw ();
|
||||
{
|
||||
auto lock = std::scoped_lock (m_lock);
|
||||
for (auto &session : m_sessions)
|
||||
session->draw ();
|
||||
}
|
||||
|
||||
ImGui::End ();
|
||||
}
|
||||
@ -161,10 +163,13 @@ std::time_t FtpServer::startTime ()
|
||||
return s_startTime;
|
||||
}
|
||||
|
||||
void FtpServer::handleStartButton ()
|
||||
void FtpServer::handleNetworkFound ()
|
||||
{
|
||||
if (m_socket)
|
||||
return;
|
||||
{
|
||||
auto lock = std::scoped_lock (m_lock);
|
||||
if (m_socket)
|
||||
return;
|
||||
}
|
||||
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
@ -196,49 +201,66 @@ void FtpServer::handleStartButton ()
|
||||
|
||||
Log::info ("Started server at %s\n", m_name.c_str ());
|
||||
|
||||
m_socket = std::move (socket);
|
||||
LOCKED (m_socket = std::move (socket));
|
||||
}
|
||||
|
||||
void FtpServer::handleStopButton ()
|
||||
void FtpServer::handleNetworkLost ()
|
||||
{
|
||||
m_socket.reset ();
|
||||
{
|
||||
UniqueSocket sock;
|
||||
LOCKED (sock = std::move (m_socket));
|
||||
}
|
||||
|
||||
Log::info ("Stopped server at %s\n", m_name.c_str ());
|
||||
}
|
||||
|
||||
void FtpServer::loop ()
|
||||
{
|
||||
if (platform::networkVisible ())
|
||||
handleNetworkFound ();
|
||||
|
||||
// poll listen socket
|
||||
if (m_socket)
|
||||
{
|
||||
// poll listen socket
|
||||
auto const lock = std::scoped_lock (m_lock);
|
||||
if (m_socket)
|
||||
Socket::PollInfo info{*m_socket, POLLIN, 0};
|
||||
if (Socket::poll (&info, 1, 0ms) > 0)
|
||||
{
|
||||
Socket::PollInfo info{*m_socket, POLLIN, 0};
|
||||
if (Socket::poll (&info, 1, 0ms) > 0)
|
||||
auto socket = m_socket->accept ();
|
||||
if (socket)
|
||||
{
|
||||
auto socket = m_socket->accept ();
|
||||
if (socket)
|
||||
m_sessions.emplace_back (FtpSession::create (std::move (socket)));
|
||||
else
|
||||
handleStopButton ();
|
||||
auto session = FtpSession::create (std::move (socket));
|
||||
LOCKED (m_sessions.emplace_back (std::move (session)));
|
||||
}
|
||||
else
|
||||
handleNetworkLost ();
|
||||
}
|
||||
}
|
||||
|
||||
// remove dead sessions
|
||||
for (auto it = std::begin (m_sessions); it != std::end (m_sessions);)
|
||||
{
|
||||
auto const &session = *it;
|
||||
if (session->dead ())
|
||||
it = m_sessions.erase (it);
|
||||
else
|
||||
++it;
|
||||
std::vector<UniqueFtpSession> deadSessions;
|
||||
{
|
||||
// remove dead sessions
|
||||
auto lock = std::scoped_lock (m_lock);
|
||||
auto it = std::begin (m_sessions);
|
||||
while (it != std::end (m_sessions))
|
||||
{
|
||||
auto &session = *it;
|
||||
if (session->dead ())
|
||||
{
|
||||
deadSessions.emplace_back (std::move (session));
|
||||
it = m_sessions.erase (it);
|
||||
}
|
||||
else
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// poll sessions
|
||||
if (!m_sessions.empty ())
|
||||
{
|
||||
if (!FtpSession::poll (m_sessions))
|
||||
handleStopButton ();
|
||||
handleNetworkLost ();
|
||||
}
|
||||
// avoid busy polling in background thread
|
||||
else
|
||||
|
@ -162,6 +162,11 @@ bool platform::init ()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool platform::networkVisible ()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool platform::loop ()
|
||||
{
|
||||
bool inactive;
|
||||
|
@ -40,6 +40,17 @@ bool platform::init ()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool platform::networkVisible ()
|
||||
{
|
||||
NifmInternetConnectionType type;
|
||||
std::uint32_t wifi;
|
||||
NifmInternetConnectionStatus status;
|
||||
if (R_FAILED (nifmGetInternetConnectionStatus (&type, &wifi, &status)))
|
||||
return false;
|
||||
|
||||
return status == NifmInternetConnectionStatus_Connected;
|
||||
}
|
||||
|
||||
bool platform::loop ()
|
||||
{
|
||||
if (!appletMainLoop ())
|
||||
|
Loading…
Reference in New Issue
Block a user