Browse Source

* exiting threads at nlm unload
* renamed some libc functions

armin 21 years ago
parent
commit
173aea0681

+ 3 - 2
rtl/netwlibc/Makefile

@@ -1,5 +1,5 @@
 #
 #
-# Don't edit, this file is generated by FPCMake Version 1.1 [2004/09/19]
+# Don't edit, this file is generated by FPCMake Version 1.1 [2004/09/22]
 #
 #
 default: all
 default: all
 MAKEFILETARGETS=netwlibc
 MAKEFILETARGETS=netwlibc
@@ -1427,7 +1427,8 @@ sysutils$(PPUEXT) : sysutils.pp $(wildcard $(OBJPASDIR)/sysutils/*.inc) \
 	$(COMPILER) -Fi$(OBJPASDIR)/sysutils sysutils.pp
 	$(COMPILER) -Fi$(OBJPASDIR)/sysutils sysutils.pp
 classes$(PPUEXT) : classes.pp $(wildcard $(OBJPASDIR)/classes/*.inc) \
 classes$(PPUEXT) : classes.pp $(wildcard $(OBJPASDIR)/classes/*.inc) \
 		   sysutils$(PPUEXT) typinfo$(PPUEXT) rtlconst$(PPUEXT) \
 		   sysutils$(PPUEXT) typinfo$(PPUEXT) rtlconst$(PPUEXT) \
-		   sysconst$(PPUEXT) types$(PPUEXT) systhrds$(PPUEXT)
+		   sysconst$(PPUEXT) types$(PPUEXT) systhrds$(PPUEXT) \
+		   tthread.inc
 	$(COMPILER) -Fi$(OBJPASDIR)/classes classes.pp
 	$(COMPILER) -Fi$(OBJPASDIR)/classes classes.pp
 typinfo$(PPUEXT): $(OBJPASDIR)/typinfo.pp objpas$(PPUEXT)
 typinfo$(PPUEXT): $(OBJPASDIR)/typinfo.pp objpas$(PPUEXT)
 	$(COMPILER) -Sg $(OBJPASDIR)/typinfo.pp
 	$(COMPILER) -Sg $(OBJPASDIR)/typinfo.pp

+ 2 - 1
rtl/netwlibc/Makefile.fpc

@@ -163,7 +163,8 @@ sysutils$(PPUEXT) : sysutils.pp $(wildcard $(OBJPASDIR)/sysutils/*.inc) \
 
 
 classes$(PPUEXT) : classes.pp $(wildcard $(OBJPASDIR)/classes/*.inc) \
 classes$(PPUEXT) : classes.pp $(wildcard $(OBJPASDIR)/classes/*.inc) \
                    sysutils$(PPUEXT) typinfo$(PPUEXT) rtlconst$(PPUEXT) \
                    sysutils$(PPUEXT) typinfo$(PPUEXT) rtlconst$(PPUEXT) \
-                   sysconst$(PPUEXT) types$(PPUEXT) systhrds$(PPUEXT)
+                   sysconst$(PPUEXT) types$(PPUEXT) systhrds$(PPUEXT) \
+                   tthread.inc
         $(COMPILER) -Fi$(OBJPASDIR)/classes classes.pp
         $(COMPILER) -Fi$(OBJPASDIR)/classes classes.pp
 
 
 typinfo$(PPUEXT): $(OBJPASDIR)/typinfo.pp objpas$(PPUEXT)
 typinfo$(PPUEXT): $(OBJPASDIR)/typinfo.pp objpas$(PPUEXT)

+ 12 - 1
rtl/netwlibc/classes.pp

@@ -39,10 +39,21 @@ implementation
 { OS - independent class implementations are in /inc directory. }
 { OS - independent class implementations are in /inc directory. }
 {$i classes.inc}
 {$i classes.inc}
 
 
+initialization
+  CommonInit;
+
+finalization
+  DoneThreads;
+  CommonCleanup;
+
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.1  2004-09-05 20:58:47  armin
+  Revision 1.2  2004-09-26 19:23:34  armin
+  * exiting threads at nlm unload
+  * renamed some libc functions
+
+  Revision 1.1  2004/09/05 20:58:47  armin
   * first rtl version for netwlibc
   * first rtl version for netwlibc
 
 
 }
 }

+ 12 - 8
rtl/netwlibc/dos.pp

@@ -66,7 +66,7 @@ uses
 function dosversion : word;
 function dosversion : word;
 var i : Tutsname;
 var i : Tutsname;
 begin
 begin
-  if uname (i) >= 0 then
+  if Fpuname (i) >= 0 then
     dosversion := WORD (i.netware_minor) SHL 8 + i.netware_major
     dosversion := WORD (i.netware_minor) SHL 8 + i.netware_major
   else dosversion := $0005;
   else dosversion := $0005;
 end;
 end;
@@ -217,7 +217,7 @@ begin
   //writeln (stderr,'Ok');
   //writeln (stderr,'Ok');
   if i <> -1 then
   if i <> -1 then
   begin
   begin
-    waitpid(i,@wstat,0);
+    Fpwaitpid(i,@wstat,0);
     doserror := 0;
     doserror := 0;
     lastdosexitcode := wstat;
     lastdosexitcode := wstat;
   end else
   end else
@@ -393,7 +393,7 @@ begin
       fname := f._dir + f.name;
       fname := f._dir + f.name;
       if length (fname) = 255 then dec (byte(fname[0]));
       if length (fname) = 255 then dec (byte(fname[0]));
       fname := fname + #0;
       fname := fname + #0;
-      if stat (@fname[1],StatBuf) = 0 then
+      if Fpstat (@fname[1],StatBuf) = 0 then
         timet2dostime (StatBuf.st_mtim.tv_sec, time)
         timet2dostime (StatBuf.st_mtim.tv_sec, time)
       else
       else
         time := 0;
         time := 0;
@@ -624,7 +624,7 @@ var
   StatBuf : TStat;
   StatBuf : TStat;
 begin
 begin
   doserror := 0;
   doserror := 0;
-  if fstat (filerec (f).handle, StatBuf) = 0 then
+  if Fpfstat (filerec (f).handle, StatBuf) = 0 then
     timet2dostime (StatBuf.st_mtim.tv_sec,time)
     timet2dostime (StatBuf.st_mtim.tv_sec,time)
   else begin
   else begin
     time := 0;
     time := 0;
@@ -671,7 +671,7 @@ procedure getfattr(var f;var attr : word);
 VAR StatBuf : TStat;
 VAR StatBuf : TStat;
 begin
 begin
   doserror := 0;
   doserror := 0;
-  if stat (@textrec(f).name, StatBuf) = 0 then
+  if Fpstat (@textrec(f).name, StatBuf) = 0 then
     attr := nwattr2dosattr (StatBuf.st_mode)
     attr := nwattr2dosattr (StatBuf.st_mode)
   else
   else
   begin
   begin
@@ -686,7 +686,7 @@ var
   StatBuf : TStat;
   StatBuf : TStat;
   newMode : longint;
   newMode : longint;
 begin
 begin
-  if stat (@textrec(f).name,StatBuf) = 0 then
+  if Fpstat (@textrec(f).name,StatBuf) = 0 then
   begin
   begin
     newmode := StatBuf.st_mode and ($FFFF0000 - M_A_RDONLY-M_A_HIDDEN-M_A_SYSTEM-M_A_ARCH); {only this can be set by dos unit}
     newmode := StatBuf.st_mode and ($FFFF0000 - M_A_RDONLY-M_A_HIDDEN-M_A_SYSTEM-M_A_ARCH); {only this can be set by dos unit}
     newmode := newmode or M_A_BITS_SIGNIFICANT;  {set netware attributes}
     newmode := newmode or M_A_BITS_SIGNIFICANT;  {set netware attributes}
@@ -698,7 +698,7 @@ begin
       newmode := newmode or M_A_SYSTEM;
       newmode := newmode or M_A_SYSTEM;
     if attr and archive > 0 then
     if attr and archive > 0 then
       newmode := newmode or M_A_ARCH;
       newmode := newmode or M_A_ARCH;
-    if chmod (@textrec(f).name,newMode) < 0 then
+    if Fpchmod (@textrec(f).name,newMode) < 0 then
       doserror := ___errno^ else
       doserror := ___errno^ else
       doserror := 0;
       doserror := 0;
   end else
   end else
@@ -822,7 +822,11 @@ end;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.3  2004-09-19 20:06:37  armin
+  Revision 1.4  2004-09-26 19:23:34  armin
+  * exiting threads at nlm unload
+  * renamed some libc functions
+
+  Revision 1.3  2004/09/19 20:06:37  armin
   * removed get/free video buf from video.pp
   * removed get/free video buf from video.pp
   * implemented sockets
   * implemented sockets
   * basic library support
   * basic library support

File diff suppressed because it is too large
+ 235 - 397
rtl/netwlibc/libc.pp


+ 97 - 15
rtl/netwlibc/system.pp

@@ -82,6 +82,7 @@ const
   Dll_Process_Detach_Hook : TDLL_Entry_Hook = nil;
   Dll_Process_Detach_Hook : TDLL_Entry_Hook = nil;
   Dll_Thread_Attach_Hook  : TDLL_Entry_Hook = nil;
   Dll_Thread_Attach_Hook  : TDLL_Entry_Hook = nil;
   Dll_Thread_Detach_Hook  : TDLL_Entry_Hook = nil;
   Dll_Thread_Detach_Hook  : TDLL_Entry_Hook = nil;
+  NetwareUnloadProc       : pointer = nil;  {like exitProc but for nlm unload only}
   envp : ppchar = nil;
   envp : ppchar = nil;
 
 
 
 
@@ -96,7 +97,12 @@ procedure NWSysSetThreadFunctions (atv:TSysReleaseThreadVars;
                                    stdata:TSysSetThreadDataAreaPtr);
                                    stdata:TSysSetThreadDataAreaPtr);
 
 
 
 
-procedure __ConsolePrintf (s :shortstring);
+procedure ConsolePrintf (s :shortstring);
+procedure ConsolePrintf (FormatStr : PCHAR; Param : LONGINT);
+procedure ConsolePrintf (FormatStr : PCHAR; Param : pchar);
+procedure ConsolePrintf (FormatStr : PCHAR; P1,P2 : LONGINT);
+procedure ConsolePrintf (FormatStr : PCHAR; P1,P2,P3 : LONGINT);
+procedure ConsolePrintf (FormatStr : PCHAR);
 procedure __EnterDebugger; cdecl;
 procedure __EnterDebugger; cdecl;
 
 
 function NWGetCodeStart : pointer;  // needed for Lineinfo
 function NWGetCodeStart : pointer;  // needed for Lineinfo
@@ -126,6 +132,7 @@ var
   ReleaseThreadVars : TSysReleaseThreadVars = nil;
   ReleaseThreadVars : TSysReleaseThreadVars = nil;
   AllocateThreadVars: TSysReleaseThreadVars = nil;
   AllocateThreadVars: TSysReleaseThreadVars = nil;
   SetThreadDataAreaPtr : TSysSetThreadDataAreaPtr = nil;
   SetThreadDataAreaPtr : TSysSetThreadDataAreaPtr = nil;
+  TerminatingThreadID : dword = 0;
 
 
 procedure NWSysSetThreadFunctions (atv:TSysReleaseThreadVars;
 procedure NWSysSetThreadFunctions (atv:TSysReleaseThreadVars;
                                    rtv:TSysReleaseThreadVars;
                                    rtv:TSysReleaseThreadVars;
@@ -153,7 +160,18 @@ var SigTermHandlerActive : boolean;
 
 
 Procedure system_exit;
 Procedure system_exit;
 begin
 begin
-  //__ConsolePrintf ('system_exit');
+  if TerminatingThreadID <> 0 then
+    if TerminatingThreadID <> ThreadId then
+      if TerminatingThreadID <> dword(pthread_self) then
+      begin
+        {$ifdef DEBUG_MT}
+        ConsolePrintf ('Terminating Thread %x because halt was called while Thread %x terminates nlm'#13#10,dword(pthread_self),TerminatingThreadId);
+        {$endif}
+        pthread_exit (nil);
+        // only for the case ExitThread fails
+        while true do
+          NXThreadYield;
+      end;
   if assigned (ReleaseThreadVars) then ReleaseThreadVars;
   if assigned (ReleaseThreadVars) then ReleaseThreadVars;
 
 
   {$ifdef autoHeapRelease}
   {$ifdef autoHeapRelease}
@@ -260,7 +278,7 @@ var P2 : POINTER;
 begin
 begin
   if HeapSbrkReleased then
   if HeapSbrkReleased then
   begin
   begin
-    __ConsolePrintf ('Error: SysOSFree called after all heap memory was released');
+    ConsolePrintf ('Error: SysOSFree called after all heap memory was released'#13#10);
     exit(nil);
     exit(nil);
   end;
   end;
   SysOSAlloc := _Alloc (size,HeapAllocResourceTag);
   SysOSAlloc := _Alloc (size,HeapAllocResourceTag);
@@ -332,7 +350,7 @@ var i : longint;
 begin
 begin
   if HeapSbrkReleased then
   if HeapSbrkReleased then
   begin
   begin
-    __ConsolePrintf ('Error: SysOSFree called after all heap memory was released');
+    ConsolePrintf ('Error: SysOSFree called after all heap memory was released'#13#10);
   end else
   end else
   if (HeapSbrkLastUsed > 0) then
   if (HeapSbrkLastUsed > 0) then
     for i := 1 to HeapSbrkLastUsed do
     for i := 1 to HeapSbrkLastUsed do
@@ -541,7 +559,7 @@ VAR res     : LONGINT;
     statbuf : TStat;
     statbuf : TStat;
 begin
 begin
   {$ifdef IOpossix}
   {$ifdef IOpossix}
-  res := fstat (handle, statbuf);
+  res := Fpfstat (handle, statbuf);
   {$else}
   {$else}
   res := _fstat (_fileno (_TFILE(handle)), statbuf);  // was _filelength for clib
   res := _fstat (_fileno (_TFILE(handle)), statbuf);  // was _filelength for clib
   {$endif}
   {$endif}
@@ -858,7 +876,7 @@ procedure InitFPU;assembler;
 function CheckFunction : longint; CDECL; [public,alias: '_NonAppCheckUnload'];
 function CheckFunction : longint; CDECL; [public,alias: '_NonAppCheckUnload'];
 var oldPtr : pointer;
 var oldPtr : pointer;
 begin
 begin
-  //__ConsolePrintf ('CheckFunction');
+  //ConsolePrintf ('CheckFunction'#13#10);
   if assigned (NetwareCheckFunction) then
   if assigned (NetwareCheckFunction) then
   begin
   begin
     if assigned (SetThreadDataAreaPtr) then
     if assigned (SetThreadDataAreaPtr) then
@@ -875,14 +893,49 @@ begin
 end;
 end;
 
 
 
 
-procedure __ConsolePrintf (s : shortstring);
+procedure ConsolePrintf (s : shortstring);
+begin
+  if length(s) > 254 then
+    byte(s[0]) := 254;
+  s := s + #0;
+  ConsolePrintf (@s[1]);
+end;
+
+procedure ConsolePrintf (FormatStr : PCHAR);
+begin
+  if NWLoggerScreen = nil then
+    NWLoggerScreen := getnetwarelogger;
+  if NWLoggerScreen <> nil then
+    screenprintf (NWLoggerScreen,FormatStr);
+end;
+
+procedure ConsolePrintf (FormatStr : PCHAR; Param : LONGINT);
+begin
+  if NWLoggerScreen = nil then
+    NWLoggerScreen := getnetwarelogger;
+  if NWLoggerScreen <> nil then
+    screenprintf (NWLoggerScreen,FormatStr,Param);
+end;
+
+procedure ConsolePrintf (FormatStr : PCHAR; Param : pchar);
+begin
+  ConsolePrintf (FormatStr,longint(Param));
+end;
+
+procedure ConsolePrintf (FormatStr : PCHAR; P1,P2 : LONGINT);
+begin
+  if NWLoggerScreen = nil then
+    NWLoggerScreen := getnetwarelogger;
+  if NWLoggerScreen <> nil then
+    screenprintf (NWLoggerScreen,FormatStr,P1,P2);
+end;
+
+procedure ConsolePrintf (FormatStr : PCHAR; P1,P2,P3 : LONGINT);
 begin
 begin
-  if length(s) > 252 then
-    byte(s[0]) := 252;
-  s := s + #13#10#0;
   if NWLoggerScreen = nil then
   if NWLoggerScreen = nil then
     NWLoggerScreen := getnetwarelogger;
     NWLoggerScreen := getnetwarelogger;
-  screenprintf (NWLoggerScreen,@s[1]);
+  if NWLoggerScreen <> nil then
+    screenprintf (NWLoggerScreen,FormatStr,P1,P2,P3);
 end;
 end;
 
 
 
 
@@ -892,7 +945,7 @@ var NWUts : Tutsname;
 
 
 procedure getCodeAddresses;
 procedure getCodeAddresses;
 begin
 begin
-  if uname(NWUts) < 0 then
+  if Fpuname(NWUts) < 0 then
     FillChar(NWuts,sizeof(NWUts),0);
     FillChar(NWuts,sizeof(NWUts),0);
 end;
 end;
 
 
@@ -973,6 +1026,7 @@ end;
   Halt (or _exit) can not be called from this callback procedure }
   Halt (or _exit) can not be called from this callback procedure }
 procedure TermSigHandler (Sig:longint); CDecl;
 procedure TermSigHandler (Sig:longint); CDecl;
 var oldPtr : pointer;
 var oldPtr : pointer;
+    current_exit : procedure;
 begin
 begin
   { Threadvar Pointer will not be valid because the signal
   { Threadvar Pointer will not be valid because the signal
     handler is called by netware with a differnt thread. To avoid
     handler is called by netware with a differnt thread. To avoid
@@ -980,6 +1034,28 @@ begin
     here }
     here }
   if assigned (SetThreadDataAreaPtr) then
   if assigned (SetThreadDataAreaPtr) then
     oldPtr := SetThreadDataAreaPtr (NIL);  { nil means main thread }
     oldPtr := SetThreadDataAreaPtr (NIL);  { nil means main thread }
+
+  TerminatingThreadID := dword(pthread_self);
+
+  {we need to finalize winock to release threads
+   waiting on a blocking socket call. If that thread
+   calls halt, we have to avoid that unit finalization
+   is called by that thread because we are doing it
+   here
+
+   like the old exitProc, mainly to allow winsock to release threads
+   blocking in a winsock calls }
+  while NetwareUnloadProc<>nil Do
+  Begin
+    InOutRes:=0;
+    current_exit:=tProcedure(NetwareUnloadProc);
+    NetwareUnloadProc:=nil;
+    current_exit();
+    NXThreadYield;
+    //hadExitProc := true;
+  End;
+
+
   SigTermHandlerActive := true;  { to avoid that system_exit calls _exit }
   SigTermHandlerActive := true;  { to avoid that system_exit calls _exit }
   do_exit;                       { calls finalize units }
   do_exit;                       { calls finalize units }
   if assigned (SetThreadDataAreaPtr) then
   if assigned (SetThreadDataAreaPtr) then
@@ -1025,7 +1101,9 @@ function _DLLMain (hInstDLL:pointer; fdwReason:dword; DLLParam:longint):longbool
 [public, alias : '_FPC_DLL_Entry'];
 [public, alias : '_FPC_DLL_Entry'];
 var res : longbool;
 var res : longbool;
 begin
 begin
-  __ConsolePrintf ('_FPC_DLL_Entry called');
+  {$ifdef DEBUG_MT}
+  ConsolePrintf ('_FPC_DLL_Entry called');
+  {$endif}
   _DLLMain := false;
   _DLLMain := false;
   isLibrary := true;
   isLibrary := true;
   case fdwReason of
   case fdwReason of
@@ -1094,7 +1172,7 @@ Begin
   HeapListAllocResourceTag :=
   HeapListAllocResourceTag :=
     AllocateResourceTag(NLMHandle,'Heap Memory List',AllocSignature);
     AllocateResourceTag(NLMHandle,'Heap Memory List',AllocSignature);
   {$endif}
   {$endif}
-  Signal (SIGTERM, @TermSigHandler);
+  FpSignal (SIGTERM, @TermSigHandler);
 
 
 { Setup heap }
 { Setup heap }
   InitHeap;
   InitHeap;
@@ -1116,7 +1194,11 @@ Begin
 End.
 End.
 {
 {
   $Log$
   $Log$
-  Revision 1.3  2004-09-19 20:06:37  armin
+  Revision 1.4  2004-09-26 19:23:34  armin
+  * exiting threads at nlm unload
+  * renamed some libc functions
+
+  Revision 1.3  2004/09/19 20:06:37  armin
   * removed get/free video buf from video.pp
   * removed get/free video buf from video.pp
   * implemented sockets
   * implemented sockets
   * basic library support
   * basic library support

+ 25 - 38
rtl/netwlibc/systhrds.pp

@@ -34,6 +34,14 @@ type
 
 
 implementation
 implementation
 
 
+{ ok, so this is a hack, but it works nicely. Just never use
+  a multiline argument with WRITE_DEBUG! }
+{$MACRO ON}
+{$IFDEF DEBUG_MT}
+{$define WRITE_DEBUG := ConsolePrintf} // actually write something
+{$ELSE}
+{$define WRITE_DEBUG := //}      // just comment out those lines
+{$ENDIF}
 
 
 {*****************************************************************************
 {*****************************************************************************
                              Generic overloaded
                              Generic overloaded
@@ -82,17 +90,13 @@ implementation
         pthread_setspecific(tlskey,dataindex);
         pthread_setspecific(tlskey,dataindex);
         if thredvarsmainthread = nil then
         if thredvarsmainthread = nil then
           thredvarsmainthread := dataindex;
           thredvarsmainthread := dataindex;
-        {$ifdef DEBUG_MT}
-        __ConsolePrintf ('SysAllocateThreadVars');
-        {$endif}
+        WRITE_DEBUG ('SysAllocateThreadVars'#13#10);
       end;
       end;
 
 
 
 
     procedure SysReleaseThreadVars;
     procedure SysReleaseThreadVars;
       begin
       begin
-        {$ifdef DEBUG_MT}
-        __ConsolePrintf ('SysReleaseThreadVars');
-        {$endif}
+        WRITE_DEBUG ('SysReleaseThreadVars'#13#10);
         _Free (pthread_getspecific(tlskey));
         _Free (pthread_getspecific(tlskey));
       end;
       end;
 
 
@@ -128,9 +132,7 @@ implementation
       begin
       begin
         { Release Threadvars }
         { Release Threadvars }
 {$ifdef HASTHREADVAR}
 {$ifdef HASTHREADVAR}
-{$ifdef DEBUG_MT}
-        __ConsolePrintf('DoneThread, releasing threadvars');
-{$endif DEBUG_MT}
+        WRITE_DEBUG('DoneThread, releasing threadvars'#13#10);
         SysReleaseThreadVars;
         SysReleaseThreadVars;
 {$endif HASTHREADVAR}
 {$endif HASTHREADVAR}
       end;
       end;
@@ -139,39 +141,25 @@ implementation
     function ThreadMain(param : pointer) : pointer;cdecl;
     function ThreadMain(param : pointer) : pointer;cdecl;
       var
       var
         ti : tthreadinfo;
         ti : tthreadinfo;
-{$ifdef DEBUG_MT}
-        // in here, don't use write/writeln before having called
-        // InitThread! I wonder if anyone ever debugged these routines,
-        // because they will have crashed if DEBUG_MT was enabled!
-        // this took me the good part of an hour to figure out
-        // why it was crashing all the time!
-        // this is kind of a workaround, we simply write(2) to fd 0
-        s: string[100]; // not an ansistring
-{$endif DEBUG_MT}
       begin
       begin
-{$ifdef DEBUG_MT}
-        __ConsolePrintf('New thread started, initing threadvars');
-{$endif DEBUG_MT}
+        WRITE_DEBUG('New thread started, initing threadvars'#13#10);
 {$ifdef HASTHREADVAR}
 {$ifdef HASTHREADVAR}
         { Allocate local thread vars, this must be the first thing,
         { Allocate local thread vars, this must be the first thing,
           because the exception management and io depends on threadvars }
           because the exception management and io depends on threadvars }
         SysAllocateThreadVars;
         SysAllocateThreadVars;
 {$endif HASTHREADVAR}
 {$endif HASTHREADVAR}
         { Copy parameter to local data }
         { Copy parameter to local data }
-{$ifdef DEBUG_MT}
-        __ConsolePrintf ('New thread started, initialising ...');
-{$endif DEBUG_MT}
+        WRITE_DEBUG('New thread started, initialising ...'#13#10);
         ti:=pthreadinfo(param)^;
         ti:=pthreadinfo(param)^;
         dispose(pthreadinfo(param));
         dispose(pthreadinfo(param));
         { Initialize thread }
         { Initialize thread }
         InitThread(ti.stklen);
         InitThread(ti.stklen);
         { Start thread function }
         { Start thread function }
-{$ifdef DEBUG_MT}
-        __ConsolePrintf('Jumping to thread function');
-{$endif DEBUG_MT}
+        WRITE_DEBUG('Jumping to thread function'#13#10);
         ThreadMain:=pointer(ti.f(ti.p));
         ThreadMain:=pointer(ti.f(ti.p));
         DoneThread;
         DoneThread;
-	pthread_detach(pointer(pthread_self));
+	//pthread_detach(pointer(pthread_self));
+        pthread_exit (nil);
       end;
       end;
 
 
 
 
@@ -182,9 +170,7 @@ implementation
         ti : pthreadinfo;
         ti : pthreadinfo;
         thread_attr : pthread_attr_t;
         thread_attr : pthread_attr_t;
       begin
       begin
-{$ifdef DEBUG_MT}
-        __ConsolePrintf('Creating new thread');
-{$endif DEBUG_MT}
+        WRITE_DEBUG('SysBeginThread: Creating new thread'#13#10);
         { Initialize multithreading if not done }
         { Initialize multithreading if not done }
         if not IsMultiThread then
         if not IsMultiThread then
          begin
          begin
@@ -202,9 +188,7 @@ implementation
         ti^.p:=p;
         ti^.p:=p;
         ti^.stklen:=stacksize;
         ti^.stklen:=stacksize;
         { call pthread_create }
         { call pthread_create }
-{$ifdef DEBUG_MT}
-        __ConsolePrintf('Starting new thread');
-{$endif DEBUG_MT}
+        WRITE_DEBUG('SysBeginThread: Starting new thread'#13#10);
         pthread_attr_init(@thread_attr);
         pthread_attr_init(@thread_attr);
         pthread_attr_setinheritsched(@thread_attr, PTHREAD_EXPLICIT_SCHED);
         pthread_attr_setinheritsched(@thread_attr, PTHREAD_EXPLICIT_SCHED);
 
 
@@ -218,9 +202,7 @@ implementation
           threadid := 0;
           threadid := 0;
         end;
         end;
         SysBeginThread:=threadid;
         SysBeginThread:=threadid;
-{$ifdef DEBUG_MT}
-        writeln('BeginThread returning ',SysBeginThread);
-{$endif DEBUG_MT}
+        WRITE_DEBUG('SysBeginThread returning %d'#13#10,SysBeginThread);
       end;
       end;
 
 
 
 
@@ -262,6 +244,7 @@ implementation
     begin
     begin
       LResult := 0;
       LResult := 0;
       LResultP := @LResult;
       LResultP := @LResult;
+      WRITE_DEBUG('SysWaitForThreadTerminate: waiting for %d, timeout %d'#13#10,threadHandle,timeoutMS);
       pthread_join(Pointer(threadHandle), @LResultP);
       pthread_join(Pointer(threadHandle), @LResultP);
       SysWaitForThreadTerminate := LResult;
       SysWaitForThreadTerminate := LResult;
     end;
     end;
@@ -500,7 +483,11 @@ initialization
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.2  2004-09-19 20:06:37  armin
+  Revision 1.3  2004-09-26 19:23:34  armin
+  * exiting threads at nlm unload
+  * renamed some libc functions
+
+  Revision 1.2  2004/09/19 20:06:37  armin
   * removed get/free video buf from video.pp
   * removed get/free video buf from video.pp
   * implemented sockets
   * implemented sockets
   * basic library support
   * basic library support

+ 13 - 9
rtl/netwlibc/sysutils.pp

@@ -175,7 +175,7 @@ Function FileAge (Const FileName : String): Longint;
 var Info : TStat;
 var Info : TStat;
     TM  : TTM;
     TM  : TTM;
 begin
 begin
-  If stat (pchar(FileName),Info) <> 0 then
+  If Fpstat (pchar(FileName),Info) <> 0 then
     exit(-1)
     exit(-1)
   else
   else
     begin
     begin
@@ -189,7 +189,7 @@ end;
 Function FileExists (Const FileName : String) : Boolean;
 Function FileExists (Const FileName : String) : Boolean;
 VAR Info : TStat;
 VAR Info : TStat;
 begin
 begin
-  FileExists:=(stat(pchar(filename),Info) = 0);
+  FileExists:=(Fpstat(pchar(filename),Info) = 0);
 end;
 end;
 
 
 
 
@@ -239,7 +239,7 @@ begin
       size := Pdirent(FindData.EntryP)^.d_size;
       size := Pdirent(FindData.EntryP)^.d_size;
       name := strpas (Pdirent(FindData.EntryP)^.d_name);
       name := strpas (Pdirent(FindData.EntryP)^.d_name);
       fname := FindData._dir + name;
       fname := FindData._dir + name;
-      if stat (pchar(fname),StatBuf) = 0 then
+      if Fpstat (pchar(fname),StatBuf) = 0 then
         time := UnixToWinAge (StatBuf.st_mtim.tv_sec)
         time := UnixToWinAge (StatBuf.st_mtim.tv_sec)
       else
       else
         time := 0;
         time := 0;
@@ -337,7 +337,7 @@ Function FileGetDate (Handle : Longint) : Longint;
 Var Info : TStat;
 Var Info : TStat;
     _PTM : PTM;
     _PTM : PTM;
 begin
 begin
-  If fstat(Handle,Info) <> 0 then
+  If Fpfstat(Handle,Info) <> 0 then
     Result:=-1
     Result:=-1
   else
   else
     begin
     begin
@@ -361,7 +361,7 @@ end;
 Function FileGetAttr (Const FileName : String) : Longint;
 Function FileGetAttr (Const FileName : String) : Longint;
 Var Info : TStat;
 Var Info : TStat;
 begin
 begin
-  If stat (pchar(FileName),Info) <> 0 then
+  If Fpstat (pchar(FileName),Info) <> 0 then
     Result:=-1
     Result:=-1
   Else
   Else
     Result := (Info.st_mode shr 16) and $ffff;
     Result := (Info.st_mode shr 16) and $ffff;
@@ -373,7 +373,7 @@ var
   StatBuf : TStat;
   StatBuf : TStat;
   newMode : longint;
   newMode : longint;
 begin
 begin
-  if stat (pchar(Filename),StatBuf) = 0 then
+  if Fpstat (pchar(Filename),StatBuf) = 0 then
   begin
   begin
     {what should i do here ?
     {what should i do here ?
      only support sysutils-standard attributes or also support the extensions defined
      only support sysutils-standard attributes or also support the extensions defined
@@ -389,7 +389,7 @@ begin
       newmode := StatBuf.st_mode and ($ffff0000-M_A_RDONLY-M_A_HIDDEN- M_A_SYSTEM-M_A_SUBDIR-M_A_ARCH);
       newmode := StatBuf.st_mode and ($ffff0000-M_A_RDONLY-M_A_HIDDEN- M_A_SYSTEM-M_A_SUBDIR-M_A_ARCH);
       newmode := newmode or (attr shl 16) or M_A_BITS_SIGNIFICANT;
       newmode := newmode or (attr shl 16) or M_A_BITS_SIGNIFICANT;
     end;
     end;
-    if chmod (pchar(Filename),newMode) < 0 then
+    if Fpchmod (pchar(Filename),newMode) < 0 then
       result := ___errno^ else
       result := ___errno^ else
       result := 0;
       result := 0;
   end else
   end else
@@ -509,7 +509,7 @@ end;
 function DirectoryExists (const Directory: string): boolean;
 function DirectoryExists (const Directory: string): boolean;
 var Info : TStat;
 var Info : TStat;
 begin
 begin
-  If stat (pchar(Directory),Info) <> 0 then
+  If Fpstat (pchar(Directory),Info) <> 0 then
     exit(false)
     exit(false)
   else
   else
     Exit ((Info.st_mode and M_A_SUBDIR) <> 0);
     Exit ((Info.st_mode and M_A_SUBDIR) <> 0);
@@ -638,7 +638,11 @@ end.
 {
 {
 
 
   $Log$
   $Log$
-  Revision 1.3  2004-09-19 20:06:37  armin
+  Revision 1.4  2004-09-26 19:23:34  armin
+  * exiting threads at nlm unload
+  * renamed some libc functions
+
+  Revision 1.3  2004/09/19 20:06:37  armin
   * removed get/free video buf from video.pp
   * removed get/free video buf from video.pp
   * implemented sockets
   * implemented sockets
   * basic library support
   * basic library support

+ 104 - 23
rtl/netwlibc/tthread.inc

@@ -66,6 +66,16 @@
   change them completely.
   change them completely.
 }
 }
 
 
+{ ok, so this is a hack, but it works nicely. Just never use
+  a multiline argument with WRITE_DEBUG! }
+{$MACRO ON}
+{$IFDEF DEBUG_MT}
+{$define WRITE_DEBUG := ConsolePrintf} // actually write something
+{$ELSE}
+{$define WRITE_DEBUG := //}      // just comment out those lines
+{$ENDIF}
+
+
 function SemaphoreInit: Pointer;
 function SemaphoreInit: Pointer;
 begin
 begin
   SemaphoreInit := GetMem(SizeOf(TFilDes));
   SemaphoreInit := GetMem(SizeOf(TFilDes));
@@ -95,11 +105,22 @@ end;
 
 
 // =========== semaphore end ===========
 // =========== semaphore end ===========
 
 
+type
+  PThreadRec=^TThreadRec;
+  TThreadRec=record
+    thread : TThread;
+    next   : PThreadRec;
+  end;
+
 var
 var
-  ThreadsInited: boolean = false;
+  ThreadRoot : PThreadRec;
+  ThreadsInited : boolean = false;
+  DisableRemoveThread : boolean;
+  ThreadCount: longint = 0;
 {$IFDEF LINUX}
 {$IFDEF LINUX}
   GMainPID: LongInt = 0;
   GMainPID: LongInt = 0;
 {$ENDIF}
 {$ENDIF}
+
 const
 const
   // stupid, considering its not even implemented...
   // stupid, considering its not even implemented...
   Priorities: array [TThreadPriority] of Integer =
   Priorities: array [TThreadPriority] of Integer =
@@ -112,29 +133,83 @@ begin
     {$IFDEF LINUX}
     {$IFDEF LINUX}
     GMainPid := fpgetpid();
     GMainPid := fpgetpid();
     {$ENDIF}
     {$ENDIF}
+    ThreadRoot:=nil;
+    ThreadsInited:=true;
+    DisableRemoveThread:=false;
   end;
   end;
 end;
 end;
 
 
 procedure DoneThreads;
 procedure DoneThreads;
+var
+  hp,next : PThreadRec;
 begin
 begin
-  ThreadsInited := false;
+  DisableRemoveThread := true;    {to avoid that Destroy calling RemoveThread modifies Thread List}
+  while assigned(ThreadRoot) do
+   begin
+     WRITE_DEBUG('DoneThreads: calling Destroy'#13#10);
+     ThreadRoot^.Thread.Destroy;
+     hp:=ThreadRoot;
+     ThreadRoot:=ThreadRoot^.Next;
+     dispose(hp);
+     WRITE_DEBUG('DoneThreads: called destroy, remaining threads: %d ThreadRoot: %x'#13#10,ThreadCount,longint(ThreadRoot));
+   end;
+  ThreadsInited:=false;
 end;
 end;
 
 
-{ ok, so this is a hack, but it works nicely. Just never use
-  a multiline argument with WRITE_DEBUG! }
-{$MACRO ON}
-{$IFDEF DEBUG_MT}
-{$define WRITE_DEBUG := writeln} // actually write something
-{$ELSE}
-{$define WRITE_DEBUG := //}      // just comment out those lines
-{$ENDIF}
+procedure AddThread(t:TThread);
+var
+  hp : PThreadRec;
+begin
+  { Need to initialize threads ? }
+  if not ThreadsInited then
+   InitThreads;
+
+  { Put thread in the linked list }
+  new(hp);
+  hp^.Thread:=t;
+  hp^.next:=ThreadRoot;
+  ThreadRoot:=hp;
+
+  inc(ThreadCount);
+end;
+
+
+procedure RemoveThread(t:TThread);
+var
+  lasthp,hp : PThreadRec;
+begin
+  if not DisableRemoveThread then  {disabled while in DoneThreads}
+  begin
+    hp:=ThreadRoot;
+    lasthp:=nil;
+    while assigned(hp) do
+    begin
+      if hp^.Thread=t then
+      begin
+        if assigned(lasthp) then
+         lasthp^.next:=hp^.next
+        else
+         ThreadRoot:=hp^.next;
+        dispose(hp);
+        Dec(ThreadCount);
+        if ThreadCount = 0 then ThreadsInited := false;
+        exit;
+      end;
+      lasthp:=hp;
+      hp:=hp^.next;
+    end;
+  end else
+    dec(ThreadCount);
+end;
+
+
 
 
 function ThreadFunc(parameter: Pointer): LongInt;
 function ThreadFunc(parameter: Pointer): LongInt;
 var
 var
   LThread: TThread;
   LThread: TThread;
   c: char;
   c: char;
 begin
 begin
-  WRITE_DEBUG('ThreadFunc is here...');
+  WRITE_DEBUG('ThreadFunc is here...'#13#10);
   LThread := TThread(parameter);
   LThread := TThread(parameter);
   {$IFDEF LINUX}
   {$IFDEF LINUX}
   // save the PID of the "thread"
   // save the PID of the "thread"
@@ -142,38 +217,38 @@ begin
   // the LinuxThreads implementation is used
   // the LinuxThreads implementation is used
   LThread.FPid := fpgetpid();
   LThread.FPid := fpgetpid();
   {$ENDIF}
   {$ENDIF}
-  WRITE_DEBUG('thread initing, parameter = ', LongInt(LThread));
+  WRITE_DEBUG('thread initing, parameter = %d'#13#10, LongInt(LThread));
   try
   try
     if LThread.FInitialSuspended then begin
     if LThread.FInitialSuspended then begin
       SemaphoreWait(LThread.FSem);
       SemaphoreWait(LThread.FSem);
       if not LThread.FInitialSuspended then begin
       if not LThread.FInitialSuspended then begin
-        WRITE_DEBUG('going into LThread.Execute');
+        WRITE_DEBUG('going into LThread.Execute'#13#10);
         LThread.Execute;
         LThread.Execute;
       end;
       end;
     end else begin
     end else begin
-      WRITE_DEBUG('going into LThread.Execute');
+      WRITE_DEBUG('going into LThread.Execute'#13#10);
       LThread.Execute;
       LThread.Execute;
     end;
     end;
   except
   except
     on e: exception do begin
     on e: exception do begin
-      WRITE_DEBUG('got exception: ',e.message);
+      WRITE_DEBUG('got exception: %s'#13#10,pchar(e.message));
       LThread.FFatalException :=  TObject(AcquireExceptionObject);
       LThread.FFatalException :=  TObject(AcquireExceptionObject);
       // not sure if we should really do this...
       // not sure if we should really do this...
       // but .Destroy was called, so why not try FreeOnTerminate?
       // but .Destroy was called, so why not try FreeOnTerminate?
       if e is EThreadDestroyCalled then LThread.FFreeOnTerminate := true;
       if e is EThreadDestroyCalled then LThread.FFreeOnTerminate := true;
     end;
     end;
   end;
   end;
-  WRITE_DEBUG('thread done running');
+  WRITE_DEBUG('thread done running'#13#10);
   Result := LThread.FReturnValue;
   Result := LThread.FReturnValue;
-  WRITE_DEBUG('Result is ',Result);
+  WRITE_DEBUG('Result is %d'#13#10,Result);
   LThread.FFinished := True;
   LThread.FFinished := True;
   LThread.DoTerminate;
   LThread.DoTerminate;
   if LThread.FreeOnTerminate then begin
   if LThread.FreeOnTerminate then begin
-    WRITE_DEBUG('Thread should be freed');
+    WRITE_DEBUG('Thread should be freed'#13#10);
     LThread.Free;
     LThread.Free;
-    WRITE_DEBUG('Thread freed');
+    WRITE_DEBUG('Thread freed'#13#10);
   end;
   end;
-  WRITE_DEBUG('thread func exiting');
+  WRITE_DEBUG('thread func exiting'#13#10);
 end;
 end;
 
 
 { TThread }
 { TThread }
@@ -182,15 +257,16 @@ begin
   // lets just hope that the user doesn't create a thread
   // lets just hope that the user doesn't create a thread
   // via BeginThread and creates the first TThread Object in there!
   // via BeginThread and creates the first TThread Object in there!
   InitThreads;
   InitThreads;
+  AddThread(self);
   inherited Create;
   inherited Create;
   FSem := SemaphoreInit;
   FSem := SemaphoreInit;
   FSuspended :=CreateSuspended;
   FSuspended :=CreateSuspended;
   FSuspendedExternal := false;
   FSuspendedExternal := false;
   FInitialSuspended := CreateSuspended;
   FInitialSuspended := CreateSuspended;
   FFatalException := nil;
   FFatalException := nil;
-  WRITE_DEBUG('creating thread, self = ',longint(self));
+  WRITE_DEBUG('creating thread, self = %d'#13#10,longint(self));
   FHandle:= BeginThread(@ThreadFunc, Pointer(Self), FThreadID);
   FHandle:= BeginThread(@ThreadFunc, Pointer(Self), FThreadID);
-  WRITE_DEBUG('TThread.Create done');
+  WRITE_DEBUG('TThread.Create done'#13#10);
 end;
 end;
 
 
 
 
@@ -215,6 +291,7 @@ begin
   FFatalException := nil;
   FFatalException := nil;
   SemaphoreDestroy(FSem);
   SemaphoreDestroy(FSem);
   inherited Destroy;
   inherited Destroy;
+  RemoveThread(self);          {remove it from the list of active threads}
 end;
 end;
 
 
 procedure TThread.SetSuspended(Value: Boolean);
 procedure TThread.SetSuspended(Value: Boolean);
@@ -326,7 +403,11 @@ end;
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.1  2004-09-05 20:58:47  armin
+  Revision 1.2  2004-09-26 19:23:34  armin
+  * exiting threads at nlm unload
+  * renamed some libc functions
+
+  Revision 1.1  2004/09/05 20:58:47  armin
   * first rtl version for netwlibc
   * first rtl version for netwlibc
 
 
 }
 }

Some files were not shown because too many files changed in this diff