]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
PURE_STATIC improvements: Allow modules to be reloaded, generate linker arguments
authordanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>
Sun, 17 Jan 2010 03:17:25 +0000 (03:17 +0000)
committerdanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>
Sun, 17 Jan 2010 03:17:25 +0000 (03:17 +0000)
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@12276 e03df62e-2008-0410-955e-edbf42e46eb7

make/calcdep.pl
make/unit-cc.pl
src/modmanager_dynamic.cpp
src/modmanager_static.cpp
src/modules.cpp

index 1a1963b3102c9ac5ff5c79c9179d47400d690238..55e0630fc80da3497470661fdd98a7dfde843282 100755 (executable)
@@ -120,20 +120,28 @@ bad-target:
 all: inspircd
 
 END
-       my @deps;
+       my(@deps, @srcs);
        for my $file (<*.cpp>, <modes/*.cpp>, <socketengines/*.cpp>, <commands/*.cpp>,
                        <modules/*.cpp>, <modules/m_*/*.cpp>, "threadengines/threadengine_pthread.cpp") {
                my $out = find_output $file, 1;
+               if ($out =~ m#obj/([^/]+)/[^/]+.o$#) {
+                       mkdir "$ENV{BUILDPATH}/obj/$1";
+               }
                dep_cpp $file, $out;
                next if $file =~ m#^socketengines/# && $file ne "socketengines/$ENV{SOCKETENGINE}.cpp";
                push @deps, $out;
+               push @srcs, $file;
        }
 
        my $core_mk = join ' ', @deps;
+       my $core_src = join ' ', @srcs;
        print MAKE <<END;
 
-bin/inspircd: $core_mk
-       \$(RUNCC) -o \$\@ \$(CORELDFLAGS) \$(LDLIBS) \$^ \$>
+obj/ld-extra.cmd: $core_src
+       \@\$(SOURCEPATH)/make/unit-cc.pl -f\$(VERBOSE) \$\@ \$^ \$>
+
+bin/inspircd: obj/ld-extra.cmd $core_mk
+       \@\$(SOURCEPATH)/make/unit-cc.pl -l\$(VERBOSE) \$\@ \$^ \$>
 
 inspircd: bin/inspircd
 
index 23a7dfb76fb7d74f031c8f137446760ec0d9c26b..489b46ff93eada94a75d5d28159dc62db0a52444 100755 (executable)
@@ -13,6 +13,14 @@ if ($out =~ /^-/) {
        $_ = $out;
        $out = shift;
        $verbose = /v/;
+       if (/f/) {
+               do_static_find(@ARGV);
+               exit;
+       }
+       if (/l/) {
+               do_static_link(@ARGV);
+               exit;
+       }
 }
 
 my $file = shift;
@@ -32,3 +40,31 @@ my $execstr = "$ENV{RUNCC} $flags -o $out $file";
 print "$execstr\n" if $verbose;
 exec $execstr;
 exit 1;
+
+sub do_static_find {
+       my @flags;
+       for my $file (@ARGV) {
+               push @flags, getlinkerflags($file);
+       }
+       open F, '>', $out;
+       print F join ' ', @flags;
+       close F;
+}
+
+sub do_static_link {
+       my $execstr = "$ENV{RUNCC} -o $out $ENV{CORELDFLAGS} $ENV{LDLIBS}";
+       for (@ARGV) {
+               if (/\.cmd$/) {
+                       open F, '<', $_;
+                       my $libs = <F>;
+                       chomp $libs;
+                       $execstr .= ' '.$libs;
+                       close F;
+               } else {
+                       $execstr .= ' '.$_;
+               }
+       }
+       print "$execstr\n" if $verbose;
+       exec $execstr;
+       exit 1;
+}
index 2f686ec96bfa485988592ebdbb516d5aa74256cc..9005622603f8d45df04ce87677814f5efe25021c 100644 (file)
@@ -136,79 +136,6 @@ bool ModuleManager::Load(const char* filename)
        return true;
 }
 
