SDHotSwapModule/source/main.cpp

111 lines
2.8 KiB
C++
Raw Normal View History

2022-03-04 00:59:38 +01:00
#include "exports.h"
#include "logger.h"
#include "sdcard.h"
#include "version.h"
2022-03-04 00:59:38 +01:00
#include <condition_variable>
#include <coreinit/cache.h>
#include <coreinit/filesystem.h>
#include <coreinit/thread.h>
#include <mutex>
#include <sdutils/sdutils.h>
#include <thread>
#include <wums.h>
WUMS_MODULE_EXPORT_NAME("homebrew_sdhotswap");
WUMS_MODULE_SKIP_INIT_FINI();
// This NEEDS to be on the heap. Global DTOR are never called for modules
// but we need a fresh instance of this condition_variable on each app change.
std::condition_variable *cv = nullptr;
std::mutex *cv_m = nullptr;
std::thread *mountThread = nullptr;
bool sStopThread = false;
bool sIsSDInsertedAndMounted = false;
2023-07-19 18:48:22 +02:00
#define MODULE_VERSION "v0.1.1"
#define MODULE_VERSION_FULL MODULE_VERSION MODULE_VERSION_EXTRA
2022-03-04 00:59:38 +01:00
int mount_thread() {
std::unique_lock<std::mutex> lk(*cv_m);
// Wait until the main thread has checked the sd status once.
cv->wait(lk);
while (!sStopThread) {
auto newStatus = IsSDCardInserted();
if (newStatus != sIsSDInsertedAndMounted) {
if (newStatus) {
if (MountSDCard()) {
callAttachCallbacks(SDUTILS_ATTACH_MOUNTED);
sIsSDInsertedAndMounted = true;
}
} else {
if (UnmountSDCard()) {
callAttachCallbacks(SDUTILS_ATTACH_UNMOUNTED);
sIsSDInsertedAndMounted = false;
}
}
OSMemoryBarrier();
}
OSSleepTicks(OSMillisecondsToTicks(100));
}
return 0;
}
WUMS_APPLICATION_STARTS() {
OSReport("Running SDHotSwapModule " MODULE_VERSION_FULL "\n");
2022-03-04 00:59:38 +01:00
initLogging();
sStopThread = false;
cv = new std::condition_variable;
cv_m = new std::mutex;
OSMemoryBarrier();
mountThread = new std::thread(mount_thread);
auto nativeHandle = (OSThread *) mountThread->native_handle();
OSSetThreadName(nativeHandle, "SDHotSwapModuleThread");
while (!OSSetThreadAffinity(nativeHandle, OS_THREAD_ATTRIB_AFFINITY_CPU2)) {
OSSleepTicks(OSMillisecondsToTicks(16));
}
auto check = InitialSDCheck();
if (check < 0) {
// On error stop thread.
sStopThread = true;
} else {
// Otherwise it retuns the current status.
sIsSDInsertedAndMounted = check == 1;
}
OSMemoryBarrier();
2022-05-09 20:05:22 +02:00
DEBUG_FUNCTION_LINE_VERBOSE("Wake up the thread");
2022-03-04 00:59:38 +01:00
// Now we can wake up the thread!
cv->notify_all();
}
WUMS_APPLICATION_ENDS() {
sStopThread = true;
OSMemoryBarrier();
cv->notify_all();
if (mountThread != nullptr) {
mountThread->join();
delete mountThread;
mountThread = nullptr;
}
DeInitSDCheck();
delete cv;
delete cv_m;
cv = nullptr;
cv_m = nullptr;
OSMemoryBarrier();
deinitLogging();
}