Browse Source

fix mod dynlib lifetime issues

opengl-renderer-broken
Martin Dørum 4 years ago
parent
commit
a4652732ab
5 changed files with 28 additions and 6 deletions
  1. 8
    1
      libswan/include/swan/Mod.h
  2. 2
    0
      libswan/include/swan/OS.h
  3. 2
    3
      libswan/src/Game.cc
  4. 8
    0
      libswan/src/Mod.cc
  5. 8
    2
      libswan/src/OS.cc

+ 8
- 1
libswan/include/swan/Mod.h View File

@@ -11,13 +11,19 @@
#include "WorldGen.h"
#include "Entity.h"
#include "Resource.h"
#include "OS.h"
#include "util.h"

namespace Swan {

class Mod {
public:
Mod(const std::string &path): path_(path) {}
Mod(const std::string &path, OS::Dynlib &&dynlib):
path_(path), dynlib_(std::move(dynlib)) {}

// We have to manually ensure anything created from the dynlib
// is destructed before the dynlib itself is destructed
~Mod();

void init(const std::string &name);

@@ -43,6 +49,7 @@ private:
std::vector<std::unique_ptr<Entity::Factory>> entities_;

std::string path_;
OS::Dynlib dynlib_;
bool inited_ = false;
};


+ 2
- 0
libswan/include/swan/OS.h View File

@@ -12,6 +12,8 @@ bool isTTY(FILE *f);
class Dynlib {
public:
Dynlib(const std::string &path);
Dynlib(const Dynlib &) = delete;
Dynlib(Dynlib &&dl);
~Dynlib();

template<typename T> T get(const std::string &name) { return (T)getVoid(name); }

+ 2
- 3
libswan/src/Game.cc View File

@@ -13,14 +13,13 @@ namespace Swan {

std::unique_ptr<Mod> Game::loadMod(const std::string &path) {
OS::Dynlib dl(path + "/mod");

auto init = dl.get<void (*)(Swan::Mod &)>("mod_init");
if (init == NULL) {
warn << path << ": No 'mod_init' function!";
return NULL;
return nullptr;
}

std::unique_ptr<Mod> mod = std::make_unique<Mod>(path);
std::unique_ptr<Mod> mod = std::make_unique<Mod>(path, std::move(dl));
init(*mod);
return mod;
}

+ 8
- 0
libswan/src/Mod.cc View File

@@ -8,6 +8,14 @@

namespace Swan {

Mod::~Mod() {
images_.clear();
tiles_.clear();
items_.clear();
worldgens_.clear();
entities_.clear();
}

void Mod::init(const std::string &name) {
name_ = name;
inited_ = true;

+ 8
- 2
libswan/src/OS.cc View File

@@ -16,13 +16,19 @@ bool isTTY(FILE *f) {

Dynlib::Dynlib(const std::string &path) {
handle_ = dlopen((path + ".so").c_str(), RTLD_LAZY);
if (handle_ == NULL) {
if (handle_ == nullptr) {
throw std::runtime_error(dlerror());
}
}

Dynlib::Dynlib(Dynlib &&dl) {
handle_ = dl.handle_;
dl.handle_ = nullptr;
}

Dynlib::~Dynlib() {
dlclose(handle_);
if (handle_ != nullptr)
dlclose(handle_);
}

void *Dynlib::getVoid(const std::string &name) {

Loading…
Cancel
Save