-bool ModuleManager::CanUnload(Module* mod)
-{
-       std::map<std::string, Module*>::iterator modfind = Modules.find(mod->ModuleSourceFile);
-
-       if (modfind == Modules.end() || modfind->second != mod)
-       {
-               LastModuleError = "Module " + mod->ModuleSourceFile + " is not loaded, cannot unload it!";
-               ServerInstance->Logs->Log("MODULE", DEFAULT, LastModuleError);
-               return false;
-       }
-       if (mod->GetVersion().Flags & VF_STATIC)
-       {
-               LastModuleError = "Module " + mod->ModuleSourceFile + " not unloadable (marked static)";
-               ServerInstance->Logs->Log("MODULE", DEFAULT, LastModuleError);
-               return false;
-       }
-       return true;
-}
-
-void ModuleManager::DoSafeUnload(Module* mod)
-{
-       std::map<std::string, Module*>::iterator modfind = Modules.find(mod->ModuleSourceFile);
-
-       std::vector<reference<ExtensionItem> > items;
-       ServerInstance->Extensions.BeginUnregister(modfind->second, items);
-       /* Give the module a chance to tidy out all its metadata */
-       for (chan_hash::iterator c = ServerInstance->chanlist->begin(); c != ServerInstance->chanlist->end(); c++)
-       {
-               mod->OnCleanup(TYPE_CHANNEL,c->second);
-               c->second->doUnhookExtensions(items);
-               const UserMembList* users = c->second->GetUsers();
-               for(UserMembCIter mi = users->begin(); mi != users->end(); mi++)
-                       mi->second->doUnhookExtensions(items);
-       }
-       for (user_hash::iterator u = ServerInstance->Users->clientlist->begin(); u != ServerInstance->Users->clientlist->end(); u++)
-       {
-               mod->OnCleanup(TYPE_USER,u->second);
-               u->second->doUnhookExtensions(items);
-       }
-       for(char m='A'; m <= 'z'; m++)
-       {
-               ModeHandler* mh;
-               mh = ServerInstance->Modes->FindMode(m, MODETYPE_USER);
-               if (mh && mh->creator == mod)
-                       ServerInstance->Modes->DelMode(mh);
-               mh = ServerInstance->Modes->FindMode(m, MODETYPE_CHANNEL);
-               if (mh && mh->creator == mod)
-                       ServerInstance->Modes->DelMode(mh);
-       }
-       for(std::multimap<std::string, ServiceProvider*>::iterator i = DataProviders.begin(); i != DataProviders.end(); )
-       {
-               std::multimap<std::string, ServiceProvider*>::iterator curr = i++;
-               if (curr->second->creator == mod)
-                       DataProviders.erase(curr);
-       }
-       for(unsigned int i = 0; i < ServerInstance->Modules->ActiveDynrefs.size(); i++)
-               ServerInstance->Modules->ActiveDynrefs[i]->ClearCache();
-
-       /* Tidy up any dangling resolvers */
-       ServerInstance->Res->CleanResolvers(mod);
-
-       FOREACH_MOD(I_OnUnloadModule,OnUnloadModule(mod));
-
-       DetachAll(mod);
-
-       Modules.erase(modfind);
-       ServerInstance->GlobalCulls.AddItem(mod);
-
-       ServerInstance->Logs->Log("MODULE", DEFAULT,"Module %s unloaded",mod->ModuleSourceFile.c_str());
-       this->ModCount--;
-       ServerInstance->BuildISupport();
-}
-
 namespace {
        struct UnloadAction : public HandlerBase0<void>
        {
index e09310a13bf66fde0823082094565e38540baa39..3227036795a9b0015b87df8c7fda926ec47b9ab9 100644 (file)
@@ -58,28 +58,58 @@ class AllModule : public Module
 
 MODULE_INIT(AllModule)
 
-bool ModuleManager::Load(const char* filename)
+bool ModuleManager::Load(const char* name)
 {
+       for(std::vector<AllModuleList*>::iterator i = modlist->begin(); i != modlist->end(); ++i)
+       {
+               if ((**i).name == name)
+               {
+                       try
+                       {
+                               Module* c = (*(**i).init)();
+                               Modules[name] = c;
+                               FOREACH_MOD(I_OnLoadModule,OnLoadModule(c));
+                               return true;
+                       }
+                       catch (CoreException& modexcept)
+                       {
+                               ServerInstance->Logs->Log("MODULE", DEFAULT, "Unable to load " + (**i).name + ": " + modexcept.GetReason());
+                       }
+               }
+       }
        return false;
 }
 
-bool ModuleManager::CanUnload(Module* mod)
+bool ModuleManager::Unload(Module* mod)
 {
        return false;
 }
 
-void ModuleManager::DoSafeUnload(Module* mod)
-{
-}
-
-bool ModuleManager::Unload(Module* mod)
-{
-       return false;
+namespace {
+       struct ReloadAction : public HandlerBase0<void>
+       {
+               Module* const mod;
+               HandlerBase1<void, bool>* const callback;
+               ReloadAction(Module* m, HandlerBase1<void, bool>* c)
+                       : mod(m), callback(c) {}
+               void Call()
+               {
+                       std::string name = mod->ModuleSourceFile;
+                       ServerInstance->Modules->DoSafeUnload(mod);
+                       ServerInstance->GlobalCulls.Apply();
+                       bool rv = ServerInstance->Modules->Load(name.c_str());
+                       callback->Call(rv);
+                       ServerInstance->GlobalCulls.AddItem(this);
+               }
+       };
 }
 
 void ModuleManager::Reload(Module* mod, HandlerBase1<void, bool>* callback)
 {
-       callback->Call(false);
+       if (CanUnload(mod))
+               ServerInstance->AtomicActions.AddAction(new ReloadAction(mod, callback));
+       else
+               callback->Call(false);
 }
 
 void ModuleManager::LoadAll()
index cbd6c7b3871a7270f8549418550a89fc10daef35..b25469c30b17405a2a162cd9eab48d1f1bbc788b 100644 (file)
@@ -329,6 +329,79 @@ bool ModuleManager::SetPriority(Module* mod, Implementation i, Priority s, Modul
        return true;
 }
 
+bool ModuleManager::CanUnload(Module* mod)
+{
+       std::map<std::string, Module*>::iterator modfind = Modules.find(mod->ModuleSourceFile);
+
+       if (modfind == Modules.end() || modfind->second != mod)
+       {
+               LastModuleError = "Module " + mod->ModuleSourceFile + " is not loaded, cannot unload it!";
+               ServerInstance->Logs->Log("MODULE", DEFAULT, LastModuleError);
+               return false;
+       }
+       if (mod->GetVersion().Flags & VF_STATIC)
+       {
+               LastModuleError = "Module " + mod->ModuleSourceFile + " not unloadable (marked static)";
+               ServerInstance->Logs->Log("MODULE", DEFAULT, LastModuleError);
+               return false;
+       }
+       return true;
+}
+
+void ModuleManager::DoSafeUnload(Module* mod)
+{
+       std::map<std::string, Module*>::iterator modfind = Modules.find(mod->ModuleSourceFile);
+
+       std::vector<reference<ExtensionItem> > items;
+       ServerInstance->Extensions.BeginUnregister(modfind->second, items);
+       /* Give the module a chance to tidy out all its metadata */
+       for (chan_hash::iterator c = ServerInstance->chanlist->begin(); c != ServerInstance->chanlist->end(); c++)
+       {
+               mod->OnCleanup(TYPE_CHANNEL,c->second);
+               c->second->doUnhookExtensions(items);
+               const UserMembList* users = c->second->GetUsers();
+               for(UserMembCIter mi = users->begin(); mi != users->end(); mi++)
+                       mi->second->doUnhookExtensions(items);
+       }
+       for (user_hash::iterator u = ServerInstance->Users->clientlist->begin(); u != ServerInstance->Users->clientlist->end(); u++)
+       {
+               mod->OnCleanup(TYPE_USER,u->second);
+               u->second->doUnhookExtensions(items);
+       }
+       for(char m='A'; m <= 'z'; m++)
+       {
+               ModeHandler* mh;
+               mh = ServerInstance->Modes->FindMode(m, MODETYPE_USER);
+               if (mh && mh->creator == mod)
+                       ServerInstance->Modes->DelMode(mh);
+               mh = ServerInstance->Modes->FindMode(m, MODETYPE_CHANNEL);
+               if (mh && mh->creator == mod)
+                       ServerInstance->Modes->DelMode(mh);
+       }
+       for(std::multimap<std::string, ServiceProvider*>::iterator i = DataProviders.begin(); i != DataProviders.end(); )
+       {
+               std::multimap<std::string, ServiceProvider*>::iterator curr = i++;
+               if (curr->second->creator == mod)
+                       DataProviders.erase(curr);
+       }
+       for(unsigned int i = 0; i < ServerInstance->Modules->ActiveDynrefs.size(); i++)
+               ServerInstance->Modules->ActiveDynrefs[i]->ClearCache();
+
+       /* Tidy up any dangling resolvers */
+       ServerInstance->Res->CleanResolvers(mod);
+
+       FOREACH_MOD(I_OnUnloadModule,OnUnloadModule(mod));
+
+       DetachAll(mod);
+
+       Modules.erase(modfind);
+       ServerInstance->GlobalCulls.AddItem(mod);
+
+       ServerInstance->Logs->Log("MODULE", DEFAULT,"Module %s unloaded",mod->ModuleSourceFile.c_str());
+       this->ModCount--;
+       ServerInstance->BuildISupport();
+}
+
 std::string& ModuleManager::LastError()
 {
        return LastModuleError;