Skip to content

Commit

Permalink
Trinity.Core: fix #44; fix #16; fix #19
Browse files Browse the repository at this point in the history
  • Loading branch information
yatli committed Apr 24, 2017
1 parent 5120ce4 commit 3c51fe6
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 9 deletions.
9 changes: 7 additions & 2 deletions src/Trinity.C/include/Trinity/IO/Path.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ namespace Trinity
static const char WindowsDirectorySeparator = '\\';
static const char UnixDirectorySeparator = '/';
static const char *DirectorySeparators = "/\\";
extern String g_AssemblyPath;

#if defined(TRINITY_PLATFORM_WINDOWS)
static const char DirectorySeparator = WindowsDirectorySeparator;
Expand Down Expand Up @@ -325,13 +326,16 @@ namespace Trinity

inline String MyAssemblyPath()
{
if (g_AssemblyPath != "") return g_AssemblyPath;

#if defined(TRINITY_PLATFORM_WINDOWS)
Array<u16char> lpFilename(1024);
HMODULE hmodule = GetModuleHandleW(L"Trinity.C.dll");
/* If Trinity.C.dll is absent, we default to the executing assembly (sending NULL into the API) */
GetModuleFileNameW(hmodule, lpFilename, static_cast<DWORD>(lpFilename.Length()));
lpFilename[lpFilename.Length() - 1] = 0;
return GetDirectoryName(GetFullPath(String::FromWcharArray(lpFilename, -1)));
g_AssemblyPath = GetDirectoryName(GetFullPath(String::FromWcharArray(lpFilename, -1)));
return g_AssemblyPath;
#elif defined(TRINITY_PLATFORM_LINUX)
// XXX does not make sense if MyAssemblyPath always point to the mono host...
char* filename_buf = new char[1024];
Expand All @@ -340,7 +344,8 @@ namespace Trinity
filename_buf[filename_buf_size] = 0;
String ret(filename_buf);
delete[] filename_buf;
return GetDirectoryName(ret);
g_AssemblyPath = GetDirectoryName(ret);
return g_AssemblyPath;
#else
#error Not supported
#endif
Expand Down
15 changes: 14 additions & 1 deletion src/Trinity.C/src/Runtime/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,19 @@
#include "BackgroundThread/BackgroundThread.h"
#include "Trinity/Diagnostics/LogAutoFlushTask.h"

namespace Trinity
{
namespace IO
{
namespace Path
{
Trinity::String g_AssemblyPath = "";
}
}
}

/* Should only be reached from CLR*/
DLL_EXPORT VOID __stdcall __INIT_TRINITY_C__()
DLL_EXPORT VOID __stdcall __INIT_TRINITY_C__(u16char* pAssemblyPath)
{
#ifdef TRINITY_PLATFORM_WINDOWS
Memory::LargePageMinimum = GetLargePageMinimum();
Expand All @@ -23,5 +34,7 @@ DLL_EXPORT VOID __stdcall __INIT_TRINITY_C__()
Runtime::__transition_enabled = true;
#endif

Trinity::IO::Path::g_AssemblyPath = Trinity::String::FromWcharArray(pAssemblyPath, -1);

BackgroundThread::TaskScheduler::Start();
}
5 changes: 4 additions & 1 deletion src/Trinity.Core/Trinity/Configuration/TrinityConfig.IO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,16 @@ public static void SaveConfig(string configFile)
}
catch (Exception) { }
}
string dir = Path.GetDirectoryName(configFile);
if (dir == string.Empty) dir = Global.MyAssemblyPath;

FileUtility.CompletePath(Path.GetDirectoryName(configFile), true);
#region create basic xml info
XmlDocument configXml = new XmlDocument();
XmlDeclaration declaration = configXml.CreateXmlDeclaration("1.0", "utf-8", null);
XmlNode rootNode = configXml.CreateElement(ConfigurationConstants.Tags.ROOT_NODE);
XmlAttribute version = configXml.CreateAttribute(ConfigurationConstants.Attrs.CONFIG_VERSION);
version.Value = "1.0";
version.Value = ConfigurationConstants.Tags.CURRENTVER;
rootNode.Attributes.Append(version);
#endregion
#region Get Local Setting Info
Expand Down
9 changes: 6 additions & 3 deletions src/Trinity.Core/Trinity/Runtime/TrinityC.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ internal static partial class TrinityC
private static bool s_initialized = false;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void Init()
internal unsafe static void Init()
{
lock (s_initlock)
{
Expand Down Expand Up @@ -70,7 +70,10 @@ internal static void Init()
}

/* native assembly is released. initialize Trinity.C now */
__INIT_TRINITY_C__();
fixed(char* pAssemblyPath = AssemblyPath.MyAssemblyPath)
{
__INIT_TRINITY_C__(pAssemblyPath);
}

if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
Expand Down Expand Up @@ -110,6 +113,6 @@ private static void ReleaseNativeAssembly(string native_assembly_name, string tr
}

[DllImport(TrinityC.AssemblyName)]
private static extern unsafe void __INIT_TRINITY_C__();
private static extern unsafe void __INIT_TRINITY_C__(char* pAssemblyPath);
}
}
4 changes: 4 additions & 0 deletions src/Trinity.Core/Utilities/IO/FileUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,11 @@ public static string RandomFileNameWithoutExtension
/// <returns>The completed directory path.</returns>
public static string CompletePath(string path, bool create_nonexistent = true)
{
if (path == null) throw new ArgumentNullException("path");
if (path == "") path = Environment.CurrentDirectory;

string _path = path;

if (path[path.Length - 1] != Path.DirectorySeparatorChar)
_path = path + Path.DirectorySeparatorChar;
if (create_nonexistent && (!Directory.Exists(_path)))
Expand Down
61 changes: 59 additions & 2 deletions src/Trinity.Core/Utilities/MISC/AssemblyPath.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
Expand All @@ -10,15 +11,71 @@ namespace Trinity.Utilities
{
internal static class AssemblyPath
{
private static string my_assembly_path = "";
private static string my_assembly_path = null;
internal static string MyAssemblyPath
{
get
{
if (my_assembly_path.Length == 0)
if (my_assembly_path == null)
{
// primary heuristics: find the assembly that calls into Trinity
Assembly trinity_asm = Assembly.GetExecutingAssembly();
int firstTrinityFrame = 0;
for (int skipFrames = 1; ; skipFrames++)
{
StackFrame stackFrame;
try
{
stackFrame = new StackFrame(skipFrames);
if (stackFrame.GetMethod() == null) break;
}
catch { break; }

try
{
var asm = stackFrame.GetMethod().Module.Assembly;
if (asm == trinity_asm) firstTrinityFrame = skipFrames;
}
catch { continue; }
}

for (int skipFrames = firstTrinityFrame + 1; ; skipFrames++)
{
StackFrame stackFrame;
try
{
stackFrame = new StackFrame(skipFrames);
if (stackFrame.GetMethod() == null) break;
}
catch { break; }

try
{
var method = stackFrame.GetMethod();
var type = method.DeclaringType;
var asm = method.Module.Assembly;

if (asm == trinity_asm) continue;
if (asm.IsDynamic) continue;
if (type == typeof(System.RuntimeMethodHandle)) continue;
if (type.FullName == "System.Linq.Enumerable+WhereSelectEnumerableIterator`2") continue;
if (type.FullName == "System.Linq.Enumerable+WhereEnumerableIterator`1") continue;
if (type.FullName == "System.Linq.Enumerable") continue;

var path = asm.Location;
my_assembly_path = System.IO.Path.GetDirectoryName(path) + Path.DirectorySeparatorChar;
break;
}
catch { continue; }
}
}

if (my_assembly_path == null)
{
// last resort heuristic: return the path of the Trinity assembly.
my_assembly_path = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + Path.DirectorySeparatorChar;
}

return my_assembly_path;
}
}
Expand Down

0 comments on commit 3c51fe6

Please sign in to comment.