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