[project @ 1999-07-06 15:33:23 by simonmar]
[ghc-hetmet.git] / ghc / rts / RtsStartup.c
index d079f6e..d87f188 100644 (file)
@@ -1,5 +1,7 @@
 /* -----------------------------------------------------------------------------
- * $Id: RtsStartup.c,v 1.5 1999/01/26 11:12:47 simonm Exp $
+ * $Id: RtsStartup.c,v 1.17 1999/07/06 15:33:23 simonmar Exp $
+ *
+ * (c) The GHC Team, 1998-1999
  *
  * Main function for a standalone Haskell program.
  *
  */
 struct RTS_FLAGS RtsFlags;
 
-extern void startupHaskell(int argc, char *argv[])
+static int rts_has_started_up = 0;
+
+void
+startupHaskell(int argc, char *argv[])
 {
+#ifdef ENABLE_WIN32_DLL_SUPPORT
+    int i;
+#endif
+
+    /* To avoid repeated initialisations of the RTS */
+   if (rts_has_started_up)
+     return;
+   else
+     rts_has_started_up=1;
+
 #if defined(PAR)
     int nPEs = 0;                  /* Number of PEs */
 #endif
@@ -76,7 +91,7 @@ extern void startupHaskell(int argc, char *argv[])
     prog_argc = argc;
     prog_argv = argv;
 
-#if defined(PAR)
+#ifdef PAR
    /* Initialise the parallel system -- before initHeap! */
     initParallelSystem();
    /* And start GranSim profiling if required: omitted for now
@@ -104,16 +119,48 @@ extern void startupHaskell(int argc, char *argv[])
 #if 0
     initUserSignals();
 #endif
+    /* When the RTS and Prelude live in separate DLLs,
+       we need to patch up the char- and int-like tables
+       that the RTS keep after both DLLs have been loaded,
+       filling in the tables with references to where the
+       static info tables have been loaded inside the running
+       process.
+    */
+#ifdef ENABLE_WIN32_DLL_SUPPORT
+    for(i=0;i<=255;i++)
+       (CHARLIKE_closure[i]).header.info = (const StgInfoTable*)&Czh_static_info;
 
+    for(i=0;i<=32;i++)
+       (INTLIKE_closure[i]).header.info = (const StgInfoTable*)&Izh_static_info;
+       
+#endif
     /* Record initialization times */
     end_init();
 }
 
+/*
+ * Shutting down the RTS - two ways of doing this, one which
+ * calls exit(), one that doesn't.
+ *
+ * (shutdownHaskellAndExit() is called by System.exitWith).
+ */
+void
+shutdownHaskellAndExit(int n)
+{
+  OnExitHook();
+  shutdownHaskell();
+  stg_exit(n);
+}
+
 void
 shutdownHaskell(void)
 {
-  /* Finalise any remaining weak pointers */
-  finaliseWeakPointersNow();
+  if (!rts_has_started_up)
+     return;
+
+  /* Finalize any remaining weak pointers */
+  finalizeWeakPointersNow();
 
 #if defined(GRAN)
   #error FixMe.
@@ -136,25 +183,12 @@ shutdownHaskell(void)
   if (RtsFlags.TickyFlags.showTickyStats) PrintTickyInfo();
 #endif
 
-  /*
-    This fflush is important, because: if "main" just returns,
-    then we will end up in pre-supplied exit code that will close
-    streams and flush buffers.  In particular we have seen: it
-    will close fd 0 (stdin), then flush fd 1 (stdout), then <who
-    cares>...
-    
-    But if you're playing with sockets, that "close fd 0" might
-    suggest to the daemon that all is over, only to be presented
-    with more stuff on "fd 1" at the flush.
-    
-    The fflush avoids this sad possibility.
-   */
-  fflush(stdout);
+  rts_has_started_up=0;
 }
 
 
 /* 
- * called from STG-land to exit the program cleanly 
+ * called from STG-land to exit the program
  */
 
 void  
@@ -163,7 +197,7 @@ stg_exit(I_ n)
 #ifdef PAR
   par_exit(n);
 #else
-  OnExitHook();
   exit(n);
 #endif
 }
+