Fix 3DS multithreading

This commit is contained in:
Michael Theall 2020-04-06 21:17:30 -05:00
parent 2da46d407f
commit e8b62be621
7 changed files with 29 additions and 54 deletions

View File

@ -52,7 +52,7 @@ public:
/// \brief Poll for activity
/// \param sessions_ Sessions to poll
static void poll (std::vector<UniqueFtpSession> const &sessions_);
static bool poll (std::vector<UniqueFtpSession> const &sessions_);
private:
/// \brief Command buffer size

View File

@ -82,7 +82,7 @@ public:
/// \brief Parameterized constructor
/// \param func_ Thread entrypoint
Thread (std::function<void ()> func_);
Thread (std::function<void ()> &&func_);
Thread (Thread const &that_) = delete;

View File

@ -282,7 +282,8 @@ void platform::exit ()
imgui::citro3d::exit ();
imgui::ctru::exit ();
socExit ();
if (s_socuActive)
socExit ();
s_socuActive = false;
std::free (s_socuBuffer);
@ -304,7 +305,7 @@ public:
/// \brief Parameterized constructor
/// \param func_ Thread entry point
privateData_t (std::function<void ()> func_) : thread (nullptr)
privateData_t (std::function<void ()> &&func_) : thread (nullptr), func (std::move (func_))
{
s32 priority = 0x30;
svcGetThreadPriority (&priority, CUR_THREAD_HANDLE);
@ -335,7 +336,8 @@ platform::Thread::Thread () : m_d (new privateData_t ())
{
}
platform::Thread::Thread (std::function<void ()> func_) : m_d (new privateData_t (func_))
platform::Thread::Thread (std::function<void ()> &&func_)
: m_d (new privateData_t (std::move (func_)))
{
}

View File

@ -35,13 +35,6 @@
#include <thread>
using namespace std::chrono_literals;
#ifndef _3DS
/// \todo Investigate multithreading on 3DS
#define MULTITHREADED 1
#else
#define MULTITHREADED 0
#endif
namespace
{
/// \brief Application start time
@ -57,11 +50,9 @@ std::string s_freeSpace;
///////////////////////////////////////////////////////////////////////////
FtpServer::~FtpServer ()
{
#if MULTITHREADED
m_quit = true;
m_thread.join ();
#endif
}
FtpServer::FtpServer (std::uint16_t const port_)
@ -71,17 +62,11 @@ FtpServer::FtpServer (std::uint16_t const port_)
handleStartButton ();
#if MULTITHREADED
m_thread = platform::Thread (std::bind (&FtpServer::threadFunc, this));
#endif
}
void FtpServer::draw ()
{
#if !MULTITHREADED
loop ();
#endif
ImGuiIO &io = ImGui::GetIO ();
auto const width = io.DisplaySize.x;
auto const height = io.DisplaySize.y;
@ -233,6 +218,8 @@ void FtpServer::loop ()
auto socket = m_socket->accept ();
if (socket)
m_sessions.emplace_back (FtpSession::create (std::move (socket)));
else
handleStopButton ();
}
}
}
@ -249,12 +236,13 @@ void FtpServer::loop ()
// poll sessions
if (!m_sessions.empty ())
FtpSession::poll (m_sessions);
#if MULTITHREADED
{
if (!FtpSession::poll (m_sessions))
handleStopButton ();
}
// avoid busy polling in background thread
else
platform::Thread::sleep (16ms);
#endif
}
void FtpServer::threadFunc ()

View File

@ -359,26 +359,8 @@ UniqueFtpSession FtpSession::create (UniqueSocket commandSocket_)
return UniqueFtpSession (new FtpSession (std::move (commandSocket_)));
}
void FtpSession::poll (std::vector<UniqueFtpSession> const &sessions_)
bool FtpSession::poll (std::vector<UniqueFtpSession> const &sessions_)
{
#if 0
auto const printEvents = [] (int const events_) {
std::string out;
if (events_ & POLLIN)
out += "[IN]";
if (events_ & POLLPRI)
out += "[PRI]";
if (events_ & POLLOUT)
out += "[OUT]";
if (events_ & POLLHUP)
out += "[HUP]";
if (events_ & POLLERR)
out += "[ERR]";
return out;
};
#endif
// poll for pending close sockets first
std::vector<Socket::PollInfo> info;
for (auto &session : sessions_)
@ -395,7 +377,10 @@ void FtpSession::poll (std::vector<UniqueFtpSession> const &sessions_)
{
auto const rc = Socket::poll (info.data (), info.size (), 0ms);
if (rc < 0)
{
Log::error ("poll: %s\n", std::strerror (errno));
return false;
}
else
{
for (auto const &i : info)
@ -472,22 +457,18 @@ void FtpSession::poll (std::vector<UniqueFtpSession> const &sessions_)
}
if (info.empty ())
return;
return true;
// poll for activity
#if MULTITHREADED
// poll for activity
auto const rc = Socket::poll (info.data (), info.size (), 16ms);
#else
auto const rc = Socket::poll (info.data (), info.size (), 0ms);
#endif
if (rc < 0)
{
Log::error ("poll: %s\n", std::strerror (errno));
return;
return false;
}
if (rc == 0)
return;
return true;
for (auto &session : sessions_)
{
@ -568,6 +549,8 @@ void FtpSession::poll (std::vector<UniqueFtpSession> const &sessions_)
}
}
}
return true;
}
void FtpSession::setState (State const state_, bool const closePasv_, bool const closeData_)

View File

@ -207,7 +207,7 @@ public:
/// \brief Parameterized constructor
/// \param func_ Thread entry point
privateData_t (std::function<void ()> func_) : thread (func_)
privateData_t (std::function<void ()> &&func_) : thread (std::move (func_))
{
}
@ -222,7 +222,8 @@ platform::Thread::Thread () : m_d (new privateData_t ())
{
}
platform::Thread::Thread (std::function<void ()> func_) : m_d (new privateData_t (func_))
platform::Thread::Thread (std::function<void ()> &&func_)
: m_d (new privateData_t (std::move (func_)))
{
}

View File

@ -82,7 +82,7 @@ public:
/// \brief Parameterized constructor
/// \param func_ Thread entry point
privateData_t (std::function<void ()> func_) : thread (func_)
privateData_t (std::function<void ()> &&func_) : thread (std::move (func_))
{
}
@ -97,7 +97,8 @@ platform::Thread::Thread () : m_d (new privateData_t ())
{
}
platform::Thread::Thread (std::function<void ()> func_) : m_d (new privateData_t (func_))
platform::Thread::Thread (std::function<void ()> &&func_)
: m_d (new privateData_t (std::move (func_)))
{
}