Improve error handling

Signed-off-by: Mahyar Koshkouei <deltabeard@users.noreply.github.com>
This commit is contained in:
Mahyar Koshkouei
2017-02-12 23:07:36 +00:00
parent 3878bf4e23
commit 984192eebe
5 changed files with 116 additions and 30 deletions

View File

@@ -1,5 +1,15 @@
#include <3ds.h>
/* Errors that can't be explained with errno */
#define NDSP_INIT_FAIL 1000
#define DECODER_INIT_FAIL 1001
#define FILE_NOT_SUPPORTED 1002
struct errInfo_t
{
volatile int* error;
Handle* failEvent;
volatile char* errstr;
};
char* ctrmus_strerror(int err);

View File

@@ -16,9 +16,12 @@
#include <unistd.h>
#include "all.h"
#include "error.h"
#include "main.h"
#include "playback.h"
volatile bool runThreads = true;
int main(int argc, char **argv)
{
PrintConsole topScreen;
@@ -26,6 +29,12 @@ int main(int argc, char **argv)
int fileMax;
int fileNum = 0;
int from = 0;
Thread watchdogThread;
Handle* playbackFailEvent = malloc(sizeof(Handle));
struct watchdogInfo* watchdogInfoIn;
struct errInfo_t* errInfo;
static volatile int error;
static volatile char* errorstr = NULL;
gfxInitDefault();
sdmcInit();
@@ -33,6 +42,17 @@ int main(int argc, char **argv)
consoleInit(GFX_BOTTOM, &bottomScreen);
consoleSelect(&bottomScreen);
svcCreateEvent(playbackFailEvent, RESET_ONESHOT);
watchdogInfoIn = calloc(1, sizeof(struct watchdogInfo));
errInfo = calloc(1, sizeof(struct errInfo_t));
errInfo->error = &error;
errInfo->failEvent = playbackFailEvent;
errInfo->errstr = errorstr;
watchdogInfoIn->screen = &topScreen;
watchdogInfoIn->errInfo = errInfo;
watchdogThread = threadCreate(playbackWatchdog, watchdogInfoIn, 4 * 1024, 0x20, -2, true);
printf("%p", playbackFailEvent);
chdir(DEFAULT_DIR);
chdir("MUSIC");
if(listDir(from, MAX_LIST, 0) < 0)
@@ -66,6 +86,8 @@ int main(int argc, char **argv)
kDown = hidKeysDown();
kHeld = hidKeysHeld();
consoleSelect(&bottomScreen);
/* Exit ctrmus */
if(kDown & KEY_START)
break;
@@ -92,25 +114,26 @@ int main(int argc, char **argv)
else
puts("Playing");
consoleSelect(&bottomScreen);
continue;
}
/* Show controls */
else if(kDown & KEY_LEFT)
if(kDown & KEY_LEFT)
{
consoleSelect(&topScreen);
showControls();
consoleSelect(&bottomScreen);
continue;
}
}
/* Stop */
if(kDown & KEY_X)
{
stopPlayback();
changeFile(NULL);
continue;
/* Stop */
if(kDown & KEY_B)
{
stopPlayback();
changeFile(NULL, NULL, NULL);
consoleSelect(&topScreen);
puts("Stopped");
continue;
}
}
if((kDown & KEY_UP ||
@@ -196,7 +219,7 @@ int main(int argc, char **argv)
}
consoleSelect(&topScreen);
changeFile(ep->d_name);
changeFile(ep->d_name, &error, playbackFailEvent);
consoleSelect(&bottomScreen);
if(closedir(dp) != 0)
@@ -214,8 +237,9 @@ int main(int argc, char **argv)
out:
puts("Exiting...");
runThreads = false;
stopPlayback();
changeFile(NULL);
changeFile(NULL, NULL, NULL);
gfxExit();
sdmcExit();
@@ -242,17 +266,46 @@ static void showControls(void)
{
printf("Button mappings:\n"
"Pause: L+R or L+Up\n"
"Stop: X\n"
"Stop: L+B\n"
"A: Open File\n"
"B: Go up folder\n"
"Start: Exit\n");
}
static int changeFile(const char* ep_file)
void playbackWatchdog(void* infoIn)
{
struct watchdogInfo* info = infoIn;
while(runThreads)
{
svcWaitSynchronization(*info->errInfo->failEvent, U64_MAX);
svcClearEvent(*info->errInfo->failEvent);
consoleSelect(info->screen);
printf("Here %s:%d err:%d\n", __func__, __LINE__, *info->errInfo->error);
#if 0
if(*info->error != 0)
{
printf("An error occurred: %s", ctrmus_strerror(*info->error));
if(info->str != NULL)
printf(" %s", info->str);
printf("\n");
info->str = NULL;
}
#endif
}
return;
}
static int changeFile(const char* ep_file, volatile int* error, Handle* failEvent)
{
s32 prio;
static Thread thread = NULL;
static char* file = NULL;
static struct playbackInfo* info = NULL;
if(info == NULL)
info = calloc(1, sizeof(struct playbackInfo));
if(ep_file != NULL && getFileType(ep_file) < 0)
{
@@ -274,18 +327,19 @@ static int changeFile(const char* ep_file)
thread = NULL;
/* free allocated file string */
delete(file);
delete(info->file);
}
if(ep_file == NULL)
return 0;
file = strdup(ep_file);
printf("Playing: %s\n", file);
info->file = strdup(ep_file);
info->errInfo->error = error;
info->errInfo->failEvent = failEvent;
printf("Playing: %s\n", info->file);
svcGetThreadPriority(&prio, CUR_THREAD_HANDLE);
thread = threadCreate(playFile, file, 32 * 1024, prio - 1,
-2, false);
thread = threadCreate(playFile, info, 32 * 1024, prio - 1, -2, false);
return 0;
}

View File

@@ -13,9 +13,17 @@
/* Maximum number of lines that can be displayed */
#define MAX_LIST 27
struct watchdogInfo
{
PrintConsole* screen;
struct errInfo_t* errInfo;
};
void playbackWatchdog(void* infoIn);
static void showControls(void);
static int changeFile(const char* ep_file);
static int changeFile(const char* ep_file, volatile int* error, Handle* failEvent);
/**
* Get number of files in current working folder

View File

@@ -10,21 +10,25 @@
#include "playback.h"
#include "wav.h"
volatile bool stop = false;
static volatile bool stop = false;
/**
* Should only be called from a new thread only.
*/
void playFile(void* fileIn)
void playFile(void* infoIn)
{
struct decoder_fn decoder;
struct playbackInfo* info = infoIn;
int16_t* buffer1 = NULL;
int16_t* buffer2 = NULL;
ndspWaveBuf waveBuf[2];
bool lastbuf = false;
int ret = -1;
const char* file = fileIn;
const char* file = info->file;
//info->str = strdup("Testing.");
errno = 12;
goto err;
/* Reset previous stop command */
stop = false;
@@ -47,20 +51,19 @@ void playFile(void* fileIn)
break;
default:
threadExit(0);
return;
goto err;
}
if(R_FAILED(ndspInit()))
{
errno = NDSP_INIT_FAIL;
goto out;
goto err;
}
if((ret = (*decoder.init)(file)) != 0)
{
errno = DECODER_INIT_FAIL;
goto out;
goto err;
}
buffer1 = linearAlloc(decoder.buffSize * sizeof(int16_t));
@@ -140,14 +143,19 @@ void playFile(void* fileIn)
DSP_FlushDataCache(buffer2, decoder.buffSize * sizeof(int16_t));
}
out:
(*decoder.exit)();
out:
ndspChnWaveBufClear(CHANNEL);
ndspExit();
linearFree(buffer1);
linearFree(buffer2);
threadExit(0);
return;
err:
*info->errInfo->error = errno;
svcSignalEvent(*info->errInfo->failEvent);
goto out;
}
/**

View File

@@ -8,7 +8,13 @@ enum file_types
FILE_TYPE_MP3
};
void playFile(void* fileIn);
struct playbackInfo
{
char* file;
struct errInfo_t* errInfo;
};
void playFile(void* infoIn);
/**
* Pause or play current file.