Most likely a change in druntime broke this. Windows, obviously.

======================================================
..\dmd -g -d -ofmydll2.dll -version=use_patch mydll2.d dll2.d mydll2.def
std.contracts has been scheduled for deprecation. Please use std.exception instead.

implib /system mydll2.lib mydll2.dll
Digital Mars Import Library Manager Version 8.41n
Copyright (C) Digital Mars 2000-2004 All Rights Reserved, www.digitalmars.com
implib/h for help
Input is a Windows NT DLL file 'MYDLL2.DLL'.
Output is a Windows NT import library.
Digital Mars Import Library Creator complete.

..\dmd -g -d testmydll2.d mydll2.lib

testmydll2
hello dll world
hello dll world
---- hangs here ----
================== mydll2.d ==================
module mydll2;

import std.stdio;

version(D_Version2)
{
       import core.memory;
}
else
{
       import std.gc;
}

export void dllprint()
{
       writefln("hello dll world");
}

int glob;


// test access to (tls) globals
export int getglob()
{
       return glob;
}

// test gc-mem-allocation from different threads
export char* alloc(int sz)
{
       char* p = (new char[sz]).ptr;
version(D_Version2)
       GC.addRange(p, sz);
else
       addRange(p, p + sz);

       return p;
}

export void free(char* p, int sz)
{
version(D_Version2)
       GC.removeRange(p);
else
       removeRange(p);

       // delete p;
}
================== dll2.d =================
// Public Domain

import std.c.windows.windows;
import std.c.stdlib;

version(D_Version2)
{
   import core.runtime;
   import core.memory;
version(use_patch)
   import core.dll_helper;
   import core.stdc.string;

   extern (C) void _moduleTlsCtor();
   extern (C) void _moduleTlsDtor();
}
else
{
   import std.gc;
   import std.thread;

version(use_patch)
   import std.thread_helper;

   extern (C)
   {
   void gc_init();
   void gc_term();
   void _minit();
   void _moduleCtor();
   void _moduleDtor();
   void _moduleUnitTests();
   }
}

extern (Windows)
BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved)
{
   switch (ulReason)
   {
   case DLL_PROCESS_ATTACH:
version(D_Version2)
{
   version(use_patch)
   {
if( !dll_fixTLS( hInstance, &_tlsstart, &_tlsend, &_tls_callbacks_a, &_tls_index ) )
       return false;

       thread_setNeedLock(true);
       Runtime.initialize();

       // attach to all other threads
       enumProcessThreads( function (uint id, void* context) {
           if( !Thread.findThread( id ) )
           {
               thread_attach( id );
               thread_moduleTlsCtor( id );
           }
           return true;
       }, null );
   }
   else
       Runtime.initialize();
}
else
{
       gc_init();            // initialize GC
       _minit();            // initialize module list
       _moduleCtor();        // run module constructors
       _moduleUnitTests();        // run module unit tests

   version(use_patch)
   {
       // attach to all other threads
       enumProcessThreads( function (uint id, void* context) {
       if( !Thread._getThreadById( id ) )
Thread.thread_attach( id, OpenThreadHandle( id ), getThreadStackBottom( id ) );
       return true;
       }, null );
   }
//        enumThreads();
}
       break;

   case DLL_PROCESS_DETACH:
version(D_Version2)
{
   version(use_patch)
   {
       // detach from all other threads
       enumProcessThreads(
           function (uint id, void* context) {
               if( id != GetCurrentThreadId() && Thread.findThread( id ) )
                   thread_detach( id );
               return true;
           }, null );
   }
       Runtime.terminate();
}
else
{
   version(use_patch)
   {
       // detach from all other threads
       enumProcessThreads(
           function (uint id, void* context) {
               if( id != GetCurrentThreadId() )
               {
                   thread_moduleTlsDtor( id );
                   Thread.thread_detach( id );
               }
               return true;
           }, null );
   }
       _moduleDtor();
       gc_term();            // shut down GC
}
       break;

   case DLL_THREAD_ATTACH:
version(use_patch)
{
   version(D_Version2)
   {
           thread_attachThis();
           _moduleTlsCtor();
   }
   else
       Thread.thread_attach();
}
       break;

   case DLL_THREAD_DETACH:
version(use_patch)
{
   version(D_Version2)
   {
       if( Thread.findThread( GetCurrentThreadId() ) )
           _moduleTlsDtor();
       thread_detachThis();
   }
   else
       Thread.thread_detach();
}
       break;
   }
   return true;
}

