Threaded apps are starting to work.
This commit is contained in:
parent
f28bbd476e
commit
9caff407f4
2 changed files with 99 additions and 49 deletions
112
roo_e/main.c
112
roo_e/main.c
|
|
@ -26,7 +26,10 @@
|
|||
#include "roo_e.h"
|
||||
|
||||
|
||||
static RooNamedPointerT **_appList = NULL; // NOLINT
|
||||
static RooAppThreadT **_appThreadList = NULL; // NOLINT
|
||||
|
||||
|
||||
static void *rooStartAppThread(void *arg);
|
||||
|
||||
|
||||
#ifdef PLATFORM_DOS
|
||||
|
|
@ -120,37 +123,56 @@ static int lastResort(void) {
|
|||
#endif // PLATFORM_DOS
|
||||
|
||||
|
||||
int rooStartApp(const char *appName, const int argc, char *argv[], RooNamedPointerT **handle) {
|
||||
RooNamedPointerT *namedPointer = NULL;
|
||||
int result = -1;
|
||||
RooAppThreadT *rooStartApp(const char *appName, const int argc, char *argv[]) {
|
||||
RooAppThreadT *appThread = NULL;
|
||||
|
||||
dlerror(); // Clear any existing error.
|
||||
NEW(RooAppThreadT, appThread);
|
||||
NEW(RooNamedPointerT, appThread->namedPointer);
|
||||
appThread->namedPointer->name = utilCreateString("app/%s.app", appName);
|
||||
appThread->namedPointer->pointer = dlopen(appThread->namedPointer->name, RTLD_LAZY);
|
||||
if (!appThread->namedPointer->pointer) {
|
||||
printf("ROO/E: Unable to load %s! %s\n", appThread->namedPointer->name, dlerror());
|
||||
DEL(appThread->namedPointer->name);
|
||||
DEL(appThread->namedPointer);
|
||||
DEL(appThread);
|
||||
} else {
|
||||
appThread->argc = argc;
|
||||
//***TODO*** argv handling is a bit sketchy. We should deep copy this.
|
||||
appThread->argv = argv;
|
||||
appThread->result = -1;
|
||||
pthread_create(&appThread->thread, NULL, rooStartAppThread, (void *)appThread);
|
||||
arrput(_appThreadList, appThread);
|
||||
}
|
||||
|
||||
return appThread;
|
||||
}
|
||||
|
||||
|
||||
static void *rooStartAppThread(void *arg) {
|
||||
int (*appMain)(const int argc, char *argv[]); // NOLINT
|
||||
RooAppThreadT *appThread = (RooAppThreadT *)arg;
|
||||
|
||||
union {
|
||||
void *from;
|
||||
int (*to)(const int argc, char *argv[]);
|
||||
} appPtrCast; // NOLINT
|
||||
|
||||
dlerror(); // Clear any existing error.
|
||||
NEW(RooNamedPointerT, namedPointer);
|
||||
namedPointer->name = utilCreateString("app/%s.app", appName);
|
||||
namedPointer->pointer = dlopen(namedPointer->name, RTLD_LAZY);
|
||||
if (!namedPointer->pointer) {
|
||||
printf("ROO/E: Unable to load %s! %s\n", namedPointer->name, dlerror());
|
||||
} else {
|
||||
appPtrCast.from = dlsym(namedPointer->pointer, "_appMain");
|
||||
appThread->running = true;
|
||||
appPtrCast.from = dlsym(appThread->namedPointer->pointer, "_appMain");
|
||||
appMain = appPtrCast.to; // NOLINT
|
||||
result = appMain(argc, argv);
|
||||
arrput(_appList, namedPointer);
|
||||
if (handle != NULL) *handle = namedPointer->pointer;
|
||||
}
|
||||
debug("ROO/E: Calling appMain.\n");
|
||||
appThread->result = appMain(appThread->argc, appThread->argv);
|
||||
debug("ROO/E: Back from appMain.\n");
|
||||
appThread->running = false;
|
||||
|
||||
return result;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
RooAbortReasonT rooStopApp(RooNamedPointerT **appHandle, RooStopReasonT reason) {
|
||||
RooAbortReasonT rooStopApp(RooAppThreadT **threadPointer, RooStopReasonT reason) {
|
||||
RooAbortReasonT abort = ROO_ABORT_NONE;
|
||||
RooNamedPointerT *namedPointer = NULL;
|
||||
RooAppThreadT *appThread = NULL;
|
||||
int (*appStop)(RooStopReasonT reason);
|
||||
|
||||
union {
|
||||
|
|
@ -158,18 +180,13 @@ RooAbortReasonT rooStopApp(RooNamedPointerT **appHandle, RooStopReasonT reason)
|
|||
int (*to)(RooStopReasonT reason);
|
||||
} appPtrCast; // NOLINT
|
||||
|
||||
namedPointer = *appHandle;
|
||||
appThread = *threadPointer;
|
||||
|
||||
appPtrCast.from = dlsym(namedPointer->pointer, "_appStop");
|
||||
appPtrCast.from = dlsym(appThread->namedPointer->pointer, "_appStop");
|
||||
if (appPtrCast.from != NULL) {
|
||||
appStop = appPtrCast.to; // NOLINT
|
||||
abort = appStop(reason);
|
||||
}
|
||||
if (abort == ROO_ABORT_NONE) {
|
||||
dlclose(namedPointer->pointer);
|
||||
DEL(namedPointer->name);
|
||||
DEL(namedPointer);
|
||||
}
|
||||
|
||||
return abort;
|
||||
}
|
||||
|
|
@ -179,10 +196,12 @@ int main(const int argc, char *argv[]) {
|
|||
|
||||
DIR *dir = NULL;
|
||||
struct dirent *dirent = NULL;
|
||||
int result;
|
||||
RooAbortReasonT abort;
|
||||
RooAppThreadT *appThread = NULL;;
|
||||
RooNamedPointerT **dynList = NULL;
|
||||
RooNamedPointerT *namedPointer = NULL;
|
||||
int result;
|
||||
// RooAbortReasonT abort;
|
||||
int x;
|
||||
int (*dynInitStop)(void);
|
||||
|
||||
union {
|
||||
|
|
@ -237,24 +256,45 @@ int main(const int argc, char *argv[]) {
|
|||
debug("ROO/E: Loaded %d libraries.\n", arrlen(dynList));
|
||||
|
||||
// Load the Shell. This needs to be configurable.
|
||||
result = rooStartApp("kpsmpgc", 0, NULL, NULL);
|
||||
rooStartApp("kpsmpgc", 0, NULL);
|
||||
|
||||
// Run as long as apps are running.
|
||||
while (arrlen(_appList) > 0) {
|
||||
while (arrlen(_appThreadList) > 0) {
|
||||
// Wait for all apps to exit.
|
||||
for (x=0; x<arrlen(_appThreadList); x++) {
|
||||
appThread = _appThreadList[x]; // NOLINT
|
||||
debug("ROO/E: App %d of %d running == %d\n", x, arrlen(_appThreadList), (int)appThread->running);
|
||||
if (appThread->running == false) {
|
||||
debug("ROO/E: Joining.\n");
|
||||
pthread_join(appThread->thread, NULL);
|
||||
debug("ROO/E: Joined.\n");
|
||||
dlclose(appThread->namedPointer->pointer);
|
||||
debug("ROO/E: %s exited.\n", appThread->namedPointer->name);
|
||||
DEL(appThread->namedPointer->name);
|
||||
DEL(appThread->namedPointer);
|
||||
//***TODO*** Deal with argv cleanup here?
|
||||
DEL(appThread);
|
||||
//***TODO*** We need some way to deal with return values and checking if apps are alive.
|
||||
arrdel(_appThreadList, x);
|
||||
// Exit loop after changing array length.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// Unload APPs.
|
||||
while (arrlen(_appList) > 0) {
|
||||
namedPointer = _appList[0]; // NOLINT
|
||||
debug("ROO/E: Stopping %s\n", namedPointer->name);
|
||||
abort = rooStopApp(&namedPointer, ROO_STOP_SHUTDOWN);
|
||||
while (arrlen(_appThreadList) > 0) {
|
||||
appThread = _appThreadList[0]; // NOLINT
|
||||
debug("ROO/E: Stopping %s\n", appThread->namedPointer->name);
|
||||
abort = rooStopApp(&appThread, ROO_STOP_SHUTDOWN);
|
||||
if (abort == ROO_ABORT_NONE) {
|
||||
arrdel(_appList, 0);
|
||||
arrdel(_appThreadList, 0);
|
||||
} else {
|
||||
break; // Somebody didn't want to stop.
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Unload DYNs
|
||||
debug("ROO/E: Unloading %d libraries.\n", arrlen(dynList));
|
||||
|
|
|
|||
|
|
@ -51,6 +51,16 @@ typedef struct RooNamedPointerS {
|
|||
void *pointer;
|
||||
} RooNamedPointerT;
|
||||
|
||||
typedef struct RooAppThreadS {
|
||||
pthread_t thread;
|
||||
volatile bool running;
|
||||
int argc;
|
||||
char **argv;
|
||||
int result;
|
||||
RooNamedPointerT *namedPointer;
|
||||
} RooAppThreadT;
|
||||
|
||||
|
||||
typedef enum {
|
||||
ROO_STOP_EXITING = 0, // App quit
|
||||
ROO_STOP_SHUTDOWN, // Roo/E shutdown
|
||||
|
|
@ -64,8 +74,8 @@ typedef enum {
|
|||
} RooAbortReasonT;
|
||||
|
||||
|
||||
int rooStartApp(const char *appName, int argc, char *argv[], RooNamedPointerT **handle);
|
||||
RooAbortReasonT rooStopApp(RooNamedPointerT **appHandle, RooStopReasonT reason);
|
||||
RooAppThreadT *rooStartApp(const char *appName, int argc, char *argv[]);
|
||||
RooAbortReasonT rooStopApp(RooAppThreadT **threadPointer, RooStopReasonT reason);
|
||||
|
||||
|
||||
#endif // ROO_E_H
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue