Skip to content

Commit

Permalink
Update core loading on android
Browse files Browse the repository at this point in the history
Use mkstemps to crete an unique path for the core to be copied to and keep its file descriptor around for the whole lifetime of the object opened by dlopen
  • Loading branch information
edo9300 committed Aug 24, 2021
1 parent 2c2595a commit 7cd8546
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 16 deletions.
56 changes: 45 additions & 11 deletions gframe/dllinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@
#elif defined(EDOPRO_MACOS)
#define CORENAME EPRO_TEXT("libocgcore.dylib")
#elif defined(__ANDROID__)
#include <fcntl.h> //open()
#include <unistd.h> //close()
struct AndroidCore {
void* library;
int fd;
};
#if defined(__arm__)
#define CORENAME EPRO_TEXT("libocgcorev7.so")
#elif defined(__i386__)
Expand Down Expand Up @@ -45,26 +51,54 @@
#undef CREATE_CLONE

#ifdef _WIN32
inline void* OpenLibrary(epro::path_stringview path) {
static inline void* OpenLibrary(epro::path_stringview path) {
return LoadLibrary(fmt::format("{}" CORENAME, path).data());
}
#define CloseLibrary(core) FreeLibrary((HMODULE)core)

#define GetFunction(core, x) (decltype(x))GetProcAddress((HMODULE)core, #x)

#else
#elif defined(__ANDROID__)

inline void* OpenLibrary(epro::path_stringview path) {
#ifdef __ANDROID__
static void* OpenLibrary(epro::path_stringview path) {
void* lib = nullptr;
const auto dest_dir = porting::internal_storage + "/libocgcore.so";
ygo::Utils::FileCopy(fmt::format("{}" CORENAME, path), dest_dir);
lib = dlopen(dest_dir.data(), RTLD_LAZY);
ygo::Utils::FileDelete(dest_dir);
return lib;
auto dest_path = porting::internal_storage + "/libocgcoreXXXXXX.so";
auto output = mkstemps(&dest_path[0], 3);
if(output == -1)
return nullptr;
auto input = open(fmt::format("{}" CORENAME, path).data(), O_RDONLY);
if(input == -1) {
unlink(dest_path.data());
close(output);
return nullptr;
}
ygo::Utils::FileCopyFD(input, output);
lib = dlopen(dest_path.data(), RTLD_NOW);
unlink(dest_path.data());
if(!lib) {
close(output);
return nullptr;
}
close(input);
auto core = new AndroidCore;
core->library = lib;
core->fd = output;
return core;
}

static inline void CloseLibrary(void* core) {
AndroidCore* acore = static_cast<AndroidCore*>(core);
dlclose(acore->library);
close(acore->fd);
delete acore;
}

#define GetFunction(core, x) (decltype(x))dlsym(static_cast<AndroidCore*>(core)->library, #x)

#else
return dlopen(fmt::format("{}" CORENAME, path).data(), RTLD_LAZY);
#endif

static inline void* OpenLibrary(epro::path_stringview path) {
return dlopen(fmt::format("{}" CORENAME, path).data(), RTLD_NOW);
}

#define CloseLibrary(core) dlclose(core)
Expand Down
16 changes: 11 additions & 5 deletions gframe/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,15 @@ namespace ygo {
return mkdir(path.data(), 0777) == 0 || errno == EEXIST;
#endif
}
#ifdef __linux__
bool Utils::FileCopyFD(int source, int destination) {
off_t bytesCopied = 0;
struct stat fileinfo = { 0 };
fstat(source, &fileinfo);
int result = sendfile(destination, source, &bytesCopied, fileinfo.st_size);
return result != -1;
}
#endif
bool Utils::FileCopy(epro::path_stringview source, epro::path_stringview destination) {
if(source == destination)
return false;
Expand All @@ -110,13 +119,10 @@ namespace ygo {
close(input);
return false;
}
off_t bytesCopied = 0;
struct stat fileinfo = { 0 };
fstat(input, &fileinfo);
int result = sendfile(output, input, &bytesCopied, fileinfo.st_size);
auto result = FileCopyFD(output, input);
close(input);
close(output);
return result != -1;
return result;
#elif defined(__APPLE__)
return copyfile(source.data(), destination.data(), 0, COPYFILE_ALL) == 0;
#else
Expand Down
3 changes: 3 additions & 0 deletions gframe/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ namespace ygo {
static irr::IOSOperator* OSOperator;
static epro::path_string working_dir;
static bool MakeDirectory(epro::path_stringview path);
#ifdef __linux__
static bool FileCopyFD(int source, int destination);
#endif
static bool FileCopy(epro::path_stringview source, epro::path_stringview destination);
static bool FileMove(epro::path_stringview source, epro::path_stringview destination);
static bool FileExists(epro::path_stringview path);
Expand Down

0 comments on commit 7cd8546

Please sign in to comment.