====================== mydll2.def ================
LIBRARY "mydll2.dll"
EXETYPE NT
SUBSYSTEM WINDOWS
CODE SHARED EXECUTE
DATA WRITE

===================== testmydll2.d ===================

version(D_Version2)
{
   const string d2_shared = " __gshared ";
}
else
{
   const string d2_shared = "";
}

version(dynload)
{
   extern(Windows) void* LoadLibraryA(in char* dll);
   extern(Windows) void* GetProcAddress(void* lib, in char* name);

   typedef void fnDllPrint();
   typedef int fnGetglob();
   typedef char* fnAlloc(int sz);
   typedef void fnFree(char* p, int sz);

   mixin(d2_shared ~ "fnDllPrint* pDllPrint;");
   mixin(d2_shared ~ "fnGetglob* pGetglob;");
   mixin(d2_shared ~ "fnAlloc* pAlloc;");
   mixin(d2_shared ~ "fnFree* pFree;");

   int loadLib()
   {
      void* lib = LoadLibraryA("mydll2.dll".ptr);
      assert(lib);
pDllPrint = cast(fnDllPrint*) GetProcAddress(lib, "D6mydll28dllprintFZv".ptr); pFree = cast(fnFree*) GetProcAddress(lib, "D6mydll24freeFPaiZv".ptr); pAlloc = cast(fnAlloc*) GetProcAddress(lib, "D6mydll25allocFiZPa".ptr); pGetglob = cast(fnGetglob*) GetProcAddress(lib, "D6mydll27getglobFZi".ptr);
      assert(pDllPrint && pFree && pAlloc && pGetglob);
      return 0;
   }

   void dllprint()
   {
       (*pDllPrint)();
   }

   int getglob()
   {
       return (*pGetglob)();
   }

   char* alloc(int sz)
   {
       return (*pAlloc)(sz);
   }
   void free(char* p, int sz)
   {
       (*pFree)(p, sz);
   }
}
else
{
   import mydll2;
}

mixin(d2_shared ~ "Object syncobj;");

void runtest()
{
   // wait until lib loaded
   synchronized(syncobj) getglob();

   //int g = mydll.glob;

   char*[] mem;
   for(int i = 0; i < 10000; i++)
   {
       mem ~= alloc(16);
   }
   for(int i = 0; i < 10000; i++)
   {
       free(mem[i], 16);
   }
dllprint();
}

version(D_Version2)
{
   import core.thread;

   class TestThread : Thread
   {
       this()
       {
           super(&runtest);
       }
   }
}
else
{
   import std.thread;

   class TestThread : Thread
   {
       int run()
       {
           runtest();
           return 0;
       }
       void join()
       {
           wait();
       }
   }

}

void test_threaded()
{
   syncobj = new Object;
   TestThread[] th;
for(int i = 0; i < 10; i++)
       th ~= new TestThread();
// don't run threads before lib loaded
   synchronized(syncobj)
   {
       for(int i = 0; i < 5; i++)
           th[i].start();
// create some threads before loading the lib, other later
       version(dynload) loadLib();
   }

   for(int i = 5; i < 10; i++)
       th[i].start();
for(int i = 0; i < 10; i++)
       th[i].join();
}

int main()
{
  test_threaded();
  return 0;
}

===============================================

_______________________________________________
phobos mailing list
[email protected]
http://lists.puremagic.com/mailman/listinfo/phobos

Reply via email to